Add VSCODE_PROXY_URI environment variable This can be used by extensions to open a port and access it through the proxy. It is available in the terminal as well. This can be tested using printenv in the terminal and by using the codeServerTest.proxyUri command through the test extension (copy it into your extensions, use --extensions-dir, or symlink it). This has e2e tests. Index: code-server/lib/vscode/src/vs/base/common/product.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/product.ts +++ code-server/lib/vscode/src/vs/base/common/product.ts @@ -35,6 +35,7 @@ export interface IProductConfiguration { readonly rootEndpoint?: string readonly updateEndpoint?: string readonly logoutEndpoint?: string + readonly proxyEndpointTemplate?: string readonly version: string; readonly date?: string; Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts @@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/comm import { RemoteAuthorities } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; import { IProductService } from 'vs/platform/product/common/productService'; -import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts'; export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService { @@ -23,7 +23,7 @@ export class RemoteAuthorityResolverServ private readonly _connectionToken: Promise<string> | string | undefined; private readonly _connectionTokens: Map<string, string>; - constructor(@IProductService productService: IProductService, connectionToken: Promise<string> | string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) { + constructor(@IProductService productService: IProductService, connectionToken: Promise<string> | string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: string) { super(); this._connectionToken = connectionToken; this._connectionTokens = new Map<string, string>(); @@ -61,9 +61,14 @@ export class RemoteAuthorityResolverServ private async _doResolveAuthority(authority: string): Promise<ResolverResult> { const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken); + let options: ResolvedOptions | undefined; + if (this.proxyEndpointTemplate) { + const proxyUrl = new URL(this.proxyEndpointTemplate, window.location.href); + options = { extensionHostEnv: { VSCODE_PROXY_URI: decodeURIComponent(proxyUrl.toString()) }} + } const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80); const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort); - const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken } }; + const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken }, options }; RemoteAuthorities.set(authority, result.authority.host, result.authority.port); this._cache.set(authority, result); this._onDidChangeConnectionData.fire(); Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts @@ -314,6 +314,7 @@ export class WebClientServer { rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, + proxyEndpointTemplate: base + '/proxy/{{port}}', embedderIdentifier: 'server-distro', extensionsGallery: this._productService.extensionsGallery, }, Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts @@ -247,7 +247,7 @@ export class BrowserMain extends Disposa // Remote const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName); - const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider); + const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider, this.configuration.productConfiguration?.proxyEndpointTemplate); serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); // Signing Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -388,7 +388,7 @@ export async function createTerminalEnvi // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables - sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI'); + sanitizeProcessEnvironment(env, 'VSCODE_IPC_HOOK_CLI', 'VSCODE_PROXY_URI'); // Merge config (settings) and ShellLaunchConfig environments mergeEnvironments(env, allowedEnvFromConfig);