Skip to content

Commit 2d1b28d

Browse files
author
Matt Bierner
authored
Use the new lastCommittedOrigin for remote port forwarding in webviews (microsoft#105531)
Fixes microsoft#102449
1 parent 1c4f6ac commit 2d1b28d

6 files changed

Lines changed: 25 additions & 40 deletions

File tree

src/vs/platform/webview/common/webviewManagerService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const IWebviewManagerService = createDecorator<IWebviewManagerService>('w
1414
export interface IWebviewManagerService {
1515
_serviceBrand: unknown;
1616

17-
registerWebview(id: string, webContentsId: number | undefined, windowId: number, metadata: RegisterWebviewMetadata): Promise<void>;
17+
registerWebview(id: string, windowId: number, metadata: RegisterWebviewMetadata): Promise<void>;
1818
unregisterWebview(id: string): Promise<void>;
1919
updateWebviewMetadata(id: string, metadataDelta: Partial<RegisterWebviewMetadata>): Promise<void>;
2020

src/vs/platform/webview/electron-main/webviewMainService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class WebviewMainService extends Disposable implements IWebviewManagerSer
3333
this.portMappingProvider = this._register(new WebviewPortMappingProvider(tunnelService));
3434
}
3535

36-
public async registerWebview(id: string, webContentsId: number | undefined, windowId: number, metadata: RegisterWebviewMetadata): Promise<void> {
36+
public async registerWebview(id: string, windowId: number, metadata: RegisterWebviewMetadata): Promise<void> {
3737
const extensionLocation = metadata.extensionLocation ? URI.from(metadata.extensionLocation) : undefined;
3838

3939
this.protocolProvider.registerWebview(id, {
@@ -43,7 +43,7 @@ export class WebviewMainService extends Disposable implements IWebviewManagerSer
4343
localResourceRoots: metadata.localResourceRoots.map(x => URI.from(x))
4444
});
4545

46-
this.portMappingProvider.registerWebview(id, webContentsId, {
46+
this.portMappingProvider.registerWebview(id, {
4747
extensionLocation,
4848
mappings: metadata.portMappings,
4949
resolvedAuthority: metadata.remoteConnectionData,

src/vs/platform/webview/electron-main/webviewPortMappingProvider.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { session } from 'electron';
6+
import { OnBeforeRequestListenerDetails, session } from 'electron';
77
import { Disposable } from 'vs/base/common/lifecycle';
88
import { URI } from 'vs/base/common/uri';
99
import { IAddress } from 'vs/platform/remote/common/remoteAgentConnection';
1010
import { ITunnelService } from 'vs/platform/remote/common/tunnel';
1111
import { webviewPartitionId } from 'vs/platform/webview/common/resourceLoader';
1212
import { IWebviewPortMapping, WebviewPortMappingManager } from 'vs/platform/webview/common/webviewPortMapping';
1313

14+
interface OnBeforeRequestListenerDetails_Extended extends OnBeforeRequestListenerDetails {
15+
readonly lastCommittedOrigin?: string;
16+
}
17+
1418
interface PortMappingData {
1519
readonly extensionLocation: URI | undefined;
1620
readonly mappings: readonly IWebviewPortMapping[];
@@ -20,13 +24,10 @@ interface PortMappingData {
2024
export class WebviewPortMappingProvider extends Disposable {
2125

2226
private readonly _webviewData = new Map<string, {
23-
readonly webContentsId: number | undefined;
2427
readonly manager: WebviewPortMappingManager;
2528
metadata: PortMappingData;
2629
}>();
2730

28-
private _webContentsIdsToWebviewIds = new Map<number, /* id */ string>();
29-
3031
constructor(
3132
@ITunnelService private readonly _tunnelService: ITunnelService,
3233
) {
@@ -40,12 +41,15 @@ export class WebviewPortMappingProvider extends Disposable {
4041
'*://127.0.0.1:*/*',
4142
'*://0.0.0.0:*/*',
4243
]
43-
}, async (details, callback) => {
44-
const webviewId = details.webContentsId && this._webContentsIdsToWebviewIds.get(details.webContentsId);
45-
if (!webviewId) {
44+
}, async (details: OnBeforeRequestListenerDetails_Extended, callback) => {
45+
let origin: URI;
46+
try {
47+
origin = URI.parse(details.lastCommittedOrigin!);
48+
} catch {
4649
return callback({});
4750
}
4851

52+
const webviewId = origin.authority;
4953
const entry = this._webviewData.get(webviewId);
5054
if (!entry) {
5155
return callback({});
@@ -56,26 +60,20 @@ export class WebviewPortMappingProvider extends Disposable {
5660
});
5761
}
5862

59-
public async registerWebview(id: string, webContentsId: number | undefined, metadata: PortMappingData): Promise<void> {
63+
public async registerWebview(id: string, metadata: PortMappingData): Promise<void> {
6064
const manager = new WebviewPortMappingManager(
6165
() => this._webviewData.get(id)?.metadata.extensionLocation,
6266
() => this._webviewData.get(id)?.metadata.mappings || [],
6367
this._tunnelService);
6468

65-
this._webviewData.set(id, { webContentsId, metadata, manager });
66-
if (typeof webContentsId === 'number') {
67-
this._webContentsIdsToWebviewIds.set(webContentsId, id);
68-
}
69+
this._webviewData.set(id, { metadata, manager });
6970
}
7071

7172
public unregisterWebview(id: string): void {
7273
const existing = this._webviewData.get(id);
7374
if (existing) {
7475
existing.manager.dispose();
7576
this._webviewData.delete(id);
76-
if (typeof existing.webContentsId === 'number') {
77-
this._webContentsIdsToWebviewIds.delete(existing.webContentsId);
78-
}
7977
}
8078
}
8179

src/vs/workbench/contrib/webview/electron-browser/iframeWebviewElement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class ElectronIframeWebview extends IFrameWebview {
5252
super(id, options, contentOptions, extension, webviewThemeDataProvider,
5353
noficationService, tunnelService, fileService, requestService, telemetryService, environmentService, _workbenchEnvironmentService, _remoteAuthorityResolverService, logService);
5454

55-
this._resourceRequestManager = this._register(instantiationService.createInstance(WebviewResourceRequestManager, id, extension, this.content.options, Promise.resolve(undefined)));
55+
this._resourceRequestManager = this._register(instantiationService.createInstance(WebviewResourceRequestManager, id, extension, this.content.options));
5656
}
5757

5858
protected createElement(options: WebviewOptions, contentOptions: WebviewContentOptions) {

src/vs/workbench/contrib/webview/electron-browser/resourceLoading.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ export class WebviewResourceRequestManager extends Disposable {
5858
private readonly id: string,
5959
private readonly extension: WebviewExtensionDescription | undefined,
6060
initialContentOptions: WebviewContentOptions,
61-
getWebContentsId: Promise<number | undefined>,
6261
@ILogService private readonly _logService: ILogService,
6362
@IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService,
6463
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@@ -79,15 +78,13 @@ export class WebviewResourceRequestManager extends Disposable {
7978
const remoteAuthority = environmentService.configuration.remoteAuthority;
8079
const remoteConnectionData = remoteAuthority ? remoteAuthorityResolverService.getConnectionData(remoteAuthority) : null;
8180

82-
this._ready = getWebContentsId.then(async (webContentsId) => {
83-
this._logService.debug(`WebviewResourceRequestManager(${this.id}): did-start-loading`);
84-
await this._webviewManagerService.registerWebview(this.id, webContentsId, electronService.windowId, {
85-
extensionLocation: this.extension?.location.toJSON(),
86-
localResourceRoots: this._localResourceRoots.map(x => x.toJSON()),
87-
remoteConnectionData: remoteConnectionData,
88-
portMappings: this._portMappings,
89-
});
90-
81+
this._logService.debug(`WebviewResourceRequestManager(${this.id}): did-start-loading`);
82+
this._ready = this._webviewManagerService.registerWebview(this.id, electronService.windowId, {
83+
extensionLocation: this.extension?.location.toJSON(),
84+
localResourceRoots: this._localResourceRoots.map(x => x.toJSON()),
85+
remoteConnectionData: remoteConnectionData,
86+
portMappings: this._portMappings,
87+
}).then(() => {
9188
this._logService.debug(`WebviewResourceRequestManager(${this.id}): did register`);
9289
});
9390

src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,7 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
142142

143143
this._myLogService.debug(`Webview(${this.id}): init`);
144144

145-
const webviewId = new Promise<number | undefined>((resolve, reject) => {
146-
const sub = this._register(addDisposableListener(this.element!, 'dom-ready', once(() => {
147-
if (!this.element) {
148-
reject();
149-
throw new Error('No element');
150-
}
151-
resolve(this.element.getWebContentsId());
152-
sub.dispose();
153-
})));
154-
});
155-
this._resourceRequestManager = this._register(instantiationService.createInstance(WebviewResourceRequestManager, id, extension, this.content.options, webviewId));
145+
this._resourceRequestManager = this._register(instantiationService.createInstance(WebviewResourceRequestManager, id, extension, this.content.options));
156146

157147
this._register(addDisposableListener(this.element!, 'dom-ready', once(() => {
158148
this._register(ElectronWebviewBasedWebview.getWebviewKeyboardHandler(configurationService, mainProcessService).add(this.element!));

0 commit comments

Comments
 (0)