Skip to content

Commit b942eb1

Browse files
committed
Add VSCODE_PROXY_URI to extension environment
This allows extensions to open windows to local ports via the proxy. Closes #1510.
1 parent b59b393 commit b942eb1

File tree

6 files changed

+31
-14
lines changed

6 files changed

+31
-14
lines changed

lib/vscode/src/vs/server/entry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ process.on('message', async (message: CodeServerMessage, socket) => {
7070
}
7171
break;
7272
case 'socket':
73-
vscode.handleWebSocket(socket, message.query, message.permessageDeflate);
73+
vscode.handleWebSocket(socket, message.query, message.options);
7474
break;
7575
}
7676
});

lib/vscode/src/vs/server/node/connection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ export class ExtensionHostConnection extends Connection {
114114
protocol: Protocol,
115115
private readonly params: IRemoteExtensionHostStartParams,
116116
private readonly environment: INativeEnvironmentService,
117+
private readonly proxyUri: string
117118
) {
118119
super(protocol, 'exthost');
119120

@@ -183,6 +184,7 @@ export class ExtensionHostConnection extends Connection {
183184
VSCODE_LOG_LEVEL: process.env.LOG_LEVEL,
184185
VSCODE_NLS_CONFIG: JSON.stringify(config),
185186
VSCODE_PARENT_PID: String(process.pid),
187+
VSCODE_PROXY_URI: this.proxyUri,
186188
},
187189
silent: true,
188190
},

