From fda5b84d5da5fb079373cb29a22cc3e846445edc Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Mon, 11 Apr 2022 21:33:50 +0200 Subject: [PATCH] commit in route --- resources/server/manifest.json | 4 +- .../code/browser/workbench/workbench-dev.html | 17 ++-- src/vs/code/browser/workbench/workbench.html | 23 ++--- src/vs/code/browser/workbench/workbench.ts | 10 ++- src/vs/server/node/webClientServer.ts | 85 ++++++++++++------- 5 files changed, 84 insertions(+), 55 deletions(-) diff --git a/resources/server/manifest.json b/resources/server/manifest.json index 38b665c8c3b..3b64fbb9ee3 100644 --- a/resources/server/manifest.json +++ b/resources/server/manifest.json @@ -6,12 +6,12 @@ "display": "standalone", "icons": [ { - "src": "/code-192.png", + "src": "code-192.png", "type": "image/png", "sizes": "192x192" }, { - "src": "/code-512.png", + "src": "code-512.png", "type": "image/png", "sizes": "512x512" } diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html index 86df5ff3666..87399387e57 100644 --- a/src/vs/code/browser/workbench/workbench-dev.html +++ b/src/vs/code/browser/workbench/workbench-dev.html @@ -11,8 +11,8 @@ - - + +, @@ -26,22 +26,23 @@ - - + + - - + + - + + - - - + + + diff --git a/src/vs/code/browser/workbench/workbench.ts b/src/vs/code/browser/workbench/workbench.ts index 612f54c17a1..cad7de3f9ed 100644 --- a/src/vs/code/browser/workbench/workbench.ts +++ b/src/vs/code/browser/workbench/workbench.ts @@ -192,6 +192,10 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback private checkCallbacksTimeout: unknown | undefined = undefined; private onDidChangeLocalStorageDisposable: IDisposable | undefined; + constructor(private readonly _callbackRoute: string) { + super(); + } + create(options: Partial = {}): URI { const id = ++LocalStorageURLCallbackProvider.REQUEST_ID; const queryParams: string[] = [`vscode-reqid=${id}`]; @@ -215,7 +219,7 @@ class LocalStorageURLCallbackProvider extends Disposable implements IURLCallback this.startListening(); } - return URI.parse(window.location.href).with({ path: '/callback', query: queryParams.join('&') }); + return URI.parse(window.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') }); } private startListening(): void { @@ -492,7 +496,7 @@ function doCreateUri(path: string, queryValues: Map): URI { if (!configElement || !configElementAttribute) { throw new Error('Missing web configuration element'); } - const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents } = JSON.parse(configElementAttribute); + const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = JSON.parse(configElementAttribute); // Create workbench create(document.body, { @@ -501,7 +505,7 @@ function doCreateUri(path: string, queryValues: Map): URI { enabled: config.settingsSyncOptions.enabled, } : undefined, workspaceProvider: WorkspaceProvider.create(config), - urlCallbackProvider: new LocalStorageURLCallbackProvider(), + urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider }); })(); diff --git a/src/vs/server/node/webClientServer.ts b/src/vs/server/node/webClientServer.ts index 91d08d315d9..c969579a075 100644 --- a/src/vs/server/node/webClientServer.ts +++ b/src/vs/server/node/webClientServer.ts @@ -78,11 +78,15 @@ export async function serveFile(logService: ILogService, req: http.IncomingMessa } const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath); +const CHARCODE_SLASH = '/'.charCodeAt(0); export class WebClientServer { private readonly _webExtensionResourceUrlTemplate: URI | undefined; + private readonly _staticRoute; + private readonly _callbackRoute; + constructor( private readonly _connectionToken: ServerConnectionToken, @IServerEnvironmentService private readonly _environmentService: IServerEnvironmentService, @@ -91,6 +95,9 @@ export class WebClientServer { @IProductService private readonly _productService: IProductService, ) { this._webExtensionResourceUrlTemplate = this._productService.extensionsGallery?.resourceUrlTemplate ? URI.parse(this._productService.extensionsGallery.resourceUrlTemplate) : undefined; + const qualityAndCommit = `${_productService.quality ?? 'oss'}-${_productService.commit ?? 'dev'}`; + this._staticRoute = `/${qualityAndCommit}/static`; + this._callbackRoute = `/${qualityAndCommit}/callback`; } /** @@ -102,16 +109,13 @@ export class WebClientServer { try { const pathname = parsedUrl.pathname!; - if (pathname === '/favicon.ico' || pathname === '/manifest.json' || pathname === '/code-192.png' || pathname === '/code-512.png') { - return serveFile(this._logService, req, res, join(APP_ROOT, 'resources', 'server', pathname.substr(1))); - } - if (/^\/static\//.test(pathname)) { + if (pathname.startsWith(this._staticRoute) && pathname.charCodeAt(this._staticRoute.length) === CHARCODE_SLASH) { return this._handleStatic(req, res, parsedUrl); } if (pathname === '/') { return this._handleRoot(req, res, parsedUrl); } - if (pathname === '/callback') { + if (pathname === this._callbackRoute) { // callback support return this._handleCallback(res); } @@ -137,9 +141,9 @@ export class WebClientServer { // Strip `/static/` from the path const normalizedPathname = decodeURIComponent(parsedUrl.pathname!); // support paths that are uri-encoded (e.g. spaces => %20) - const relativeFilePath = normalize(normalizedPathname.substr('/static/'.length)); + const relativeFilePath = normalizedPathname.substring(this._staticRoute.length + 1); - const filePath = join(APP_ROOT, relativeFilePath); + const filePath = join(APP_ROOT, relativeFilePath); // join also normalizes the path if (!isEqualOrParent(filePath, APP_ROOT, !isLinux)) { return serveError(req, res, 400, `Bad request.`); } @@ -259,8 +263,8 @@ export class WebClientServer { return serveError(req, res, 400, `Bad request.`); } - function escapeAttribute(value: string): string { - return value.replace(/"/g, '"'); + function asJSON(value: unknown): string { + return JSON.stringify(value).replace(/"/g, '"'); } let _wrapWebWorkerExtHostInIframe: undefined | false = undefined; @@ -279,28 +283,47 @@ export class WebClientServer { accessToken: this._environmentService.args['github-auth'], scopes: [['user:email'], ['repo']] } : undefined; - const data = (await util.promisify(fs.readFile)(filePath)).toString() - .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ - remoteAuthority, - _wrapWebWorkerExtHostInIframe, - developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined }, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), - workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), - productConfiguration: >{ - embedderIdentifier: 'server-distro', - extensionsGallery: this._webExtensionResourceUrlTemplate ? { - ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ - scheme: 'http', - authority: remoteAuthority, - path: `web-extension-resource/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}` - }).toString(true) - } : undefined - } - }))) - .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : ''); + + + const workbenchWebConfiguration = { + remoteAuthority, + _wrapWebWorkerExtHostInIframe, + developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined }, + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, + enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), + productConfiguration: >{ + embedderIdentifier: 'server-distro', + extensionsGallery: this._webExtensionResourceUrlTemplate ? { + ...this._productService.extensionsGallery, + 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ + scheme: 'http', + authority: remoteAuthority, + path: `web-extension-resource/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}` + }).toString(true) + } : undefined + }, + callbackRoute: this._callbackRoute + }; + + const values: { [key: string]: string } = { + WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration), + WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '', + WORKBENCH_WEB_BASE_URL: this._staticRoute, + }; + //if (!this._environmentService.isBuilt) { + //values.WORKBENCH_BUILTIN_EXTENSIONS = //get built in extensions + //} + + let data; + try { + const workbenchTemplate = (await util.promisify(fs.readFile)(filePath)).toString(); + data = workbenchTemplate.replace(/\{\{([^}]+)\}\}/g, (_, key) => values[key] ?? 'undefined'); + } catch (e) { + res.writeHead(404, { 'Content-Type': 'text/plain' }); + return res.end('Not found'); + } const cspDirectives = [ 'default-src \'self\';',