src/vs/platform/request/node/requestService.ts

296 LOC · 212 covered · 84 uncovered · 45 ranges · 42 concepts · 10 introducers · 31 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/node/pfs.ts · 866 LOCnode/pfs.tssrc/vs/platform/agentHost/node/agentSdkDownloader.ts · 626 LOCnode/agentSdkDownloader.…src/vs/platform/files/common/fileService.ts · 1491 LOCcommon/fileService.tssrc/vs/platform/files/node/diskFileSystemProvider.ts · 898 LOCnode/diskFileSystemProvi…src/vs/platform/request/node/proxy.ts · 54 LOCnode/proxy.tssrc/vs/platform/shell/node/shellEnv.ts · 222 LOCnode/shellEnv.tsagentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…diskFileSystemProvider.ts ×11 · 79 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×3 · 28 introduced LOCagentSdkDownloader.ts ×3diskFileSystemProvider.ts ×20 · 260 introduced LOCdiskFileSystemProvider.t…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 20 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 6 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 5 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 8 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×5 · 10 introduced LOCagentSdkDownloader.ts ×5agentSdkDownloader.ts ×1 · 3 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×3 · 5 introduced LOCagentSdkDownloader.ts ×3agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · 0 introduced LOCagentSdkDownloader.test|…agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 3 introduced LOCagentSdkDownloader.ts ×2agentSdkDownloader.ts ×1 · 8 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×1 · 2 introduced LOCagentSdkDownloader.ts ×1agentSdkDownloader.ts ×2 · 5 introduced LOCagentSdkDownloader.ts ×2agentHostRequestService.ts ×2 · 7 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×4 · 10 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×6 · 32 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×2 · 4 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×1 · 2 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×1 · 2 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×5 · 8 introduced LOCagentHostRequestService.…agentHostRequestService.ts ×12 · 46 introduced LOCagentHostRequestService.…requestService.ts ×5 · 18 introduced LOCrequestService.ts ×5networkDiagnosticsService.ts ×11 · 83 introduced LOCnetworkDiagnosticsServic…agentHostClientProxyChannel.ts ×4 · 26 introduced LOCagentHostClientProxyChan…agentHostRequestService.ts ×11 · 179 introduced LOCagentHostRequestService.…requestService.ts ×1 · 4 introduced LOCrequestService.ts ×1requestService.ts ×1 · 1 introduced LOCrequestService.ts ×1requestService.ts ×3 · 14 introduced LOCrequestService.ts ×3requestService.ts ×2 · 7 introduced LOCrequestService.ts ×2requestService.ts ×1 · 2 introduced LOCrequestService.ts ×1requestService.ts ×3 · 5 introduced LOCrequestService.ts ×3requestService.ts ×11 · 51 introduced LOCrequestService.ts ×11requestService.ts ×13 · 96 introduced LOCrequestService.ts ×13agentHostRequestService.test|title=AgentHostRequestService does not retry non-idempotent requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService does not retry non-idempotent requests|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService forwards cancellation to resolver fetch|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService forwards cancellation to resolver fetch|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService forwards proxy and authorization lookups through the client channel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService forwards proxy and authorization lookups through the client channel|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService retries idempotent requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService retries idempotent requests on transient errors|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=AgentHostRequestService uses resolver fetch and streams the response|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=AgentHostRequestService uses resolver fetch and streams the response|occurrence=1agentHostRequestService.…agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentHostRequestService.test|title=NetworkDiagnosticsService includes nested proxy response errors|occurrence=1agentHostRequestService.…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: false when no env override and no product config|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when env override set|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader isAvailable: true when product config populated and host has a target|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache dir includes sdkTarget so Universal launches stay separate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache hit returns immediately without re-downloading|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cache miss → downloads, extracts, writes sentinel|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: cancel before download completes cleans up scratch dir|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: concurrent calls in same process share one download|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: dev override returns the path unchanged|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: missing product config and no env override throws actionable error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: rename-loser path returns existing cache when winner already published|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: reports monotonic download progress ending at totalBytes|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: substitutes {sdkTarget} into urlTemplate|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=AgentSdkDownloader loadSdkRoot: urlTemplate with unknown placeholder throws config error|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget appends -musl on musl Linux iff the package has separate musl SKUs|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns <platform>-<arch> for supported (platform, arch)|occurrence=1agentSdkDownloader.test|…agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/agentSdkDownloader.test|title=resolveSdkTarget returns undefined for unsupported (platform, arch)|occurrence=1agentSdkDownloader.test|…requestService.test|title=Request Service Request cancellation during retry backoff|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service Request cancellation during retry backoff|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry DELETE requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry DELETE requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry PATCH requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry PATCH requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry POST requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry POST requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should NOT retry PUT requests|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should NOT retry PUT requests|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry GET requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry GET requests on transient errors|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry HEAD requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry HEAD requests on transient errors|occurrence=1requestService.test|titl…requestService.test|title=Request Service should retry OPTIONS requests on transient errors|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/request/test/node/requestService.test|title=Request Service should retry OPTIONS requests on transient errors|occurrence=1requestService.test|titl…Focused file · src/vs/platform/request/node/requestService.ts · 296 LOCnode/requestService.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- requestService.ts ×13
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import type * as http from 'http';
7 > import type * as https from 'https';
8 > import { parse as parseUrl } from 'url';
9 > import { Promises, timeout } from '../../../base/common/async.js';
10 > import { streamToBufferReadableStream } from '../../../base/common/buffer.js';
11 > import { CancellationToken } from '../../../base/common/cancellation.js';
12 > import { CancellationError, getErrorMessage } from '../../../base/common/errors.js';
13 > import * as streams from '../../../base/common/stream.js';
14 > import { isBoolean, isNumber } from '../../../base/common/types.js';
15 > import { IRequestContext, IRequestOptions } from '../../../base/parts/request/common/request.js';
16 > import { IConfigurationService } from '../../configuration/common/configuration.js';
17 > import { INativeEnvironmentService } from '../../environment/common/environment.js';
18 > import { getResolvedShellEnv } from '../../shell/node/shellEnv.js';
19 > import { ILogService } from '../../log/common/log.js';
20 > import { AbstractRequestService, AuthInfo, Credentials, IRequestService, systemCertificatesNodeDefault } from '../common/request.js';
21 > import { Agent, getProxyAgent } from './proxy.js';
22 > import { createGunzip } from 'zlib';
23 >
24 > const TRANSIENT_ERROR_CODES = new Set([
25 > 'EAI_AGAIN', // DNS lookup timed out
26 > 'ECONNREFUSED', // Connection refused by server
27 > 'EHOSTDOWN', // Host is down
28 > 'EHOSTUNREACH', // No route to host
29 > 'ENETDOWN', // Network is down
30 > 'ENETUNREACH', // Network is unreachable
31 > 'EPROTO' // Protocol error (TLS/SSL handshake failure)
32 > ]);
33 >
34 > const IDEMPOTENT_HTTP_METHODS_REGEX = /^(GET|HEAD|OPTIONS)$/i;
35 >
36 > function isTransientError(error: unknown): boolean { requestService.ts ×2
37 > if (error instanceof Error) {
38 > const code = (error as NodeJS.ErrnoException).code;
39 > return !!code && TRANSIENT_ERROR_CODES.has(code);
40 > }
41 return false;
42 }
44 > export interface IRawRequestFunction {
45 > (options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
46 > }
47 >
48 > export interface NodeRequestOptions extends IRequestOptions {
49 > agent?: Agent;
50 > strictSSL?: boolean;
51 > isChromiumNetwork?: boolean;
52 > getRawRequest?(options: IRequestOptions): IRawRequestFunction;
53 > }
54 >
55 > /**
56 > * This service exposes the `request` API, while using the global
57 > * or configured proxy settings.
58 > */
59 > export class RequestService extends AbstractRequestService implements IRequestService {
60 >
61 > declare readonly _serviceBrand: undefined;
62 >
63 > private proxyUrl?: string;
64 > private strictSSL: boolean | undefined;
65 > private authorization?: string;
66 > private shellEnvErrorLogged?: boolean;
67 >
68 > constructor(
69 > private readonly machine: 'local' | 'remote', requestService.ts ×5
70 > @IConfigurationService private readonly configurationService: IConfigurationService,
71 > @INativeEnvironmentService private readonly environmentService: INativeEnvironmentService,
72 > @ILogService logService: ILogService,
73 > ) {
74 > super(logService);
75 > this.configure();
76 > this._register(configurationService.onDidChangeConfiguration(e => {
77 if (e.affectsConfiguration('http')) {
78 this.configure();
79 }
81 > }
83 > private configure() {
84 > this.proxyUrl = this.getConfigValue<string>('http.proxy'); requestService.ts ×5
85 > this.strictSSL = !!this.getConfigValue<boolean>('http.proxyStrictSSL');
86 > this.authorization = this.getConfigValue<string>('http.proxyAuthorization');
87 > }
89 > async request(options: NodeRequestOptions, token: CancellationToken): Promise<IRequestContext> {
90 > const { proxyUrl, strictSSL } = this; diskFileSystemProvider.ts ×20
91 >
92 > let shellEnv: typeof process.env | undefined = undefined;
93 > try {
94 > shellEnv = await getResolvedShellEnv(this.configurationService, this.logService, this.environmentService.args, process.env);
95 > } catch (error) {
96 if (!this.shellEnvErrorLogged) {
97 this.shellEnvErrorLogged = true;
98 this.logService.error(`resolving shell environment failed`, getErrorMessage(error));
99 }
100 }
102 > const env = {
103 > ...process.env,
104 > ...shellEnv
105 > };
106 > const agent = options.agent ? options.agent : await getProxyAgent(options.url || '', env, { proxyUrl, strictSSL });
107 >
108 > options.agent = agent;
109 > options.strictSSL = strictSSL;
110 >
111 > if (this.authorization) {
112 options.headers = {
113 ...(options.headers || {}),
114 'Proxy-Authorization': this.authorization
115 };
116 }
118 > return this.logAndRequest(options, () => nodeRequest(options, token));
119 > }
121 > async resolveProxy(url: string): Promise<string | undefined> {
122 return undefined; // currently not implemented in node
123 }
125 > async lookupAuthorization(authInfo: AuthInfo): Promise<Credentials | undefined> {
126 return undefined; // currently not implemented in node
127 }
129 > async lookupKerberosAuthorization(urlStr: string): Promise<string | undefined> {
130 try {
131 const spnConfig = this.getConfigValue<string>('http.proxyKerberosServicePrincipal');
132 const response = await lookupKerberosAuthorization(urlStr, spnConfig, this.logService, 'RequestService#lookupKerberosAuthorization');
133 return 'Negotiate ' + response;
134 } catch (err) {
135 this.logService.debug('RequestService#lookupKerberosAuthorization Kerberos authentication failed', err);
136 return undefined;
137 }
138 }
140 > async loadCertificates(): Promise<string[]> {
141 const proxyAgent = await import('@vscode/proxy-agent');
142 return proxyAgent.loadSystemCertificates({
143 loadSystemCertificatesFromNode: () => this.getConfigValue<boolean>('http.systemCertificatesNode', systemCertificatesNodeDefault),
144 log: this.logService,
145 });
146 }
148 > private getConfigValue<T>(key: string, fallback?: T): T | undefined {
149 > if (this.machine === 'remote') { requestService.ts ×5
150 return this.configurationService.getValue<T>(key);
151 }
152 > const values = this.configurationService.inspect<T>(key); requestService.ts ×5
153 > return values.userLocalValue ?? values.defaultValue ?? fallback;
154 > }
156 >
157 export async function lookupKerberosAuthorization(urlStr: string, spnConfig: string | undefined, logService: ILogService, logPrefix: string) {
158 const importKerberos = await import('kerberos');
159 const kerberos = importKerberos.default || importKerberos;
160 const url = new URL(urlStr);
161 const spn = spnConfig
162 || (process.platform === 'win32' ? `HTTP/${url.hostname}` : `HTTP@${url.hostname}`);
163 logService.debug(`${logPrefix} Kerberos authentication lookup`, `proxyURL:${url}`, `spn:${spn}`);
164 const client = await kerberos.initializeClient(spn);
165 return client.step('');
166 }
168 > async function getNodeRequest(options: IRequestOptions): Promise<IRawRequestFunction> { diskFileSystemProvider.ts ×20
169 > const endpoint = parseUrl(options.url!);
170 > const module = endpoint.protocol === 'https:' ? await import('https') : await import('http');
171 >
172 > return module.request;
173 > }
175 > export async function nodeRequest(options: NodeRequestOptions, token: CancellationToken): Promise<IRequestContext> { requestService.ts ×11
176 > const maxRetries = 3;
177 > let lastError: Error | undefined;
178 > const isIdempotent = IDEMPOTENT_HTTP_METHODS_REGEX.test(options.type || 'GET');
179 >
180 > for (let attempt = 1; attempt <= maxRetries; attempt++) {
181 > try {
182 > return await nodeRequestAttempt(options, token);
183 > } catch (error) {
184 > lastError = error as Error; requestService.ts ×3
185 > if (error instanceof CancellationError) {
186 throw error;
187 }
189 > if (!isIdempotent || !isTransientError(error) || attempt === maxRetries) {
190 > throw error; requestService.ts ×1
191 > }
193 > await timeout(100 * attempt, token);
196
197 throw lastError;
198 }
200 > async function nodeRequestAttempt(options: NodeRequestOptions, token: CancellationToken): Promise<IRequestContext> { requestService.ts ×11
201 > return Promises.withAsyncBody<IRequestContext>(async (resolve, reject) => {
202 > const endpoint = parseUrl(options.url!);
203 > const rawRequest = options.getRawRequest
204 > ? options.getRawRequest(options) requestService.ts ×3
205 > : await getNodeRequest(options); diskFileSystemProvider.ts ×20
206 >
207 > const opts: https.RequestOptions & { cache?: 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached' } = {
208 > hostname: endpoint.hostname,
209 > port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80), requestService.ts ×11
210 > protocol: endpoint.protocol,
211 > path: endpoint.path,
212 > method: options.type || 'GET',
213 > headers: options.headers,
214 > agent: options.agent,
215 > rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true
216 > };
217 >
218 > if (options.user && options.password) {
219 opts.auth = options.user + ':' + options.password;
220 }
222 > if (options.disableCache) {
223 opts.cache = 'no-store';
224 }
226 > const req = rawRequest(opts, (res: http.IncomingMessage) => {
227 > const followRedirects: number = isNumber(options.followRedirects) ? options.followRedirects : 3; requestService.ts ×3
228 > if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
229 nodeRequest({
230 ...options,
231 url: res.headers['location'],
232 followRedirects: followRedirects - 1
233 }, token).then(resolve, reject);
234 > } else { requestService.ts ×3
235 > let stream: streams.ReadableStreamEvents<Uint8Array> = res;
236 >
237 > // Responses from Electron net module should be treated as response
238 > // from browser, which will apply gzip filter and decompress the response
239 > // using zlib before passing the result to us. Following step can be bypassed
240 > // in this case and proceed further.
241 > // Refs https://source.chromium.org/chromium/chromium/src/+/main:net/url_request/url_request_http_job.cc;l=1266-1318
242 > if (!options.isChromiumNetwork && res.headers['content-encoding'] === 'gzip') {
243 stream = res.pipe(createGunzip());
244 }
246 > resolve({ res, stream: streamToBufferReadableStream(stream) } satisfies IRequestContext);
247 > }
249 >
250 > req.on('error', reject);
251 >
252 > // Handle timeout
253 > if (options.timeout) {
254 // Chromium network requests do not support the `timeout` option
255 if (options.isChromiumNetwork) {
256 // Use Node's setTimeout for Chromium network requests
257 const timeout = setTimeout(() => {
258 req.abort();
259 reject(new Error(`Request timeout after ${options.timeout}ms`));
260 }, options.timeout);
261
262 // Clear timeout when request completes
263 req.on('response', () => clearTimeout(timeout));
264 req.on('error', () => clearTimeout(timeout));
265 req.on('abort', () => clearTimeout(timeout));
266 } else {
267 req.setTimeout(options.timeout);
268 }
269 }
271 > // Chromium will abort the request if forbidden headers are set.
272 > // Ref https://source.chromium.org/chromium/chromium/src/+/main:services/network/public/cpp/header_util.cc;l=14-48;
273 > // for additional context.
274 > if (options.isChromiumNetwork) {
275 req.removeHeader('Content-Length');
276 }
278 > if (options.data) {
279 if (typeof options.data === 'string') {
280 req.write(options.data);
281 }
282 }
284 > req.end();
285 >
286 > const cancellationListener = token.onCancellationRequested(() => {
287 > cancellationListener.dispose(); requestService.ts ×1
288 > req.abort();
289 >
290 > reject(new CancellationError());
292 >
293 > req.on('response', () => cancellationListener.dispose());
294 > req.on('error', () => cancellationListener.dispose());
295 > });
296 > }