From b566b66590487af9f50f9349d4e13ca14352fb39 Mon Sep 17 00:00:00 2001 From: Asher Date: Mon, 12 Aug 2019 10:30:02 -0500 Subject: [PATCH] Fix service worker scope when there is a base path --- README.md | 5 ++--- scripts/vscode.patch | 31 +++++++++++++++++++++++++++++-- src/server.ts | 17 +++++++++++++++-- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e660d885..2fd7f299 100644 --- a/README.md +++ b/README.md @@ -110,9 +110,8 @@ directory. Our changes include: - Add a `code-server` schema. - Allow multiple extension directories (both user and built-in). -- Rewrite assets requested by the browser to use the base URL. -- Modify the loader, websocket, webview, and service worker to use the URL of - the page as a base (and TLS if necessary for the websocket). +- Modify the loader, websocket, webview, service worker, and asset requests to + use the URL of the page as a base (and TLS if necessary for the websocket). - Send client-side telemetry through the server. - Add a file prefix to ignore for temporary files created during upload. - Insert our upload service for use in editor windows and explorer. diff --git a/scripts/vscode.patch b/scripts/vscode.patch index 0f2a4ba7..952f1662 100644 --- a/scripts/vscode.patch +++ b/scripts/vscode.patch @@ -60,7 +60,7 @@ index 99bd930a91..319c4bd3c3 100644 ]; diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts -index fa12f62900..1dbaac1640 100644 +index fa12f62900..a4c72fee8e 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1187,6 +1187,7 @@ export function animate(fn: () => void): IDisposable { @@ -80,7 +80,7 @@ index fa12f62900..1dbaac1640 100644 // rewrite vscode-remote-uris to uris of the window location // so that they can be intercepted by the service worker - return _location.with({ path: '/vscode-resources/fetch', query: `u=${JSON.stringify(uri)}` }); -+ return _location.with({ path: `${basePath}/vscode-resources/${uri.fsPath}` }); ++ return _location.with({ path: `${basePath}/vscode-resources/fetch`, query: `u=${JSON.stringify(uri)}` }); } return uri; } @@ -715,6 +715,33 @@ index 9235c739fb..32d203eb32 100644 this._register(logService.onDidChangeLogLevel(level => logLevelClient.setLevel(level))); } } +diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts +index 622bb7889b..66dd4b0bbc 100644 +--- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts ++++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts +@@ -36,7 +36,8 @@ self.addEventListener('activate', event => { + //#region --- fetching/caching + + const _cacheName = 'vscode-resources'; +-const _resourcePrefix = '/vscode-resources/fetch'; ++const rootPath = self.location.pathname.replace(/\/out\/vs\/workbench\/contrib\/resources\/browser\/resourceServiceWorkerMain.js$/, ''); ++const _resourcePrefix = `${rootPath}/vscode-resources/fetch`; + const _pendingFetch = new Map(); + + self.addEventListener('message', event => { +diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts +index dfda6a1cfb..44a01fb0fb 100644 +--- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts ++++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts +@@ -24,7 +24,7 @@ const _serviceWorker = new class ServiceWorkerStarter { + private _messageHandler?: (event: ExtendableMessageEvent) => void; + + constructor() { +- navigator.serviceWorker.register(ServiceWorkerStarter._url, { scope: '/' }).then(reg => { ++ navigator.serviceWorker.register(ServiceWorkerStarter._url, { scope: window.location.pathname.replace(/\/+$/, '') }).then(reg => { + // console.debug('SW#reg', reg); + return reg.update(); + // }).then(() => { diff --git a/src/vs/workbench/contrib/update/electron-browser/update.contribution.ts b/src/vs/workbench/contrib/update/electron-browser/update.contribution.ts index e39fa57979..3c775c9a06 100644 --- a/src/vs/workbench/contrib/update/electron-browser/update.contribution.ts diff --git a/src/server.ts b/src/server.ts index 0c0b9e24..402e2b90 100644 --- a/src/server.ts +++ b/src/server.ts @@ -198,7 +198,7 @@ export abstract class Server { response.writeHead(payload.redirect ? HttpCode.Redirect : payload.code || HttpCode.Ok, { "Content-Type": getMediaMime(payload.filePath), ...(payload.redirect ? { Location: this.withBase(request, payload.redirect) } : {}), - ...(request.headers["service-worker"] ? { "Service-Worker-Allowed": this.options.basePath + "/" } : {}), + ...(request.headers["service-worker"] ? { "Service-Worker-Allowed": this.options.basePath || "/" } : {}), ...payload.headers, }); response.end(payload.content); @@ -442,7 +442,20 @@ export class MainServer extends Server { ): Promise { switch (base) { case "/": return this.getRoot(request, parsedUrl); - case "/vscode-resources": return this.getResource(requestPath); + case "/vscode-resources": + if (requestPath === "/fetch") { + // For some reason VS Code encodes the = so the query doesn't parse + // correctly. We'll look through what's available and try to find it. + for (let value in parsedUrl.query) { + if (value && typeof value === "string") { + const query = querystring.parse(value); + if (typeof query.u === "string") { + return this.getResource(JSON.parse(query.u).path); + } + } + } + } + throw new HttpError("Not found", HttpCode.NotFound); case "/webview": if (requestPath.indexOf("/vscode-resource") === 0) { return this.getResource(requestPath.replace(/^\/vscode-resource/, ""));