Skip to content

Commit 518cd75

Browse files
committed
Fix issues surrounding built in extensions.
1 parent 77a5f2b commit 518cd75

File tree

9 files changed

+141
-106
lines changed

9 files changed

+141
-106
lines changed

resources/web/code-web.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import * as http from 'http';
22
import { IServerWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
33

4-
export function requestHandler(req: http.IncomingMessage, res: http.ServerResponse, webConfigJSON?: IServerWorkbenchConstructionOptions): void;
4+
export function requestHandler(req: http.IncomingMessage, res: http.ServerResponse, webConfigJSON: IServerWorkbenchConstructionOptions): void;

resources/web/code-web.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,11 @@ const requestHandler = (req, res, webConfigJSON) => {
272272
} else if (pathname === '/fetch-callback') {
273273
// callback fetch support
274274
return handleFetchCallback(req, res, parsedUrl);
275+
} else if (pathname === '/vscode-remote-resource') {
276+
// callback fetch support
277+
return handleRemoteResource(req, res, parsedUrl);
275278
} else if (pathname === '/builtin') {
276-
// builtin extnesions JSON
279+
// builtin extensions JSON
277280
return handleBuiltInExtensions(req, res, parsedUrl);
278281
}
279282

@@ -330,6 +333,20 @@ async function handleBuiltInExtensions(req, res, parsedUrl) {
330333
return res.end(JSON.stringify(extensions));
331334
}
332335

336+
/**
337+
* @param {import('http').IncomingMessage} req
338+
* @param {import('http').ServerResponse} res
339+
* @param {import('url').UrlWithParsedQuery} parsedUrl
340+
*/
341+
async function handleRemoteResource(req, res, parsedUrl) {
342+
const { path } = parsedUrl.query;
343+
344+
if (path) {
345+
res.setHeader('Content-Type', getMediaMime(path));
346+
res.end(await readFile(path));
347+
}
348+
}
349+
333350
/**
334351
* @param {import('http').IncomingMessage} req
335352
* @param {import('http').ServerResponse} res
@@ -673,7 +690,7 @@ const mapExtToMediaMimes = {
673690
function getMediaMime(forPath) {
674691
const ext = path.extname(forPath);
675692

676-
return mapExtToMediaMimes[ext.toLowerCase()];
693+
return mapExtToMediaMimes[ext.toLowerCase()] || 'text/plain';
677694
}
678695

679696
/**
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Coder Technologies. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Emitter } from 'vs/base/common/event';
7+
import { ConsoleLogger } from 'vs/platform/log/common/log';
8+
import { ServerProtocol } from 'vs/server/protocol';
9+
10+
export abstract class AbstractConnection {
11+
private readonly _onClose = new Emitter<void>();
12+
/**
13+
* Fire when the connection is closed (not just disconnected). This should
14+
* only happen when the connection is offline and old or has an error.
15+
*/
16+
public readonly onClose = this._onClose.event;
17+
private disposed = false;
18+
private _offline: number | undefined;
19+
20+
protected readonly logger: ConsoleLogger;
21+
22+
public constructor(
23+
protected readonly protocol: ServerProtocol,
24+
public readonly name: string,
25+
) {
26+
this.logger = new ConsoleLogger();
27+
28+
this.logger.debug('Connecting...');
29+
this.onClose(() => this.logger.debug('Closed'));
30+
}
31+
32+
public get offline(): number | undefined {
33+
return this._offline;
34+
}
35+
36+
public reconnect(protocol: ServerProtocol): void {
37+
// this.logger.debug(`${this.protocol.options.reconnectionToken} Reconnecting...`);
38+
this._offline = undefined;
39+
this.doReconnect(protocol);
40+
}
41+
42+
public dispose(reason?: string): void {
43+
// this.logger.debug(`${this.protocol.options.reconnectionToken} Disposing...`, reason);
44+
if (!this.disposed) {
45+
this.disposed = true;
46+
this.doDispose();
47+
this._onClose.fire();
48+
}
49+
}
50+
51+
protected setOffline(): void {
52+
this.logger.debug('Disconnected');
53+
if (!this._offline) {
54+
this._offline = Date.now();
55+
}
56+
}
57+
58+
/**
59+
* Set up the connection on a new socket.
60+
*/
61+
protected abstract doReconnect(protcol: ServerProtocol): void;
62+
63+
/**
64+
* Dispose/destroy everything permanently.
65+
*/
66+
protected abstract doDispose(): void;
67+
}

