mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 21:55:38 +00:00
Improve env variable handling around extension host connection type (#152466)
This commit is contained in:
parent
0f05ed4758
commit
47652af0b6
|
@ -22,6 +22,7 @@ import { logRemoteEntry } from 'vs/workbench/services/extensions/common/remoteCo
|
|||
import { removeDangerousEnvVariables } from 'vs/base/common/processes';
|
||||
import { IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService';
|
||||
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IPCExtHostConnection, writeExtHostConnection, SocketExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv';
|
||||
|
||||
export async function buildUserEnvironment(startParamsEnv: { [key: string]: string | null } = {}, withUserShellEnvironment: boolean, language: string, isDebug: boolean, environmentService: IServerEnvironmentService, logService: ILogService): Promise<IProcessEnvironment> {
|
||||
const nlsConfig = await getNLSConfiguration(language, environmentService.userDataPath);
|
||||
|
@ -244,11 +245,11 @@ export class ExtensionHostConnection {
|
|||
let extHostNamedPipeServer: net.Server | null;
|
||||
|
||||
if (this._canSendSocket) {
|
||||
env['VSCODE_EXTHOST_WILL_SEND_SOCKET'] = 'true';
|
||||
writeExtHostConnection(new SocketExtHostConnection(), env);
|
||||
extHostNamedPipeServer = null;
|
||||
} else {
|
||||
const { namedPipeServer, pipeName } = await this._listenOnPipe();
|
||||
env['VSCODE_IPC_HOOK_EXTHOST'] = pipeName;
|
||||
writeExtHostConnection(new IPCExtHostConnection(pipeName), env);
|
||||
extHostNamedPipeServer = namedPipeServer;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import { ProcessTimeRunOnceScheduler } from 'vs/base/common/async';
|
|||
import { boolean } from 'vs/editor/common/config/editorOptions';
|
||||
import { createURITransformer } from 'vs/workbench/api/node/uriTransformer';
|
||||
import { MessagePortMain } from 'electron';
|
||||
import { ExtHostConnectionType, readExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv';
|
||||
|
||||
import 'vs/workbench/api/common/extHost.common.services';
|
||||
import 'vs/workbench/api/node/extHost.node.services';
|
||||
|
@ -110,7 +111,9 @@ let onTerminate = function (reason: string) {
|
|||
};
|
||||
|
||||
function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
||||
if (process.env.VSCODE_WILL_SEND_MESSAGE_PORT) {
|
||||
const extHostConnection = readExtHostConnection(process.env);
|
||||
|
||||
if (extHostConnection.type === ExtHostConnectionType.MessagePort) {
|
||||
|
||||
return new Promise<IMessagePassingProtocol>((resolve, reject) => {
|
||||
|
||||
|
@ -139,7 +142,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
|||
|
||||
});
|
||||
|
||||
} else if (process.env.VSCODE_EXTHOST_WILL_SEND_SOCKET) {
|
||||
} else if (extHostConnection.type === ExtHostConnectionType.Socket) {
|
||||
|
||||
return new Promise<PersistentProtocol>((resolve, reject) => {
|
||||
|
||||
|
@ -208,7 +211,7 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
|
|||
|
||||
} else {
|
||||
|
||||
const pipeName = process.env.VSCODE_IPC_HOOK_EXTHOST!;
|
||||
const pipeName = extHostConnection.pipeName;
|
||||
|
||||
return new Promise<PersistentProtocol>((resolve, reject) => {
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
|
||||
export const enum ExtHostConnectionType {
|
||||
IPC = 1,
|
||||
Socket = 2,
|
||||
MessagePort = 3
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension host will connect via named pipe / domain socket to its renderer.
|
||||
*/
|
||||
export class IPCExtHostConnection {
|
||||
public static ENV_KEY = 'VSCODE_EXTHOST_IPC_HOOK';
|
||||
|
||||
public readonly type = ExtHostConnectionType.IPC;
|
||||
|
||||
constructor(
|
||||
public readonly pipeName: string
|
||||
) { }
|
||||
|
||||
public serialize(env: IProcessEnvironment): void {
|
||||
env[IPCExtHostConnection.ENV_KEY] = this.pipeName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension host will receive via nodejs IPC the socket to its renderer.
|
||||
*/
|
||||
export class SocketExtHostConnection {
|
||||
public static ENV_KEY = 'VSCODE_EXTHOST_WILL_SEND_SOCKET';
|
||||
|
||||
public readonly type = ExtHostConnectionType.Socket;
|
||||
|
||||
public serialize(env: IProcessEnvironment): void {
|
||||
env[SocketExtHostConnection.ENV_KEY] = '1';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The extension host will receive via nodejs IPC the MessagePort to its renderer.
|
||||
*/
|
||||
export class MessagePortExtHostConnection {
|
||||
public static ENV_KEY = 'VSCODE_WILL_SEND_MESSAGE_PORT';
|
||||
|
||||
public readonly type = ExtHostConnectionType.MessagePort;
|
||||
|
||||
public serialize(env: IProcessEnvironment): void {
|
||||
env[MessagePortExtHostConnection.ENV_KEY] = '1';
|
||||
}
|
||||
}
|
||||
|
||||
export type ExtHostConnection = IPCExtHostConnection | SocketExtHostConnection | MessagePortExtHostConnection;
|
||||
|
||||
function clean(env: IProcessEnvironment): void {
|
||||
delete env[IPCExtHostConnection.ENV_KEY];
|
||||
delete env[SocketExtHostConnection.ENV_KEY];
|
||||
delete env[MessagePortExtHostConnection.ENV_KEY];
|
||||
}
|
||||
|
||||
/**
|
||||
* Write `connection` into `env` and clean up `env`.
|
||||
*/
|
||||
export function writeExtHostConnection(connection: ExtHostConnection, env: IProcessEnvironment): void {
|
||||
// Avoid having two different keys that might introduce amiguity or problems.
|
||||
clean(env);
|
||||
connection.serialize(env);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read `connection` from `env` and clean up `env`.
|
||||
*/
|
||||
export function readExtHostConnection(env: IProcessEnvironment): ExtHostConnection {
|
||||
if (env[IPCExtHostConnection.ENV_KEY]) {
|
||||
return cleanAndReturn(env, new IPCExtHostConnection(env[IPCExtHostConnection.ENV_KEY]!));
|
||||
}
|
||||
if (env[SocketExtHostConnection.ENV_KEY]) {
|
||||
return cleanAndReturn(env, new SocketExtHostConnection());
|
||||
}
|
||||
if (env[MessagePortExtHostConnection.ENV_KEY]) {
|
||||
return cleanAndReturn(env, new MessagePortExtHostConnection());
|
||||
}
|
||||
throw new Error(`No connection information defined in environment!`);
|
||||
}
|
||||
|
||||
function cleanAndReturn(env: IProcessEnvironment, result: ExtHostConnection): ExtHostConnection {
|
||||
clean(env);
|
||||
return result;
|
||||
}
|
|
@ -12,6 +12,7 @@ import { PersistentProtocol } from 'vs/base/parts/ipc/common/ipc.net';
|
|||
import { createRandomIPCHandle, NodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { IExtensionHostProcessOptions } from 'vs/platform/extensions/common/extensionHostStarter';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IPCExtHostConnection, writeExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv';
|
||||
import { createMessageOfType, MessageType } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
|
||||
import { ExtensionHostProcess, ExtHostMessagePortCommunication, IExtHostCommunication, SandboxLocalProcessExtensionHost } from 'vs/workbench/services/extensions/electron-sandbox/localProcessExtensionHost';
|
||||
|
||||
|
@ -64,7 +65,7 @@ class ExtHostNamedPipeCommunication extends Disposable implements IExtHostCommun
|
|||
establishProtocol(prepared: INamedPipePreparedData, extensionHostProcess: ExtensionHostProcess, opts: IExtensionHostProcessOptions): Promise<IMessagePassingProtocol> {
|
||||
const { namedPipeServer, pipeName } = prepared;
|
||||
|
||||
opts.env['VSCODE_IPC_HOOK_EXTHOST'] = pipeName;
|
||||
writeExtHostConnection(new IPCExtHostConnection(pipeName), opts.env);
|
||||
|
||||
return new Promise<PersistentProtocol>((resolve, reject) => {
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/use
|
|||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { acquirePort } from 'vs/base/parts/ipc/electron-sandbox/ipc.mp';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { MessagePortExtHostConnection, writeExtHostConnection } from 'vs/workbench/services/extensions/common/extensionHostEnv';
|
||||
|
||||
export interface ILocalProcessExtensionHostInitData {
|
||||
readonly autoStart: boolean;
|
||||
|
@ -620,7 +621,7 @@ export class ExtHostMessagePortCommunication extends Disposable implements IExtH
|
|||
|
||||
establishProtocol(prepared: void, extensionHostProcess: ExtensionHostProcess, opts: IExtensionHostProcessOptions): Promise<IMessagePassingProtocol> {
|
||||
|
||||
opts.env['VSCODE_WILL_SEND_MESSAGE_PORT'] = 'true';
|
||||
writeExtHostConnection(new MessagePortExtHostConnection(), opts.env);
|
||||
|
||||
// Get ready to acquire the message port from the shared process worker
|
||||
const portPromise = acquirePort(undefined /* we trigger the request via service call! */, opts.responseChannel, opts.responseNonce);
|
||||
|
|
Loading…
Reference in a new issue