agentHostRequestService.ts ×11

Frontier kind: Code frontier

unlabeled · c_4b112beac0be

6 tests · 12512 LOC · 68 files · introduces 0 tests · 179 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
23 ranges179 lines · 3 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1849 ranges12512 lines · 68 files · Browse complete extent
All tests (intent)
6 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

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 native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 179 introduced LOC across 23 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/networkDiagnosticsService.ts 72 introduced LOC · 7 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- networkDiagnosticsService.ts
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 { lookup } from 'dns';
7 > import { streamToBuffer } from '../../../base/common/buffer.js';
8 > import { CancellationToken } from '../../../base/common/cancellation.js';
9 > import { IConfigurationService } from '../../configuration/common/configuration.js';
10 > import { createDecorator } from '../../instantiation/common/instantiation.js';
11 > import { ILogService } from '../../log/common/log.js';
12 > import { IProductService } from '../../product/common/productService.js';
13 > import { IRequestService, NO_FETCH_TELEMETRY } from '../../request/common/request.js';
14 > import { IAgentHostDnsResult, IAgentHostNetworkDiagnosticsInfo, IAgentHostNetworkEndpoint, IAgentHostNetworkFetchResult } from '../common/agentService.js';
15 > import { IAgentHostProxyResolver } from './agentHostProxyResolver.js';
16 >
17 > export const INetworkDiagnosticsService = createDecorator<INetworkDiagnosticsService>('networkDiagnosticsService');
18 >
19 > /**
20 > * Owns agent-host network connectivity diagnostics: host-level network context
21 > * ({@link getInfo}) and the per-URL reachability probe ({@link fetch}). Split
22 > * out from {@link IAgentService} so the network stack dependencies
23 > * ({@link IRequestService}, {@link IAgentHostProxyResolver}) are injected here
24 > * rather than threaded through the session orchestrator.
25 > */
26 > export interface INetworkDiagnosticsService {
27 > readonly _serviceBrand: undefined;
28 >
29 > /** Host-level network context: version, OS/arch, account, proxy settings/env, and endpoints worth probing. */
30 > getInfo(endpoints: readonly IAgentHostNetworkEndpoint[], account?: string): Promise<IAgentHostNetworkDiagnosticsInfo>;
31 >
32 > /** Probe connectivity from the agent host process to a single `url`. */
33 > fetch(url: string): Promise<IAgentHostNetworkFetchResult>;
34 > }
35 >
36 > /** Per-probe timeout: DNS lookup and the reachability request each get this long. */
37 > const PROBE_TIMEOUT_MS = 10_000;
38 >
39 > /** Cap on the response body returned to callers (for expected-content checks), to bound the IPC payload. */
40 > const MAX_BODY_CHARS = 64 * 1024;
41 >
42 > /**
43 > * Proxy-related environment variables surfaced in the diagnostics report so a
44 > * mismatch between the OS/config proxy and an explicit env override is visible.
45 > */
46 > const PROXY_ENV_KEYS = ['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy', 'ALL_PROXY', 'all_proxy', 'NO_PROXY', 'no_proxy'] as const;
47 >
48 > /** VS Code `http.*` proxy settings surfaced alongside the env vars. */
49 > const PROXY_CONFIG_KEYS = ['http.proxy', 'http.proxyStrictSSL', 'http.proxySupport', 'http.noProxy'] as const;
50 >
51 > export class NetworkDiagnosticsService implements INetworkDiagnosticsService {
52 >
53 > declare readonly _serviceBrand: undefined;
54 >
55 > constructor(
56 @IRequestService private readonly _requestService: IRequestService,
57 @IAgentHostProxyResolver private readonly _proxyResolver: IAgentHostProxyResolver,
60 @ILogService private readonly _logService: ILogService,
61 ) { }
63 > async getInfo(endpoints: readonly IAgentHostNetworkEndpoint[], account?: string): Promise<IAgentHostNetworkDiagnosticsInfo> {
64 const proxyEnv: Record<string, string> = {};
65 for (const key of PROXY_ENV_KEYS) {
89 };
90 }
92 > /**
93 > * Probe connectivity from the agent host process to a single `url`. Resolves
94 > * the proxy (for reporting), performs an IPv4 DNS lookup, and then a
95 > * reachability request through {@link IRequestService} — so the probe
96 > * traverses the same proxy / TLS / certificate stack the rest of VS Code
97 > * uses. Each step is individually timed and never throws; failures are
98 > * captured on the result.
99 > */
100 > async fetch(url: string): Promise<IAgentHostNetworkFetchResult> {
101 const target = new URL(url);
102 const host = target.hostname;
147 }
148 }
150 >
151 function dnsLookup(host: string, family: 4 | 6): Promise<string> {
152 return new Promise((resolve, reject) => {
154 });
155 }
157 async function resolveDns(host: string, family: 4 | 6): Promise<IAgentHostDnsResult> {
158 const start = Date.now();
164 }
165 }
167 function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {
168 return new Promise<T>((resolve, reject) => {
src/vs/platform/agentHost/common/agentHostClientProxyChannel.ts 54 introduced LOC · 5 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentHostClientProxyChannel.ts
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 { Event } from '../../../base/common/event.js';
7 > import { IChannel, IServerChannel } from '../../../base/parts/ipc/common/ipc.js';
8 > import { AuthInfo, Credentials, IRequestService } from '../../request/common/request.js';
9 >
10 > /**
11 > * IPC channel name used for in-process agent-host → renderer reverse proxy
12 > * resolution RPCs. The renderer registers a server channel under this name on
13 > * its `MessagePortClient`; the agent host reaches it via
14 > * `server.getChannel(name, c => c.ctx === clientId)` on its
15 > * `UtilityProcessServer`.
16 > *
17 > * Mirrors {@link AGENT_HOST_CLIENT_BYOK_LM_CHANNEL} for the reverse BYOK bridge.
18 > */
19 > export const AGENT_HOST_CLIENT_PROXY_CHANNEL = 'agentHostClientProxy';
20 >
21 > /**
22 > * Node end of the proxy-resolution bridge: `resolveProxy()` ships the target
23 > * URL to the renderer and resolves with the *raw* result of VS Code's
24 > * `IRequestService.resolveProxy` (the Electron session PAC-style string, e.g.
25 > * `PROXY host:port` / `DIRECT`). The node side feeds this into
26 > * `@vscode/proxy-agent`'s `resolveProxyURL` to derive the final proxy URL.
27 > */
28 > export interface IAgentHostClientProxyConnection {
29 > resolveProxy(url: string): Promise<string | undefined>;
30 > lookupAuthorization(authInfo: AuthInfo): Promise<Credentials | undefined>;
31 > lookupKerberosAuthorization(url: string): Promise<string | undefined>;
32 > }
33 >
34 > /**
35 > * Wraps an {@link IChannel} (obtained from the agent host's
36 > * `UtilityProcessServer.getChannel`) into an {@link IAgentHostClientProxyConnection}.
37 > */
38 > export function createAgentHostClientProxyConnection(channel: IChannel): IAgentHostClientProxyConnection {
39 return {
40 resolveProxy: (url) => channel.call('resolveProxy', { url }) as Promise<string | undefined>,
43 };
44 }
46 > /**
47 > * Server-side channel for in-process reverse proxy-resolution RPCs from the
48 > * local agent host. Thin adapter — forwards `resolveProxy` calls to the
49 > * renderer's {@link IRequestService}, which resolves the proxy through the
50 > * Electron session (system proxy settings, PAC scripts, etc.). The raw result
51 > * is returned verbatim; the node side derives the proxy URL from it.
52 > */
53 > export class AgentHostClientProxyChannel implements IServerChannel {
54 >
55 > constructor(
56 @IRequestService private readonly _requestService: IRequestService,
57 ) { }
59 > listen<T>(_ctx: unknown, event: string): Event<T> {
60 throw new Error(`No event '${event}' on AgentHostClientProxyChannel`);
61 }
63 > async call<T>(_ctx: unknown, command: string, arg?: unknown): Promise<T> {
64 switch (command) {
65 case 'resolveProxy': {
src/vs/platform/agentHost/node/agentHostRequestService.ts 53 introduced LOC · 11 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- agentHostRequestService.ts
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 { newWriteableBufferStream, VSBuffer, VSBufferWriteableStream } from '../../../base/common/buffer.js';
7 > import { timeout } from '../../../base/common/async.js';
8 > import { CancellationToken } from '../../../base/common/cancellation.js';
9 > import { CancellationError, isCancellationError } from '../../../base/common/errors.js';
10 > import { IDisposable } from '../../../base/common/lifecycle.js';
11 > import { IHeaders, IRequestContext, IRequestOptions } from '../../../base/parts/request/common/request.js';
12 > import { IConfigurationService } from '../../configuration/common/configuration.js';
13 > import { INativeEnvironmentService } from '../../environment/common/environment.js';
14 > import { ILogService } from '../../log/common/log.js';
15 > import { RequestService } from '../../request/node/requestService.js';
16 > import { IAgentHostProxyResolver } from './agentHostProxyResolver.js';
17 >
18 > const TRANSIENT_ERROR_CODES = new Set([
19 > 'EAI_AGAIN',
20 > 'ECONNREFUSED',
21 > 'EHOSTDOWN',
22 > 'EHOSTUNREACH',
23 > 'ENETDOWN',
24 > 'ENETUNREACH',
25 > 'EPROTO',
26 > ]);
27 >
28 > const IDEMPOTENT_HTTP_METHODS_REGEX = /^(GET|HEAD|OPTIONS)$/i;
29 >
30 function isTransientError(error: unknown): boolean {
31 if (error instanceof Error) {
35 return false;
36 }
38 > /**
39 > * Request service implemented on the agent host's `@vscode/proxy-agent`
40 > * patched fetch, including renderer-backed system/PAC resolution and VS Code's
41 > * certificate settings. The base {@link RequestService} remains unchanged for
42 > * all other Node consumers.
43 > */
44 > export class AgentHostRequestService extends RequestService {
45 >
46 > constructor(
47 @IConfigurationService configurationService: IConfigurationService,
48 @INativeEnvironmentService environmentService: INativeEnvironmentService,
52 super('local', configurationService, environmentService, logService);
53 }
55 > override request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
56 return this.logAndRequest(options, () => this._request(options, token));
57 }
59 > override resolveProxy(url: string): Promise<string | undefined> {
60 return this._proxyResolver.resolveProxy(url);
61 }
63 > private async _request(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
64 const maxRetries = 3;
65 let lastError: Error | undefined;
83 throw lastError;
84 }
86 > private async _requestAttempt(options: IRequestOptions, token: CancellationToken): Promise<IRequestContext> {
87 if (token.isCancellationRequested) {
88 throw new CancellationError();
124 }
125 }
127 >
128 function getRequestHeaders(options: IRequestOptions): Headers | undefined {
129 if (!options.headers && !options.user && !options.password && !options.proxyAuthorization) {
149 return headers;
150 }
152 function getResponseHeaders(response: Response): IHeaders {
153 const headers: IHeaders = Object.create(null);
157 return headers;
158 }
160 function emptyResponseStream(cancellationListener: IDisposable): VSBufferWriteableStream {
161 const stream = newWriteableBufferStream();
164 return stream;
165 }
167 function responseBodyToStream(body: ReadableStream<Uint8Array>, cancellation: AbortController, cancellationListener: IDisposable): VSBufferWriteableStream {
168 const reader = body.getReader();
178 return stream;
179 }
181 async function pumpResponseBody(reader: ReadableStreamDefaultReader<Uint8Array>, stream: VSBufferWriteableStream, cancellationListener: IDisposable): Promise<void> {
182 try {