提交 ed8c0e4e 编写于 作者: M Matt Bierner

Add explicit wait on protocol registration

Possible fix for #89038/#91506. In both cases, it looks like we try to use the protocol before it is properly registered. If this fix doesn't work, there's probably something weird going on on the electron side of things
上级 2158b1aa
......@@ -113,24 +113,30 @@ class WebviewSession extends Disposable {
}
class WebviewProtocolProvider extends Disposable {
private _resolve!: () => void;
private _reject!: () => void;
public readonly ready: Promise<void>;
constructor(
handle: WebviewTagHandle,
private readonly _getExtensionLocation: () => URI | undefined,
private readonly _getLocalResourceRoots: () => ReadonlyArray<URI>,
private readonly _fileService: IFileService,
getExtensionLocation: () => URI | undefined,
getLocalResourceRoots: () => ReadonlyArray<URI>,
fileService: IFileService,
) {
super();
this.ready = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
this._register(handle.onFirstLoad(contents => {
this.registerProtocols(contents);
registerFileProtocol(contents, WebviewResourceScheme, fileService, getExtensionLocation(), getLocalResourceRoots)
.then(this._resolve, this._reject);
}));
}
private registerProtocols(contents: WebContents) {
registerFileProtocol(contents, WebviewResourceScheme, this._fileService, this._getExtensionLocation(), () =>
this._getLocalResourceRoots()
);
}
}
class WebviewPortMappingProvider extends Disposable {
......@@ -204,6 +210,7 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
private _findStarted: boolean = false;
public extension: WebviewExtensionDescription | undefined;
private readonly _protocolProvider: WebviewProtocolProvider;
constructor(
id: string,
......@@ -222,11 +229,12 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
const webviewAndContents = this._register(new WebviewTagHandle(this.element!));
const session = this._register(new WebviewSession(webviewAndContents));
this._register(new WebviewProtocolProvider(
webviewAndContents,
() => this.extension ? this.extension.location : undefined,
() => (this.content.options.localResourceRoots || []),
fileService));
this._protocolProvider = new WebviewProtocolProvider
(webviewAndContents,
() => this.extension ? this.extension.location : undefined,
() => (this.content.options.localResourceRoots || []),
fileService);
this._register(this._protocolProvider);
this._register(new WebviewPortMappingProvider(
session,
......@@ -322,7 +330,8 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
parent.appendChild(this.element);
}
protected postMessage(channel: string, data?: any): void {
protected async postMessage(channel: string, data?: any): Promise<void> {
await this._protocolProvider.ready;
this.element?.send(channel, data);
}
......
......@@ -14,24 +14,27 @@ export function registerFileProtocol(
extensionLocation: URI | undefined,
getRoots: () => ReadonlyArray<URI>
) {
contents.session.protocol.registerBufferProtocol(protocol, async (request, callback: any) => {
try {
const result = await loadLocalResource(URI.parse(request.url), fileService, extensionLocation, getRoots);
if (result.type === WebviewResourceResponse.Type.Success) {
return callback({
data: Buffer.from(result.data.buffer),
mimeType: result.mimeType
});
return new Promise((resolve, reject) =>
contents.session.protocol.registerBufferProtocol(protocol, async (request, callback: any) => {
try {
const result = await loadLocalResource(URI.parse(request.url), fileService, extensionLocation, getRoots);
if (result.type === WebviewResourceResponse.Type.Success) {
return callback({
data: Buffer.from(result.data.buffer),
mimeType: result.mimeType
});
}
if (result.type === WebviewResourceResponse.Type.AccessDenied) {
console.error('Webview: Cannot load resource outside of protocol root');
return callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ });
}
} catch {
// noop
}
if (result.type === WebviewResourceResponse.Type.AccessDenied) {
console.error('Webview: Cannot load resource outside of protocol root');
return callback({ error: -10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ });
}
} catch {
// noop
}
return callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ });
});
return callback({ error: -2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ });
}, (err) => {
err ? reject(err) : resolve();
}));
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册