From 15f43eb7cc90c952a8049548d0258195568d193e Mon Sep 17 00:00:00 2001 From: Sofian Hnaide Date: Mon, 13 Feb 2023 18:28:41 -0800 Subject: [PATCH] custom updates --- product.json | 9 +++++++- src/server-main.js | 2 +- src/vs/base/common/network.ts | 8 +++---- .../browser/remoteAuthorityResolverService.ts | 22 +++++++++++++++---- .../remote/common/remoteAgentConnection.ts | 9 +++++--- .../remote/common/remoteAgentEnvironment.ts | 1 + .../remote/common/remoteAuthorityResolver.ts | 2 ++ src/vs/platform/remote/common/remoteHosts.ts | 6 +++-- .../remoteAuthorityResolverService.ts | 12 +++++++--- .../server/node/remoteAgentEnvironmentImpl.ts | 2 ++ .../node/remoteExtensionHostAgentServer.ts | 11 ++++++---- .../server/node/serverEnvironmentService.ts | 4 ++++ src/vs/server/node/serverServices.ts | 3 ++- src/vs/server/node/webClientServer.ts | 8 ++++--- .../api/common/extHostExtensionService.ts | 3 ++- src/vs/workbench/api/common/extHostTypes.ts | 4 +++- src/vs/workbench/browser/web.api.ts | 5 +++++ src/vs/workbench/browser/web.main.ts | 3 ++- .../browser/extensionsWorkbenchService.ts | 3 ++- .../test/browser/configurationService.test.ts | 6 ++--- .../common/extensionResourceLoader.ts | 2 +- .../services/extensions/common/extensions.ts | 8 +++---- .../extensions/common/remoteExtensionHost.ts | 2 +- .../electronExtensionService.ts | 3 ++- .../common/abstractRemoteAgentService.ts | 3 ++- .../common/remoteAgentEnvironmentChannel.ts | 2 ++ src/vscode-dts/vscode.proposed.resolvers.d.ts | 1 + 27 files changed, 103 insertions(+), 41 deletions(-) diff --git a/product.json b/product.json index d16abf8de2999..d53924d03253a 100644 --- a/product.json +++ b/product.json @@ -74,5 +74,12 @@ "publisherDisplayName": "Microsoft" } } - ] + ], + "extensionsGallery": { + "serviceUrl": "https://open-vsx.org/vscode/gallery", + "itemUrl": "https://open-vsx.org/vscode/item" + }, + "linkProtectionTrustedDomains": [ + "https://open-vsx.org" + ] } diff --git a/src/server-main.js b/src/server-main.js index bb5e3aded35db..ce5ab19412098 100644 --- a/src/server-main.js +++ b/src/server-main.js @@ -21,7 +21,7 @@ async function start() { // Do a quick parse to determine if a server or the cli needs to be started const parsedArgs = minimist(process.argv.slice(2), { boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms'], - string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'pick-port', 'compatibility'], + string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'pick-port', 'compatibility', 'server-root-prefix'], alias: { help: 'h', version: 'v' } }); ['host', 'port', 'accept-server-license-terms'].forEach(e => { diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index 63d6a15b49edb..43c1be2790cf7 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -112,7 +112,7 @@ class RemoteAuthoritiesImpl { private readonly _connectionTokens: { [authority: string]: string | undefined } = Object.create(null); private _preferredWebSchema: 'http' | 'https' = 'http'; private _delegate: ((uri: URI) => URI) | null = null; - private _remoteResourcesPath: string = `/${Schemas.vscodeRemoteResource}`; + private _remoteResourcesPath: { [authority: string]: string } = Object.create(null); setPreferredWebSchema(schema: 'http' | 'https') { this._preferredWebSchema = schema; @@ -122,8 +122,8 @@ class RemoteAuthoritiesImpl { this._delegate = delegate; } - setServerRootPath(serverRootPath: string): void { - this._remoteResourcesPath = `${serverRootPath}/${Schemas.vscodeRemoteResource}`; + setServerRootPath(authority: string, serverRootPath: string): void { + this._remoteResourcesPath[authority] = `${serverRootPath}/${Schemas.vscodeRemoteResource}`; } set(authority: string, host: string, port: number): void { @@ -157,7 +157,7 @@ class RemoteAuthoritiesImpl { return URI.from({ scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, authority: `${host}:${port}`, - path: this._remoteResourcesPath, + path: this._remoteResourcesPath[authority], query }); } diff --git a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts index e9231a1df85da..4386efbab596b 100644 --- a/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts @@ -20,17 +20,24 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot private readonly _cache: Map; private readonly _connectionToken: string | undefined; + private readonly _serverRootPrefix: string | undefined; private readonly _connectionTokens: Map; + private readonly _serverRootPrefixes: Map; - constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) { + constructor( + @IProductService private _productService: IProductService, + connectionToken: string | undefined, + resourceUriProvider: ((uri: URI) => URI) | undefined, + serverRootPrefix: string | undefined) { super(); this._cache = new Map(); this._connectionToken = connectionToken; + this._serverRootPrefix = serverRootPrefix; this._connectionTokens = new Map(); + this._serverRootPrefixes = new Map(); if (resourceUriProvider) { RemoteAuthorities.setDelegate(resourceUriProvider); } - RemoteAuthorities.setServerRootPath(getRemoteServerRootPath(productService)); } async resolveAuthority(authority: string): Promise { @@ -62,12 +69,13 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot private _doResolveAuthority(authority: string): ResolverResult { const connectionToken = this._connectionTokens.get(authority) || this._connectionToken; + const serverRootPrefix = this._serverRootPrefixes.get(authority) || this._serverRootPrefix; if (authority.indexOf(':') >= 0) { const pieces = authority.split(':'); - return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken } }; + return { authority: { authority, host: pieces[0], port: parseInt(pieces[1], 10), connectionToken, serverRootPrefix } }; } const port = (/^https:/.test(window.location.href) ? 443 : 80); - return { authority: { authority, host: authority, port: port, connectionToken } }; + return { authority: { authority, host: authority, port: port, connectionToken, serverRootPrefix } }; } _clearResolvedAuthority(authority: string): void { @@ -85,6 +93,12 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot this._onDidChangeConnectionData.fire(); } + _setAuthorityServerRootPath(authority: string, serverRootPrefix: string | undefined): void { + this._serverRootPrefixes.set(authority, serverRootPrefix); + RemoteAuthorities.setServerRootPath(authority, getRemoteServerRootPath(this._productService, serverRootPrefix)); + this._onDidChangeConnectionData.fire(); + } + _setCanonicalURIProvider(provider: (uri: URI) => Promise): void { } } diff --git a/src/vs/platform/remote/common/remoteAgentConnection.ts b/src/vs/platform/remote/common/remoteAgentConnection.ts index 2335efbde293a..d444d815f71f3 100644 --- a/src/vs/platform/remote/common/remoteAgentConnection.ts +++ b/src/vs/platform/remote/common/remoteAgentConnection.ts @@ -80,6 +80,7 @@ interface ISimpleConnectionOptions { socketFactory: ISocketFactory; signService: ISignService; logService: ILogService; + serverRootPrefix: string | undefined; } export interface IConnectCallback { @@ -233,7 +234,7 @@ async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptio let socket: ISocket; try { - socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options), `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); + socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options, options.serverRootPrefix), `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); } catch (error) { options.logService.error(`${logPrefix} socketFactory.connect() failed or timed out. Error:`); options.logService.error(error); @@ -391,7 +392,7 @@ export interface IConnectionOptions { } async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise { - const { host, port, connectionToken } = await options.addressProvider.getAddress(); + const { host, port, connectionToken, serverRootPrefix } = await options.addressProvider.getAddress(); return { commit: options.commit, quality: options.quality, @@ -402,7 +403,8 @@ async function resolveConnectionOptions(options: IConnectionOptions, reconnectio reconnectionProtocol: reconnectionProtocol, socketFactory: options.socketFactory, signService: options.signService, - logService: options.logService + logService: options.logService, + serverRootPrefix: serverRootPrefix, }; } @@ -410,6 +412,7 @@ export interface IAddress { host: string; port: number; connectionToken: string | undefined; + serverRootPrefix: string | undefined; } export interface IAddressProvider { diff --git a/src/vs/platform/remote/common/remoteAgentEnvironment.ts b/src/vs/platform/remote/common/remoteAgentEnvironment.ts index c1d3bfb2357b2..2937396edf94a 100644 --- a/src/vs/platform/remote/common/remoteAgentEnvironment.ts +++ b/src/vs/platform/remote/common/remoteAgentEnvironment.ts @@ -10,6 +10,7 @@ import { URI } from 'vs/base/common/uri'; export interface IRemoteAgentEnvironment { pid: number; connectionToken: string; + serverRootPrefix: string | undefined; appRoot: URI; settingsPath: URI; logsPath: URI; diff --git a/src/vs/platform/remote/common/remoteAuthorityResolver.ts b/src/vs/platform/remote/common/remoteAuthorityResolver.ts index 663eeaee64bf2..77bda3b40ea18 100644 --- a/src/vs/platform/remote/common/remoteAuthorityResolver.ts +++ b/src/vs/platform/remote/common/remoteAuthorityResolver.ts @@ -15,6 +15,7 @@ export interface ResolvedAuthority { readonly host: string; readonly port: number; readonly connectionToken: string | undefined; + readonly serverRootPrefix: string | undefined; } export interface ResolvedOptions { @@ -120,5 +121,6 @@ export interface IRemoteAuthorityResolverService { _setResolvedAuthority(resolvedAuthority: ResolvedAuthority, resolvedOptions?: ResolvedOptions): void; _setResolvedAuthorityError(authority: string, err: any): void; _setAuthorityConnectionToken(authority: string, connectionToken: string): void; + _setAuthorityServerRootPath(authority: string, serverRootPath: string | undefined): void; _setCanonicalURIProvider(provider: (uri: URI) => Promise): void; } diff --git a/src/vs/platform/remote/common/remoteHosts.ts b/src/vs/platform/remote/common/remoteHosts.ts index 760033e5789e4..32377c1e2d703 100644 --- a/src/vs/platform/remote/common/remoteHosts.ts +++ b/src/vs/platform/remote/common/remoteHosts.ts @@ -28,8 +28,10 @@ export function getRemoteName(authority: string | undefined): string | undefined /** * The root path to use when accessing the remote server. The path contains the quality and commit of the current build. * @param product + * @param serverRootPrefix * @returns */ -export function getRemoteServerRootPath(product: { quality?: string; commit?: string }): string { - return `/${product.quality ?? 'oss'}-${product.commit ?? 'dev'}`; +export function getRemoteServerRootPath(product: { quality?: string; commit?: string }, serverRootPrefix: string | undefined): string { + const prefix = serverRootPrefix ? `/${serverRootPrefix}` : ''; + return `${prefix}/${product.quality ?? 'oss'}-${product.commit ?? 'dev'}`; } diff --git a/src/vs/platform/remote/electron-sandbox/remoteAuthorityResolverService.ts b/src/vs/platform/remote/electron-sandbox/remoteAuthorityResolverService.ts index 36bca9adf942f..64b8a7f85a219 100644 --- a/src/vs/platform/remote/electron-sandbox/remoteAuthorityResolverService.ts +++ b/src/vs/platform/remote/electron-sandbox/remoteAuthorityResolverService.ts @@ -48,16 +48,16 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot private readonly _resolveAuthorityRequests: Map>; private readonly _connectionTokens: Map; private readonly _canonicalURIRequests: Map>; + private readonly _serverRootPrefixes: Map; private _canonicalURIProvider: ((uri: URI) => Promise) | null; - constructor(@IProductService productService: IProductService) { + constructor(@IProductService private _productService: IProductService) { super(); this._resolveAuthorityRequests = new Map>(); this._connectionTokens = new Map(); this._canonicalURIRequests = new Map>(); this._canonicalURIProvider = null; - - RemoteAuthorities.setServerRootPath(getRemoteServerRootPath(productService)); + this._serverRootPrefixes = new Map(); } resolveAuthority(authority: string): Promise { @@ -128,6 +128,12 @@ export class RemoteAuthorityResolverService extends Disposable implements IRemot this._onDidChangeConnectionData.fire(); } + _setAuthorityServerRootPath(authority: string, serverRootPrefix: string | undefined): void { + this._serverRootPrefixes.set(authority, serverRootPrefix); + RemoteAuthorities.setServerRootPath(authority, getRemoteServerRootPath(this._productService, serverRootPrefix)); + this._onDidChangeConnectionData.fire(); + } + _setCanonicalURIProvider(provider: (uri: URI) => Promise): void { this._canonicalURIProvider = provider; this._canonicalURIRequests.forEach((value) => { diff --git a/src/vs/server/node/remoteAgentEnvironmentImpl.ts b/src/vs/server/node/remoteAgentEnvironmentImpl.ts index dd7ebc3daa62e..0c83dd170990f 100644 --- a/src/vs/server/node/remoteAgentEnvironmentImpl.ts +++ b/src/vs/server/node/remoteAgentEnvironmentImpl.ts @@ -41,6 +41,7 @@ export class RemoteAgentEnvironmentChannel implements IServerChannel { private readonly _logService: ILogService, private readonly _extensionHostStatusService: IExtensionHostStatusService, private readonly _extensionsScannerService: IExtensionsScannerService, + private readonly _serverRootPrefix: string | undefined, ) { if (_environmentService.args['install-builtin-extension']) { const installOptions: InstallOptions = { isMachineScoped: !!_environmentService.args['do-not-sync'], installPreReleaseVersion: !!_environmentService.args['pre-release'] }; @@ -285,6 +286,7 @@ export class RemoteAgentEnvironmentChannel implements IServerChannel { return { pid: process.pid, connectionToken: (this._connectionToken.type !== ServerConnectionTokenType.None ? this._connectionToken.value : ''), + serverRootPrefix: this._serverRootPrefix, appRoot: URI.file(this._environmentService.appRoot), settingsPath: this._environmentService.machineSettingsResource, logsPath: URI.file(this._environmentService.logsPath), diff --git a/src/vs/server/node/remoteExtensionHostAgentServer.ts b/src/vs/server/node/remoteExtensionHostAgentServer.ts index 07a850e5ccfa3..d2af828bf5abc 100644 --- a/src/vs/server/node/remoteExtensionHostAgentServer.ts +++ b/src/vs/server/node/remoteExtensionHostAgentServer.ts @@ -71,6 +71,7 @@ export class RemoteExtensionHostAgentServer extends Disposable implements IServe private readonly _socketServer: SocketServer, private readonly _connectionToken: ServerConnectionToken, private readonly _vsdaMod: typeof vsda | null, + serverRootPrefix: string | undefined, hasWebClient: boolean, @IServerEnvironmentService private readonly _environmentService: IServerEnvironmentService, @IProductService private readonly _productService: IProductService, @@ -79,13 +80,13 @@ export class RemoteExtensionHostAgentServer extends Disposable implements IServe ) { super(); - this._serverRootPath = getRemoteServerRootPath(_productService); + this._serverRootPath = getRemoteServerRootPath(_productService, serverRootPrefix); this._extHostConnections = Object.create(null); this._managementConnections = Object.create(null); this._allReconnectionTokens = new Set(); this._webClientServer = ( hasWebClient - ? this._instantiationService.createInstance(WebClientServer, this._connectionToken) + ? this._instantiationService.createInstance(WebClientServer, this._connectionToken, serverRootPrefix) : null ); this._logService.info(`Extension host agent started.`); @@ -660,6 +661,7 @@ export interface IServerAPI { export async function createServer(address: string | net.AddressInfo | null, args: ServerParsedArgs, REMOTE_DATA_FOLDER: string): Promise { const connectionToken = await determineServerConnectionToken(args); + const rootServerPath = args['server-root-prefix']; if (connectionToken instanceof ServerConnectionTokenParseError) { console.warn(connectionToken.message); process.exit(1); @@ -740,10 +742,11 @@ export async function createServer(address: string | net.AddressInfo | null, arg if (hasWebClient && address && typeof address !== 'string') { // ships the web ui! const queryPart = (connectionToken.type !== ServerConnectionTokenType.None ? `?${connectionTokenQueryName}=${connectionToken.value}` : ''); - console.log(`Web UI available at http://localhost${address.port === 80 ? '' : `:${address.port}`}/${queryPart}`); + const _rootServerPath = rootServerPath ?? ''; + console.log(`Web UI available at http://localhost${address.port === 80 ? '' : `:${address.port}`}/${_rootServerPath}${queryPart}`); } - const remoteExtensionHostAgentServer = instantiationService.createInstance(RemoteExtensionHostAgentServer, socketServer, connectionToken, vsdaMod, hasWebClient); + const remoteExtensionHostAgentServer = instantiationService.createInstance(RemoteExtensionHostAgentServer, socketServer, connectionToken, vsdaMod, rootServerPath, hasWebClient); perf.mark('code/server/ready'); const currentTime = performance.now(); diff --git a/src/vs/server/node/serverEnvironmentService.ts b/src/vs/server/node/serverEnvironmentService.ts index f291461470d91..f36a73efe3f52 100644 --- a/src/vs/server/node/serverEnvironmentService.ts +++ b/src/vs/server/node/serverEnvironmentService.ts @@ -84,6 +84,8 @@ export const serverOptions: OptionDescriptions = { 'compatibility': { type: 'string' }, + 'server-root-prefix': { type: 'string' }, + _: OPTIONS['_'] }; @@ -190,6 +192,8 @@ export interface ServerParsedArgs { 'use-host-proxy'?: boolean; 'without-browser-env-var'?: boolean; + 'server-root-prefix'?: string; + /* ----- server cli ----- */ help: boolean; version: boolean; diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index a1f9cd11405e6..dcbb7d9d68b72 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -181,7 +181,8 @@ export async function setupServerServices(connectionToken: ServerConnectionToken instantiationService.invokeFunction(accessor => { const extensionManagementService = accessor.get(IExtensionManagementService); const extensionsScannerService = accessor.get(IExtensionsScannerService); - const remoteExtensionEnvironmentChannel = new RemoteAgentEnvironmentChannel(connectionToken, environmentService, extensionManagementCLIService, logService, extensionHostStatusService, extensionsScannerService); + const serverRootPrefix = args['server-root-prefix']; + const remoteExtensionEnvironmentChannel = new RemoteAgentEnvironmentChannel(connectionToken, environmentService, extensionManagementCLIService, logService, extensionHostStatusService, extensionsScannerService, serverRootPrefix); socketServer.registerChannel('remoteextensionsenvironment', remoteExtensionEnvironmentChannel); const telemetryChannel = new ServerTelemetryChannel(accessor.get(IServerTelemetryService), appInsightsAppender); diff --git a/src/vs/server/node/webClientServer.ts b/src/vs/server/node/webClientServer.ts index 04f35bdd3c3f0..1f195d2008a3e 100644 --- a/src/vs/server/node/webClientServer.ts +++ b/src/vs/server/node/webClientServer.ts @@ -102,13 +102,14 @@ export class WebClientServer { constructor( private readonly _connectionToken: ServerConnectionToken, + private readonly _serverRootPrefix: string | undefined, @IServerEnvironmentService private readonly _environmentService: IServerEnvironmentService, @ILogService private readonly _logService: ILogService, @IRequestService private readonly _requestService: IRequestService, @IProductService private readonly _productService: IProductService, ) { this._webExtensionResourceUrlTemplate = this._productService.extensionsGallery?.resourceUrlTemplate ? URI.parse(this._productService.extensionsGallery.resourceUrlTemplate) : undefined; - const serverRootPath = getRemoteServerRootPath(_productService); + const serverRootPath = getRemoteServerRootPath(_productService, this._serverRootPrefix); this._staticRoute = `${serverRootPath}/static`; this._callbackRoute = `${serverRootPath}/callback`; this._webExtensionRoute = `${serverRootPath}/web-extension-resource`; @@ -126,7 +127,8 @@ export class WebClientServer { if (pathname.startsWith(this._staticRoute) && pathname.charCodeAt(this._staticRoute.length) === CharCode.Slash) { return this._handleStatic(req, res, parsedUrl); } - if (pathname === '/') { + const rootPath = this._serverRootPrefix ? `/${this._serverRootPrefix}` : '/'; + if (pathname === rootPath) { return this._handleRoot(req, res, parsedUrl); } if (pathname === this._callbackRoute) { @@ -260,7 +262,7 @@ export class WebClientServer { newQuery[key] = parsedUrl.query[key]; } } - const newLocation = url.format({ pathname: '/', query: newQuery }); + const newLocation = url.format({ pathname: this._serverRootPrefix ?? '/', query: newQuery }); responseHeaders['Location'] = newLocation; res.writeHead(302, responseHeaders); diff --git a/src/vs/workbench/api/common/extHostExtensionService.ts b/src/vs/workbench/api/common/extHostExtensionService.ts index d23efb3a11184..3a53d041c1e7a 100644 --- a/src/vs/workbench/api/common/extHostExtensionService.ts +++ b/src/vs/workbench/api/common/extHostExtensionService.ts @@ -781,7 +781,8 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme authority: remoteAuthority, host: result.host, port: result.port, - connectionToken: result.connectionToken + connectionToken: result.connectionToken, + serverRootPrefix: result.serverRootPrefix, }; const options: ResolvedOptions = { extensionHostEnv: result.extensionHostEnv, diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index a1c2a3ea107ae..e9aad719600d0 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -456,8 +456,9 @@ export class ResolvedAuthority { readonly host: string; readonly port: number; readonly connectionToken: string | undefined; + readonly serverRootPrefix: string | undefined; - constructor(host: string, port: number, connectionToken?: string) { + constructor(host: string, port: number, serverRootPrefix: string | undefined, connectionToken?: string) { if (typeof host !== 'string' || host.length === 0) { throw illegalArgument('host'); } @@ -472,6 +473,7 @@ export class ResolvedAuthority { this.host = host; this.port = Math.round(port); this.connectionToken = connectionToken; + this.serverRootPrefix = serverRootPrefix; } } diff --git a/src/vs/workbench/browser/web.api.ts b/src/vs/workbench/browser/web.api.ts index f41ce51c11882..2cb931fa23a7b 100644 --- a/src/vs/workbench/browser/web.api.ts +++ b/src/vs/workbench/browser/web.api.ts @@ -127,6 +127,11 @@ export interface IWorkbenchConstructionOptions { */ readonly connectionToken?: string; + /** + * The server root prefix. + */ + readonly serverRootPrefix?: string; + /** * An endpoint to serve iframe content ("webview") from. This is required * to provide full security isolation from the workbench host. diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index b8a397edac4d0..0e78350b82ed5 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -205,7 +205,8 @@ export class BrowserMain extends Disposable { // Remote const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName); - const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider); + const serverRootPrefix = environmentService.options.serverRootPrefix || document.location.pathname.slice(1); + const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider, serverRootPrefix); serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); // Signing diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index c77ee7bf963a0..f60f150dc011f 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -488,7 +488,8 @@ class Extensions extends Disposable { } private async mapInstalledExtensionWithCompatibleGalleryExtension(galleryExtensions: IGalleryExtension[]): Promise<[Extension, IGalleryExtension][]> { - const mappedExtensions = this.mapInstalledExtensionWithGalleryExtension(galleryExtensions); + // don't update built-in extensions + const mappedExtensions = this.mapInstalledExtensionWithGalleryExtension(galleryExtensions).filter(([ext]) => !ext.isBuiltin); const targetPlatform = await this.server.extensionManagementService.getTargetPlatform(); const compatibleGalleryExtensions: IGalleryExtension[] = []; const compatibleGalleryExtensionsToFetch: IExtensionInfo[] = []; diff --git a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts index d36be57c24764..ff9854a63dda7 100644 --- a/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts +++ b/src/vs/workbench/services/configuration/test/browser/configurationService.test.ts @@ -80,7 +80,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); }); @@ -120,7 +120,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); const actual = testObject.getWorkspaceFolder(joinPath(folder, 'a')); @@ -140,7 +140,7 @@ suite('WorkspaceContextService - Folder', () => { const environmentService = TestEnvironmentService; fileService.registerProvider(Schemas.vscodeUserData, disposables.add(new FileUserDataProvider(ROOT.scheme, fileSystemProvider, Schemas.vscodeUserData, new NullLogService()))); - const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); + const testObject = disposables.add(new WorkspaceService({ configurationCache: new ConfigurationCache() }, environmentService, fileService, new RemoteAgentService(null, environmentService, TestProductService, new RemoteAuthorityResolverService(TestProductService, undefined, undefined, undefined), new SignService(undefined), new NullLogService()), new UriIdentityService(fileService), new NullLogService(), new NullPolicyService())); await (testObject).initialize(convertToWorkspacePayload(folder)); diff --git a/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts b/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts index 6991120b69165..9601263396188 100644 --- a/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts +++ b/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts @@ -61,7 +61,7 @@ export abstract class AbstractExtensionResourceLoaderService implements IExtensi private readonly _environmentService: IEnvironmentService, private readonly _configurationService: IConfigurationService, ) { - this._webExtensionResourceEndPoint = `${getRemoteServerRootPath(_productService)}/${WEB_EXTENSION_RESOURCE_END_POINT}/`; + this._webExtensionResourceEndPoint = `${getRemoteServerRootPath(_productService, undefined)}/${WEB_EXTENSION_RESOURCE_END_POINT}/`; if (_productService.extensionsGallery) { this._extensionGalleryResourceUrlTemplate = _productService.extensionsGallery.resourceUrlTemplate; this._extensionGalleryAuthority = this._extensionGalleryResourceUrlTemplate ? this._getExtensionGalleryAuthority(URI.parse(this._extensionGalleryResourceUrlTemplate)) : undefined; diff --git a/src/vs/workbench/services/extensions/common/extensions.ts b/src/vs/workbench/services/extensions/common/extensions.ts index 722dba8dd6b26..deff379f11018 100644 --- a/src/vs/workbench/services/extensions/common/extensions.ts +++ b/src/vs/workbench/services/extensions/common/extensions.ts @@ -359,10 +359,10 @@ function extensionDescriptionArrayToMap(extensions: IExtensionDescription[]): Ma } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { - if (!extension.enabledApiProposals) { - return false; - } - return extension.enabledApiProposals.includes(proposal); + /* + * Just enable all proposal for now + */ + return true; } export function checkProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): void { diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts index a699e459da39d..e1a5e30b0b553 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHost.ts @@ -96,7 +96,7 @@ export class RemoteExtensionHost extends Disposable implements IExtensionHost { addressProvider: { getAddress: async () => { const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(this._initDataProvider.remoteAuthority); - return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken }; + return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken, serverRootPrefix: authority.serverRootPrefix }; } }, signService: this._signService, diff --git a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts index ea87ef0642a9f..8d7f6185ba94b 100644 --- a/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts +++ b/src/vs/workbench/services/extensions/electron-sandbox/electronExtensionService.ts @@ -355,7 +355,8 @@ export abstract class ElectronExtensionService extends AbstractExtensionService authority: remoteAuthority, host: remoteAuthority.substring(0, lastColon), port: parseInt(remoteAuthority.substring(lastColon + 1), 10), - connectionToken: undefined + connectionToken: undefined, + serverRootPrefix: undefined, } }; } diff --git a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts index 0eba0de6b0072..8961194043aab 100644 --- a/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts +++ b/src/vs/workbench/services/remote/common/abstractRemoteAgentService.ts @@ -61,6 +61,7 @@ export abstract class AbstractRemoteAgentService extends Disposable implements I async (channel, connection) => { const env = await RemoteExtensionEnvironmentChannelClient.getEnvironmentData(channel, connection.remoteAuthority); this._remoteAuthorityResolverService._setAuthorityConnectionToken(connection.remoteAuthority, env.connectionToken); + this._remoteAuthorityResolverService._setAuthorityServerRootPath(connection.remoteAuthority, env.serverRootPrefix); return env; }, null @@ -225,7 +226,7 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon this._onReconnecting.fire(undefined); } const { authority } = await this._remoteAuthorityResolverService.resolveAuthority(this.remoteAuthority); - return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken }; + return { host: authority.host, port: authority.port, connectionToken: authority.connectionToken, serverRootPrefix: authority.serverRootPrefix }; } }, signService: this._signService, diff --git a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts index 35bfae00a4d00..a48580f9befeb 100644 --- a/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts +++ b/src/vs/workbench/services/remote/common/remoteAgentEnvironmentChannel.ts @@ -39,6 +39,7 @@ export interface IScanSingleExtensionArguments { export interface IRemoteAgentEnvironmentDTO { pid: number; connectionToken: string; + serverRootPrefix: string | undefined; appRoot: UriComponents; settingsPath: UriComponents; logsPath: UriComponents; @@ -66,6 +67,7 @@ export class RemoteExtensionEnvironmentChannelClient { return { pid: data.pid, connectionToken: data.connectionToken, + serverRootPrefix: data.serverRootPrefix, appRoot: URI.revive(data.appRoot), settingsPath: URI.revive(data.settingsPath), logsPath: URI.revive(data.logsPath), diff --git a/src/vscode-dts/vscode.proposed.resolvers.d.ts b/src/vscode-dts/vscode.proposed.resolvers.d.ts index f436a5625ba7c..350c43becfa30 100644 --- a/src/vscode-dts/vscode.proposed.resolvers.d.ts +++ b/src/vscode-dts/vscode.proposed.resolvers.d.ts @@ -22,6 +22,7 @@ declare module 'vscode' { readonly host: string; readonly port: number; readonly connectionToken: string | undefined; + readonly serverRootPrefix: string | undefined; constructor(host: string, port: number, connectionToken?: string); }