src/vs/server/connection.ts renamed to src/vs/server/connection/extensionHostConnection.ts

Lines changed: 7 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,17 @@
1-
/*---------------------------------------------------------------------------------------------
2-
* Copyright (c) Coder Technologies. All rights reserved.
3-
* Licensed under the MIT License. See License.txt in the project root for license information.
4-
*--------------------------------------------------------------------------------------------*/
1+
// /*---------------------------------------------------------------------------------------------
2+
// * Copyright (c) Coder Technologies. All rights reserved.
3+
// * Licensed under the MIT License. See License.txt in the project root for license information.
4+
// *--------------------------------------------------------------------------------------------*/
55

66
import * as cp from 'child_process';
7-
import { VSBuffer } from 'vs/base/common/buffer';
8-
import { Emitter } from 'vs/base/common/event';
97
import { FileAccess } from 'vs/base/common/network';
108
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
11-
import { ConsoleLogger } from 'vs/platform/log/common/log';
9+
import { AbstractConnection } from 'vs/server/connection/abstractConnection';
1210
import { IRemoteExtensionHostStartParams } from 'vs/platform/remote/common/remoteAgentConnection';
1311
import { getNlsConfiguration } from 'vs/server/nls';
1412
import { ServerProtocol } from 'vs/server/protocol';
1513
import { IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
16-
17-
export abstract class Connection {
18-
private readonly _onClose = new Emitter<void>();
19-
/**
20-
* Fire when the connection is closed (not just disconnected). This should
21-
* only happen when the connection is offline and old or has an error.
22-
*/
23-
public readonly onClose = this._onClose.event;
24-
private disposed = false;
25-
private _offline: number | undefined;
26-
27-
protected readonly logger: ConsoleLogger;
28-
29-
public constructor(
30-
protected readonly protocol: ServerProtocol,
31-
public readonly name: string,
32-
) {
33-
this.logger = new ConsoleLogger();
34-
35-
this.logger.debug('Connecting...');
36-
this.onClose(() => this.logger.debug('Closed'));
37-
}
38-
39-
public get offline(): number | undefined {
40-
return this._offline;
41-
}
42-
43-
public reconnect(protocol: ServerProtocol): void {
44-
// this.logger.debug(`${this.protocol.options.reconnectionToken} Reconnecting...`);
45-
this._offline = undefined;
46-
this.doReconnect(protocol);
47-
}
48-
49-
public dispose(reason?: string): void {
50-
// this.logger.debug(`${this.protocol.options.reconnectionToken} Disposing...`, reason);
51-
if (!this.disposed) {
52-
this.disposed = true;
53-
this.doDispose();
54-
this._onClose.fire();
55-
}
56-
}
57-
58-
protected setOffline(): void {
59-
this.logger.debug('Disconnected');
60-
if (!this._offline) {
61-
this._offline = Date.now();
62-
}
63-
}
64-
65-
/**
66-
* Set up the connection on a new socket.
67-
*/
68-
protected abstract doReconnect(protcol: ServerProtocol): void;
69-
70-
/**
71-
* Dispose/destroy everything permanently.
72-
*/
73-
protected abstract doDispose(): void;
74-
}
75-
76-
/**
77-
* Used for all the IPC channels.
78-
*/
79-
export class ManagementConnection extends Connection {
80-
public constructor(protocol: ServerProtocol) {
81-
super(protocol, 'management');
82-
protocol.onDidDispose(() => this.dispose()); // Explicit close.
83-
protocol.onSocketClose(() => this.setOffline()); // Might reconnect.
84-
protocol.sendMessage({ type: 'ok' });
85-
}
86-
87-
protected doDispose(): void {
88-
this.protocol.destroy();
89-
}
90-
91-
protected doReconnect(protocol: ServerProtocol): void {
92-
protocol.sendMessage({ type: 'ok' });
93-
this.protocol.beginAcceptReconnection(protocol.getSocket(), protocol.readEntireBuffer());
94-
this.protocol.endAcceptReconnection();
95-
protocol.dispose();
96-
}
97-
}
14+
import { VSBuffer } from 'vs/base/common/buffer';
9815

9916
interface DisconnectedMessage {
10017
type: 'VSCODE_EXTHOST_DISCONNECTED';
@@ -109,7 +26,7 @@ interface ConsoleMessage {
10926

11027
type ExtHostMessage = DisconnectedMessage | ConsoleMessage | IExtHostReadyMessage;
11128

112-
export class ExtensionHostConnection extends Connection {
29+
export class ExtensionHostConnection extends AbstractConnection {
11330
private process?: cp.ChildProcess;
11431

11532
public constructor(

src/vs/server/connection/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './abstractConnection';
2+
export * from './managementConnection';
3+
export * from './extensionHostConnection';
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// /*---------------------------------------------------------------------------------------------
2+
// * Copyright (c) Coder Technologies. All rights reserved.
3+
// * Licensed under the MIT License. See License.txt in the project root for license information.
4+
// *--------------------------------------------------------------------------------------------*/
5+
6+
import { AbstractConnection } from 'vs/server/connection/abstractConnection';
7+
import { ServerProtocol } from 'vs/server/protocol';
8+
9+
/**
10+
* Used for all the IPC channels.
11+
*/
12+
export class ManagementConnection extends AbstractConnection {
13+
public constructor(protocol: ServerProtocol) {
14+
super(protocol, 'management');
15+
protocol.onDidDispose(() => this.dispose()); // Explicit close.
16+
protocol.onSocketClose(() => this.setOffline()); // Might reconnect.
17+
protocol.sendMessage({ type: 'ok' });
18+
}
19+
20+
protected doDispose(): void {
21+
this.protocol.destroy();
22+
}
23+
24+
protected doReconnect(protocol: ServerProtocol): void {
25+
protocol.sendMessage({ type: 'ok' });
26+
this.protocol.beginAcceptReconnection(protocol.getSocket(), protocol.readEntireBuffer());
27+
this.protocol.endAcceptReconnection();
28+
protocol.dispose();
29+
}
30+
}

src/vs/server/entry.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Server as WebSocketServer } from 'ws';
1111
import { CodeServer, VscodeServerArgs as ServerArgs } from 'vs/server/server';
1212
import { createServer, IncomingMessage } from 'http';
1313
import * as net from 'net';
14+
1415
// eslint-disable-next-line code-import-patterns
1516
import { requestHandler as defaultRequestHandler } from '../../../resources/web/code-web';
1617

@@ -29,7 +30,7 @@ export async function main(args: ServerArgs) {
2930
const serverUrl = new URL(`http://${args.server}`);
3031

3132
const codeServer = new CodeServer();
32-
const workbenchConstructionOptions = await codeServer.startup(serverUrl);
33+
const workbenchConstructionOptions = await codeServer.createWorkbenchConstructionOptions(serverUrl);
3334

3435
const httpServer = createServer((req, res) => defaultRequestHandler(req, res, workbenchConstructionOptions));
3536

src/vs/server/protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class ServerProtocol extends PersistentProtocol {
7171
const handler = this.onControlMessage((rawMessage) => {
7272
try {
7373
const raw = rawMessage.toString();
74-
this.logger.info('Got message', raw);
74+
this.logger.debug('Got message', raw);
7575
const message: HandshakeMessage = JSON.parse(raw);
7676

7777
switch (message.type) {

src/vs/server/server.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'
4949
import { combinedAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
5050
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
5151
import { ExtensionEnvironmentChannel, FileProviderChannel, TerminalProviderChannel } from 'vs/server/channel';
52-
import { Connection, ExtensionHostConnection, ManagementConnection } from 'vs/server/connection';
52+
import { AbstractConnection as Connection, ExtensionHostConnection, ManagementConnection } from 'vs/server/connection/index';
5353
import { TelemetryClient } from 'vs/server/insights';
5454
import { getLocaleFromConfig, getNlsConfiguration } from 'vs/server/nls';
5555
import { ServerProtocol, ServerProtocolOptions } from 'vs/server/protocol';
@@ -66,16 +66,18 @@ import { ArgumentParser } from 'vs/platform/environment/argumentParser';
6666
import { toWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
6767
import * as WebSocket from 'ws';
6868
import { ServerSocket } from 'vs/platform/remote/node/serverWebSocket';
69+
// import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
70+
// import { ExtensionService } from 'vs/workbench/services/extensions/browser/extensionService';
6971

7072
const commit = productConfiguration.commit || 'development';
71-
const logger = new ConsoleMainLogger();
7273

7374
export type VscodeServerArgs = NativeParsedArgs & Complete<Pick<NativeParsedArgs, 'server'>>;
7475

7576
/**
7677
* Handles client connections to a editor instance via IPC.
7778
*/
7879
export class CodeServer extends ArgumentParser {
80+
private readonly logger = new ConsoleMainLogger();
7981
public readonly _onDidClientConnect = new Emitter<ClientConnectionEvent>();
8082
public readonly onDidClientConnect = this._onDidClientConnect.event;
8183
private readonly ipc = new IPCServer<RemoteAgentConnectionContext>(this.onDidClientConnect);
@@ -99,7 +101,7 @@ export class CodeServer extends ArgumentParser {
99101
})));
100102
}
101103

102-
public async startup(serverUrl: URL): Promise<IServerWorkbenchConstructionOptions> {
104+
public async createWorkbenchConstructionOptions(serverUrl: URL): Promise<IServerWorkbenchConstructionOptions> {
103105
const parsedArgs = this.resolveArgs();
104106

105107
if (!parsedArgs.server) {
@@ -159,7 +161,7 @@ export class CodeServer extends ArgumentParser {
159161
}
160162

161163
public async handleWebSocket(ws: WebSocket, query: URLSearchParams, permessageDeflate = false): Promise<true> {
162-
logger.trace('Socket connected');
164+
this.logger.trace('Socket connected');
163165

164166
const protocolOptions: ServerProtocolOptions = {
165167
reconnectionToken: <string>query.get('reconnectionToken'),
@@ -171,18 +173,15 @@ export class CodeServer extends ArgumentParser {
171173
const protocol = new ServerProtocol(new ServerSocket(ws));
172174

173175
try {
174-
const connection = await protocol.handshake();
175-
await this.connect(connection, protocol, protocolOptions);
176+
const connectionTypeRequest = await protocol.handshake();
177+
await this.connect(connectionTypeRequest, protocol, protocolOptions);
176178
} catch (error) {
177179
protocol.destroy(error.message);
178180
}
179181
return true;
180182
}
181183

182184
private async connect(message: ConnectionTypeRequest, protocol: ServerProtocol, { reconnectionToken, reconnection }: ServerProtocolOptions): Promise<void> {
183-
if (productConfiguration.commit && message.commit !== productConfiguration.commit) {
184-
logger.warn(`Version mismatch (${message.commit} instead of ${productConfiguration.commit})`);
185-
}
186185

187186
switch (message.desiredConnectionType) {
188187
case ConnectionType.ExtensionHost:
@@ -220,6 +219,7 @@ export class CodeServer extends ArgumentParser {
220219
onDidClientDisconnect: connection.onClose,
221220
});
222221
} else {
222+
this.logger.trace('New connection to extension host');
223223
// The extension host connection is used by spawning an extension host
224224
// and passing the socket into it.
225225
connection = new ExtensionHostConnection(
@@ -235,7 +235,7 @@ export class CodeServer extends ArgumentParser {
235235
connection.onClose(() => connections.delete(reconnectionToken));
236236

237237
this.disposeOldOfflineConnections(connections);
238-
logger.debug(`${connections.size} active ${connection.name} connection(s)`);
238+
this.logger.debug(`${connections.size} active ${connection.name} connection(s)`);
239239
break;
240240
case ConnectionType.Tunnel:
241241
return protocol.tunnel();
@@ -267,7 +267,7 @@ export class CodeServer extends ArgumentParser {
267267
...environmentService.extraExtensionPaths,
268268
...environmentService.extraBuiltinExtensionPaths,
269269
].map((p) => fs.mkdir(p, { recursive: true }).catch((error) => {
270-
logger.warn(error.message || error);
270+
this.logger.warn(error.message || error);
271271
})));
272272

273273

0 commit comments

Comments
 (0)