lib/vscode/src/vs/server/node/server.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { getMachineId } from 'vs/base/node/id';
99
import { ClientConnectionEvent, IPCServer, IServerChannel, ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
1010
import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner';
1111
import { main } from 'vs/code/node/cliProcessMain';
12-
import { Query, VscodeOptions, WorkbenchOptions } from 'vs/ipc';
12+
import { Query, SocketOptions, VscodeOptions, WorkbenchOptions } from 'vs/ipc';
1313
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1414
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
1515
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
@@ -46,6 +46,7 @@ import { TelemetryLogAppender } from 'vs/platform/telemetry/common/telemetryLogA
4646
import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
4747
import { combinedAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
4848
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
49+
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
4950
import { TelemetryChannel } from 'vs/server/common/telemetry';
5051
import { ExtensionEnvironmentChannel, FileProviderChannel, TerminalProviderChannel } from 'vs/server/node/channel';
5152
import { Connection, ExtensionHostConnection, ManagementConnection } from 'vs/server/node/connection';
@@ -57,7 +58,6 @@ import { getUriTransformer } from 'vs/server/node/util';
5758
import { REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel';
5859
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteAgentFileSystemChannel';
5960
import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService';
60-
import { PtyHostService } from 'vs/platform/terminal/node/ptyHostService';
6161

6262
const commit = product.commit || 'development';
6363

@@ -79,7 +79,7 @@ export class Vscode {
7979
public async initialize(options: VscodeOptions): Promise<WorkbenchOptions> {
8080
const transformer = getUriTransformer(options.remoteAuthority);
8181
if (!this.servicesPromise) {
82-
this.servicesPromise = this.initializeServices(options.args);
82+
this.servicesPromise = this.initializeServices(options);
8383
}
8484
await this.servicesPromise;
8585
const environment = this.services.get(IEnvironmentService) as INativeEnvironmentService;
@@ -116,25 +116,25 @@ export class Vscode {
116116
};
117117
}
118118

119-
public async handleWebSocket(socket: net.Socket, query: Query, permessageDeflate: boolean): Promise<true> {
119+
public async handleWebSocket(socket: net.Socket, query: Query, options: SocketOptions): Promise<true> {
120120
if (!query.reconnectionToken) {
121121
throw new Error('Reconnection token is missing from query parameters');
122122
}
123123
const protocol = new Protocol(socket, {
124124
reconnectionToken: <string>query.reconnectionToken,
125125
reconnection: query.reconnection === 'true',
126126
skipWebSocketFrames: query.skipWebSocketFrames === 'true',
127-
permessageDeflate,
127+
permessageDeflate: options.permessageDeflate,
128128
});
129129
try {
130-
await this.connect(await protocol.handshake(), protocol);
130+
await this.connect(await protocol.handshake(), protocol, options.proxyUri);
131131
} catch (error) {
132132
protocol.destroy(error.message);
133133
}
134134
return true;
135135
}
136136

137-
private async connect(message: ConnectionTypeRequest, protocol: Protocol): Promise<void> {
137+
private async connect(message: ConnectionTypeRequest, protocol: Protocol, proxyUri: string): Promise<void> {
138138
if (product.commit && message.commit !== product.commit) {
139139
logger.warn(`Version mismatch (${message.commit} instead of ${product.commit})`);
140140
}
@@ -185,6 +185,7 @@ export class Vscode {
185185
...message.args,
186186
},
187187
this.services.get(IEnvironmentService) as INativeEnvironmentService,
188+
proxyUri,
188189
);
189190
}
190191
connections.set(token, connection);
@@ -211,9 +212,9 @@ export class Vscode {
211212
// References:
212213
// ../../electron-browser/sharedProcess/sharedProcessMain.ts#L148
213214
// ../../../code/electron-main/app.ts
214-
private async initializeServices(args: NativeParsedArgs): Promise<void> {
215+
private async initializeServices(options: VscodeOptions): Promise<void> {
215216
const productService = { _serviceBrand: undefined, ...product };
216-
const environmentService = new NativeEnvironmentService(args, productService);
217+
const environmentService = new NativeEnvironmentService(options.args, productService);
217218

218219
await Promise.all([
219220
environmentService.extensionsPath,

src/node/routes/vscode.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,14 @@ wsRouter.ws("/", ensureAuthenticated, async (req) => {
227227

228228
req.ws.write(responseHeaders.join("\r\n") + "\r\n\r\n")
229229

230-
await vscode.sendWebsocket(req.ws, req.query, useCompression)
230+
await vscode.sendWebsocket(req.ws, req.query, {
231+
permessageDeflate: useCompression,
232+
// NOTE: Was going to use a domain proxy if one was set but maybe it makes
233+
// sense to just use the path proxy for now unless it presents problems.
234+
// TODO: We won't have the base path if code-server is being served behind a
235+
// proxy that is rewriting the path. We will need to send the full path from
236+
// the client when making this connection (possibly as a query param like
237+
// the token, etc).
238+
proxyUri: `${req.headers.host || ""}/proxy/{port}`,
239+
})
231240
})

src/node/vscode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,12 @@ export class VscodeProvider {
120120
/**
121121
* VS Code expects a raw socket. It will handle all the web socket frames.
122122
*/
123-
public async sendWebsocket(socket: net.Socket, query: ipc.Query, permessageDeflate: boolean): Promise<void> {
123+
public async sendWebsocket(socket: net.Socket, query: ipc.Query, options: ipc.SocketOptions): Promise<void> {
124124
const vscode = await this._vscode
125125
// TLS sockets cannot be transferred to child processes so we need an
126126
// in-between. Non-TLS sockets will be returned as-is.
127127
const socketProxy = await this.socketProvider.createProxy(socket)
128-
this.send({ type: "socket", query, permessageDeflate }, vscode, socketProxy)
128+
this.send({ type: "socket", query, options }, vscode, socketProxy)
129129
}
130130

131131
private send(message: ipc.CodeServerMessage, vscode?: cp.ChildProcess, socket?: net.Socket): void {

typings/ipc.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ export interface InitMessage {
2222

2323
export type Query = { [key: string]: string | string[] | undefined | Query | Query[] }
2424

25+
export interface SocketOptions {
26+
permessageDeflate: boolean
27+
proxyUri: string
28+
}
29+
2530
export interface SocketMessage {
2631
type: "socket"
2732
query: Query
28-
permessageDeflate: boolean
33+
options: SocketOptions
2934
}
3035

3136
export interface CliMessage {

0 commit comments

Comments
 (0)