Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -19,7 +19,6 @@ import { RPCProtocol } from 'vs/workbench/services/extensions/common/rpcProtocol
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { withNullAsUndefined } from 'vs/base/common/types';
import { ILogService } from 'vs/platform/log/common/log';
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
// we don't (yet) throw when extensions parse
// uris that have no scheme
@@ -53,9 +52,7 @@ export class ExtensionHostMain {
hostUtils: IHostUtils,
consolePatchFn: IConsolePatchFn,
logServiceFn: ILogServiceFn,
uriTransformer: IURITransformer | null,
schemeTransformer: ISchemeTransformer | null,
outputChannelName: string,
uriTransformer: IURITransformer | null
) {
this._isTerminating = false;
this._hostUtils = hostUtils;
@@ -86,8 +83,7 @@ export class ExtensionHostMain {
extHostConfiguraiton,
initData.environment,
this._extHostLogService,
schemeTransformer,
outputChannelName
uriTransformer
);
// error forwarding and stack trace scanning

View File

@@ -3,11 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { startExtensionHostProcess } from 'vs/workbench/services/extensions/node/extensionHostProcessSetup';
startExtensionHostProcess(
_ => null,
_ => null,
_ => nls.localize('extension host Log', "Extension Host")
).catch((err) => console.log(err));
startExtensionHostProcess().catch((err) => console.log(err));

View File

@@ -5,23 +5,33 @@
import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net';
import * as minimist from 'minimist';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Event } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { PersistentProtocol, ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
import { NodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
import { PersistentProtocol, ProtocolConstants, createBufferedEvent } from 'vs/base/parts/ipc/common/ipc.net';
import { NodeSocket, WebSocketNodeSocket } from 'vs/base/parts/ipc/node/ipc.net';
import product from 'vs/platform/product/node/product';
import { IInitData, MainThreadConsoleShape } from 'vs/workbench/api/common/extHost.protocol';
import { MessageType, createMessageOfType, isMessageOfType, IExtHostSocketMessage, IExtHostReadyMessage } from 'vs/workbench/services/extensions/common/extensionHostProtocol';
import { ExtensionHostMain, IExitFn, ILogServiceFn } from 'vs/workbench/services/extensions/node/extensionHostMain';
import { VSBuffer } from 'vs/base/common/buffer';
import { createBufferSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures';
import { IURITransformer } from 'vs/base/common/uriIpc';
import { IURITransformer, URITransformer, IRawURITransformer } from 'vs/base/common/uriIpc';
import { exists } from 'vs/base/node/pfs';
import { realpath } from 'vs/base/node/extpath';
import { IHostUtils } from 'vs/workbench/api/node/extHostExtensionService';
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
interface ParsedExtHostArgs {
uriTransformerPath?: string;
}
const args = minimist(process.argv.slice(2), {
string: [
'uriTransformerPath'
]
}) as ParsedExtHostArgs;
// With Electron 2.x and node.js 8.x the "natives" module
// can cause a native crash (see https://github.com/nodejs/node/issues/19891 and
@@ -72,7 +82,7 @@ function patchPatchedConsole(mainThreadConsole: MainThreadConsoleShape): void {
};
}
const createLogService: ILogServiceFn = initData => createBufferSpdLogService(ExtensionHostLogFileName, initData.logLevel, initData.logsLocation.fsPath);
const createLogService: ILogServiceFn = initData => new SpdLogService(ExtensionHostLogFileName, initData.logsLocation.fsPath, initData.logLevel);
interface IRendererConnection {
protocol: IMessagePassingProtocol;
@@ -101,27 +111,41 @@ function _createExtHostProtocol(): Promise<IMessagePassingProtocol> {
process.on('message', (msg: IExtHostSocketMessage, handle: net.Socket) => {
if (msg && msg.type === 'VSCODE_EXTHOST_IPC_SOCKET') {
const initialDataChunk = VSBuffer.wrap(Buffer.from(msg.initialDataChunk, 'base64'));
let socket: NodeSocket | WebSocketNodeSocket;
if (msg.skipWebSocketFrames) {
socket = new NodeSocket(handle);
} else {
socket = new WebSocketNodeSocket(new NodeSocket(handle));
}
if (protocol) {
// reconnection case
if (disconnectWaitTimer) {
clearTimeout(disconnectWaitTimer);
disconnectWaitTimer = null;
}
protocol.beginAcceptReconnection(new NodeSocket(handle), initialDataChunk);
protocol.beginAcceptReconnection(socket, initialDataChunk);
protocol.endAcceptReconnection();
} else {
clearTimeout(timer);
protocol = new PersistentProtocol(new NodeSocket(handle), initialDataChunk);
protocol = new PersistentProtocol(socket, initialDataChunk);
protocol.onClose(() => onTerminate());
resolve(protocol);
protocol.onSocketClose(() => {
// The socket has closed, let's give the renderer a certain amount of time to reconnect
disconnectWaitTimer = setTimeout(() => {
disconnectWaitTimer = null;
if (msg.skipWebSocketFrames) {
// Wait for rich client to reconnect
protocol.onSocketClose(() => {
// The socket has closed, let's give the renderer a certain amount of time to reconnect
disconnectWaitTimer = setTimeout(() => {
disconnectWaitTimer = null;
onTerminate();
}, ProtocolConstants.ReconnectionGraceTime);
});
} else {
// Do not wait for web companion to reconnect
protocol.onSocketClose(() => {
onTerminate();
}, ProtocolConstants.ReconnectionGraceTime);
});
});
}
}
}
});
@@ -155,16 +179,22 @@ async function createExtHostProtocol(): Promise<IMessagePassingProtocol> {
return new class implements IMessagePassingProtocol {
private _terminating = false;
private readonly _onMessage = new Emitter<VSBuffer>();
readonly onMessage: Event<VSBuffer> = createBufferedEvent(this._onMessage.event);
readonly onMessage: Event<any> = Event.filter(protocol.onMessage, msg => {
if (!isMessageOfType(msg, MessageType.Terminate)) {
return true;
}
this._terminating = true;
onTerminate();
return false;
});
private _terminating: boolean;
constructor() {
this._terminating = false;
protocol.onMessage((msg) => {
if (isMessageOfType(msg, MessageType.Terminate)) {
this._terminating = true;
onTerminate();
} else {
this._onMessage.fire(msg);
}
});
}
send(msg: any): void {
if (!this._terminating) {
@@ -272,11 +302,7 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRenderer
}
})();
export async function startExtensionHostProcess(
uriTransformerFn: (initData: IInitData) => IURITransformer | null,
schemeTransformerFn: (initData: IInitData) => ISchemeTransformer | null,
outputChannelNameFn: (initData: IInitData) => string,
): Promise<void> {
export async function startExtensionHostProcess(): Promise<void> {
const protocol = await createExtHostProtocol();
const renderer = await connectToRenderer(protocol);
@@ -291,6 +317,17 @@ export async function startExtensionHostProcess(
realpath(path: string) { return realpath(path); }
};
// Attempt to load uri transformer
let uriTransformer: IURITransformer | null = null;
if (initData.remote.authority && args.uriTransformerPath) {
try {
const rawURITransformerFactory = <any>require.__$__nodeRequire(args.uriTransformerPath);
const rawURITransformer = <IRawURITransformer>rawURITransformerFactory(initData.remote.authority);
uriTransformer = new URITransformer(rawURITransformer);
} catch (e) {
console.error(e);
}
}
const extensionHostMain = new ExtensionHostMain(
renderer.protocol,
@@ -298,9 +335,7 @@ export async function startExtensionHostProcess(
hostUtils,
patchPatchedConsole,
createLogService,
uriTransformerFn(initData),
schemeTransformerFn(initData),
outputChannelNameFn(initData)
uriTransformer
);
// rewrite onTerminate-function to be a proper shutdown

View File

@@ -12,40 +12,13 @@ import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
import * as types from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { getGalleryExtensionId, groupByExtension } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isValidExtensionVersion } from 'vs/platform/extensions/node/extensionValidator';
import { ExtensionIdentifier, ExtensionIdentifierWithVersion, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { getGalleryExtensionId, groupByExtension, ExtensionIdentifierWithVersion } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isValidExtensionVersion } from 'vs/platform/extensions/common/extensionValidator';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Translations, ILog } from 'vs/workbench/services/extensions/common/extensionPoints';
const MANIFEST_FILE = 'package.json';
export interface Translations {
[id: string]: string;
}
namespace Translations {
export function equals(a: Translations, b: Translations): boolean {
if (a === b) {
return true;
}
let aKeys = Object.keys(a);
let bKeys: Set<string> = new Set<string>();
for (let key of Object.keys(b)) {
bKeys.add(key);
}
if (aKeys.length !== bKeys.size) {
return false;
}
for (let key of aKeys) {
if (a[key] !== b[key]) {
return false;
}
bKeys.delete(key);
}
return bKeys.size === 0;
}
}
export interface NlsConfiguration {
readonly devMode: boolean;
readonly locale: string | undefined;
@@ -53,12 +26,6 @@ export interface NlsConfiguration {
readonly translations: Translations;
}
export interface ILog {
error(source: string, message: string): void;
warn(source: string, message: string): void;
info(source: string, message: string): void;
}
abstract class ExtensionManifestHandler {
protected readonly _ourVersion: string;

View File

@@ -1,53 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { getGalleryExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import product from 'vs/platform/product/node/product';
export function isUIExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean {
const uiContributions = ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').map(e => e.name);
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
const extensionKind = getExtensionKind(manifest, configurationService);
switch (extensionKind) {
case 'ui': return true;
case 'workspace': return false;
default: {
// Tagged as UI extension in product
if (isNonEmptyArray(product.uiExtensions) && product.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) {
return true;
}
// Not an UI extension if it has main
if (manifest.main) {
return false;
}
// Not an UI extension if it has dependencies or an extension pack
if (isNonEmptyArray(manifest.extensionDependencies) || isNonEmptyArray(manifest.extensionPack)) {
return false;
}
if (manifest.contributes) {
// Not an UI extension if it has no ui contributions
if (!uiContributions.length || Object.keys(manifest.contributes).some(contribution => uiContributions.indexOf(contribution) === -1)) {
return false;
}
}
return true;
}
}
}
function getExtensionKind(manifest: IExtensionManifest, configurationService: IConfigurationService): string | undefined {
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
const configuredExtensionKinds = configurationService.getValue<{ [key: string]: string }>('remote.extensionKind') || {};
for (const id of Object.keys(configuredExtensionKinds)) {
if (areSameExtensions({ id: extensionId }, { id })) {
return configuredExtensionKinds[id];
}
}
return manifest.extensionKind;
}

View File

@@ -8,7 +8,7 @@ import {
IExtensionManagementService, ILocalExtension, IGalleryExtension, InstallExtensionEvent, DidInstallExtensionEvent, IExtensionIdentifier, DidUninstallExtensionEvent, IReportedExtension, IGalleryMetadata,
IExtensionManagementServerService, IExtensionManagementServer, IExtensionGalleryService
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionType, IExtensionManifest, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { ExtensionType, isLanguagePackExtension } from 'vs/platform/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
import { Disposable } from 'vs/base/common/lifecycle';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -16,10 +16,9 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { getManifest } from 'vs/platform/extensionManagement/node/extensionManagementUtil';
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { localize } from 'vs/nls';
import { isUIExtension } from 'vs/workbench/services/extensions/node/extensionsUtil';
import { isUIExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { isNonEmptyArray } from 'vs/base/common/arrays';
import { values } from 'vs/base/common/map';
import { IProductService } from 'vs/platform/product/common/product';
export class MultiExtensionManagementService extends Disposable implements IExtensionManagementService {
@@ -35,7 +34,8 @@ export class MultiExtensionManagementService extends Disposable implements IExte
constructor(
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
@IConfigurationService private readonly configurationService: IConfigurationService
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService private readonly productService: IProductService,
) {
super();
this.servers = this.extensionManagementServerService.remoteExtensionManagementServer ? [this.extensionManagementServerService.localExtensionManagementServer, this.extensionManagementServerService.remoteExtensionManagementServer] : [this.extensionManagementServerService.localExtensionManagementServer];
@@ -85,7 +85,7 @@ export class MultiExtensionManagementService extends Disposable implements IExte
private async uninstallInServer(extension: ILocalExtension, server: IExtensionManagementServer, force?: boolean): Promise<void> {
if (server === this.extensionManagementServerService.localExtensionManagementServer) {
const installedExtensions = await this.extensionManagementServerService.remoteExtensionManagementServer!.extensionManagementService.getInstalled(ExtensionType.User);
const dependentNonUIExtensions = installedExtensions.filter(i => !isUIExtension(i.manifest, this.configurationService)
const dependentNonUIExtensions = installedExtensions.filter(i => !isUIExtension(i.manifest, this.productService, this.configurationService)
&& i.manifest.extensionDependencies && i.manifest.extensionDependencies.some(id => areSameExtensions({ id }, extension.identifier)));
if (dependentNonUIExtensions.length) {
return Promise.reject(new Error(this.getDependentsErrorMessage(extension, dependentNonUIExtensions)));
@@ -132,44 +132,38 @@ export class MultiExtensionManagementService extends Disposable implements IExte
return Promise.all(this.servers.map(({ extensionManagementService }) => extensionManagementService.unzip(zipLocation, type))).then(([extensionIdentifier]) => extensionIdentifier);
}
async install(vsix: URI): Promise<IExtensionIdentifier> {
async install(vsix: URI): Promise<ILocalExtension> {
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
const manifest = await getManifest(vsix.fsPath);
if (isLanguagePackExtension(manifest)) {
// Install on both servers
const [extensionIdentifier] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix)));
return extensionIdentifier;
const [local] = await Promise.all(this.servers.map(server => server.extensionManagementService.install(vsix)));
return local;
}
if (isUIExtension(manifest, this.configurationService)) {
if (isUIExtension(manifest, this.productService, this.configurationService)) {
// Install only on local server
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix);
}
// Install only on remote server
const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix);
// Install UI Dependencies on local server
await this.installUIDependenciesAndPackedExtensions(manifest);
return promise;
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.install(vsix);
}
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.install(vsix);
}
async installFromGallery(gallery: IGalleryExtension): Promise<void> {
async installFromGallery(gallery: IGalleryExtension): Promise<ILocalExtension> {
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None);
if (manifest) {
if (isLanguagePackExtension(manifest)) {
// Install on both servers
return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(() => undefined);
return Promise.all(this.servers.map(server => server.extensionManagementService.installFromGallery(gallery))).then(([local]) => local);
}
if (isUIExtension(manifest, this.configurationService)) {
if (isUIExtension(manifest, this.productService, this.configurationService)) {
// Install only on local server
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
}
// Install only on remote server
const promise = this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
// Install UI dependencies and packed extensions on local server
await this.installUIDependenciesAndPackedExtensions(manifest);
return promise;
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
} else {
return Promise.reject(localize('Manifest is not found', "Installing Extension {0} failed: Manifest is not found.", gallery.displayName || gallery.name));
}
@@ -177,13 +171,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(gallery);
}
private async installUIDependenciesAndPackedExtensions(manifest: IExtensionManifest): Promise<void> {
const uiExtensions = await this.getAllUIDependenciesAndPackedExtensions(manifest, CancellationToken.None);
const installed = await this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getInstalled();
const toInstall = uiExtensions.filter(e => installed.every(i => !areSameExtensions(i.identifier, e.identifier)));
await Promise.all(toInstall.map(d => this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.installFromGallery(d)));
}
getExtensionsReport(): Promise<IReportedExtension[]> {
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsReport();
}
@@ -191,49 +178,6 @@ export class MultiExtensionManagementService extends Disposable implements IExte
private getServer(extension: ILocalExtension): IExtensionManagementServer | null {
return this.extensionManagementServerService.getExtensionManagementServer(extension.location);
}
private async getAllUIDependenciesAndPackedExtensions(manifest: IExtensionManifest, token: CancellationToken): Promise<IGalleryExtension[]> {
const result = new Map<string, IGalleryExtension>();
const extensions = [...(manifest.extensionPack || []), ...(manifest.extensionDependencies || [])];
await this.getAllUIDependenciesAndPackedExtensionsRecursively(extensions, result, token);
return values(result);
}
private async getAllUIDependenciesAndPackedExtensionsRecursively(toGet: string[], result: Map<string, IGalleryExtension>, token: CancellationToken): Promise<void> {
if (toGet.length === 0) {
return Promise.resolve();
}
const extensions = (await this.extensionGalleryService.query({ names: toGet, pageSize: toGet.length }, token)).firstPage;
const manifests = await Promise.all(extensions.map(e => this.extensionGalleryService.getManifest(e, token)));
const uiExtensionsManifests: IExtensionManifest[] = [];
for (let idx = 0; idx < extensions.length; idx++) {
const extension = extensions[idx];
const manifest = manifests[idx];
if (manifest && isUIExtension(manifest, this.configurationService)) {
result.set(extension.identifier.id.toLowerCase(), extension);
uiExtensionsManifests.push(manifest);
}
}
toGet = [];
for (const uiExtensionManifest of uiExtensionsManifests) {
if (isNonEmptyArray(uiExtensionManifest.extensionDependencies)) {
for (const id of uiExtensionManifest.extensionDependencies) {
if (!result.has(id.toLowerCase())) {
toGet.push(id);
}
}
}
if (isNonEmptyArray(uiExtensionManifest.extensionPack)) {
for (const id of uiExtensionManifest.extensionPack) {
if (!result.has(id.toLowerCase())) {
toGet.push(id);
}
}
}
}
return this.getAllUIDependenciesAndPackedExtensionsRecursively(toGet, result, token);
}
}
registerSingleton(IExtensionManagementService, MultiExtensionManagementService);

View File

@@ -103,22 +103,33 @@ function setupProxyResolution(
let results: ConnectionResult[] = [];
function logEvent() {
timeout = undefined;
/* __GDPR__
"resolveProxy" : {
"count": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"duration": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"errorCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"cacheCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"cacheSize": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"cacheRolls": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"envCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"settingsCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"localhostCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"envNoProxyCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"results": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }
}
*/
mainThreadTelemetry.$publicLog('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, envNoProxyCount, results });
type ResolveProxyClassification = {
count: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
duration: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
errorCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
cacheCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
cacheSize: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
cacheRolls: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
envCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
settingsCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
localhostCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
envNoProxyCount: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
results: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
};
type ResolveProxyEvent = {
count: number;
duration: number;
errorCount: number;
cacheCount: number;
cacheSize: number;
cacheRolls: number;
envCount: number;
settingsCount: number;
localhostCount: number;
envNoProxyCount: number;
results: ConnectionResult[];
};
mainThreadTelemetry.$publicLog2<ResolveProxyEvent, ResolveProxyClassification>('resolveProxy', { count, duration, errorCount, cacheCount, cacheSize: cache.size, cacheRolls, envCount, settingsCount, localhostCount, envNoProxyCount, results });
count = duration = errorCount = cacheCount = envCount = settingsCount = localhostCount = envNoProxyCount = 0;
results = [];
}
@@ -403,7 +414,7 @@ function configureModuleLoading(extensionService: ExtHostExtensionService, looku
const modules = lookup[request];
const ext = extensionPaths.findSubstr(URI.file(parent.filename).fsPath);
if (ext && ext.enableProposedApi) {
return modules[(<any>ext).proxySupport] || modules.onRequest;
return (modules as any)[(<any>ext).proxySupport] || modules.onRequest;
}
return modules.default;
};
@@ -457,8 +468,8 @@ async function readCaCertificates() {
return undefined;
}
function readWindowsCaCertificates() {
const winCA = require.__$__nodeRequire<any>('vscode-windows-ca-certs');
async function readWindowsCaCertificates() {
const winCA = await import('vscode-windows-ca-certs');
let ders: any[] = [];
const store = winCA();
@@ -471,22 +482,26 @@ function readWindowsCaCertificates() {
store.done();
}
const seen = {};
const certs = ders.map(derToPem)
.filter(pem => !seen[pem] && (seen[pem] = true));
const certs = new Set(ders.map(derToPem));
return {
certs,
certs: Array.from(certs),
append: true
};
}
async function readMacCaCertificates() {
const stdout = (await promisify(cp.execFile)('/usr/bin/security', ['find-certificate', '-a', '-p'], { encoding: 'utf8', maxBuffer: 1024 * 1024 })).stdout;
const seen = {};
const certs = stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g)
.filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true));
const stdout = await new Promise<string>((resolve, reject) => {
const child = cp.spawn('/usr/bin/security', ['find-certificate', '-a', '-p']);
const stdout: string[] = [];
child.stdout.setEncoding('utf8');
child.stdout.on('data', str => stdout.push(str));
child.on('error', reject);
child.on('exit', code => code ? reject(code) : resolve(stdout.join('')));
});
const certs = new Set(stdout.split(/(?=-----BEGIN CERTIFICATE-----)/g)
.filter(pem => !!pem.length));
return {
certs,
certs: Array.from(certs),
append: true
};
}
@@ -500,11 +515,10 @@ async function readLinuxCaCertificates() {
for (const certPath of linuxCaCertificatePaths) {
try {
const content = await promisify(fs.readFile)(certPath, { encoding: 'utf8' });
const seen = {};
const certs = content.split(/(?=-----BEGIN CERTIFICATE-----)/g)
.filter(pem => !!pem.length && !seen[pem] && (seen[pem] = true));
const certs = new Set(content.split(/(?=-----BEGIN CERTIFICATE-----)/g)
.filter(pem => !!pem.length));
return {
certs,
certs: Array.from(certs),
append: false
};
} catch (err) {