Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Change Log
Notable changes will be documented here.

## [0.39.1]
- Fix WebSocket `ProxyDispatcher` to respect `doResolveProxy` and `addCerts` flags from `createWebSocketPatch` ([microsoft/vscode-proxy-agent#90](https://github.com/microsoft/vscode-proxy-agent/pull/90))
- Fix intermittent 407 test by checking `res.statusCode` directly

## [0.39.0]
- Add WebSocket proxy support via `createWebSocketPatch` ([microsoft/vscode-proxy-agent#89](https://github.com/microsoft/vscode-proxy-agent/pull/89))

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vscode/proxy-agent",
"version": "0.39.0",
"version": "0.39.1",
"description": "NodeJS http(s) agent implementation for VS Code",
"main": "out/index.js",
"types": "out/index.d.ts",
Expand Down
15 changes: 8 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ export function createWebSocketPatch(params: ProxyAgentParams, originalWebSocket
return new originalWebSocket(url, protocols as any);
}

const proxyDispatcher = new ProxyDispatcher(params, resolveProxyURL, init.dispatcher);
const proxyDispatcher = new ProxyDispatcher(params, resolveProxyURL, doResolveProxy, addCerts, init.dispatcher);
init.dispatcher = proxyDispatcher;
const ws = new originalWebSocket(url, init as any);
Object.defineProperty(ws, 'responseHeaders', {
Expand Down Expand Up @@ -822,6 +822,8 @@ class ProxyDispatcher extends undici.Dispatcher {
constructor(
private params: ProxyAgentParams,
private resolveProxyURL: (url: string) => Promise<string | undefined>,
private doResolveProxy: boolean,
private addCerts: boolean,
private originalDispatcher: undici.Dispatcher | undefined,
) {
super();
Expand Down Expand Up @@ -854,22 +856,21 @@ class ProxyDispatcher extends undici.Dispatcher {
const url = opts.origin?.toString();
(async () => {
try {
const addCerts = this.params.addCertificatesV1() || this.params.addCertificatesV2();
// Map ws:/wss: to http:/https: for proxy resolution
let resolveURL = url;
if (resolveURL) {
resolveURL = resolveURL.replace(/^ws(s?):/, 'http$1:');
}
const proxyURL = resolveURL ? await this.resolveProxyURL(resolveURL) : undefined;
const systemCA = addCerts ? [...tls.rootCertificates, ...await getOrLoadAdditionalCertificates(this.params)] : undefined;
const proxyURL = this.doResolveProxy && resolveURL ? await this.resolveProxyURL(resolveURL) : undefined;
const systemCA = this.addCerts ? [...tls.rootCertificates, ...await getOrLoadAdditionalCertificates(this.params)] : undefined;
const callerOptions = getAgentOptions({ dispatcher: this.originalDispatcher } as any);
const requestCA = callerOptions.requestCA || systemCA;
const proxyCA = callerOptions.proxyCA || systemCA;
let dispatcher: undici.Dispatcher;
if (proxyURL) {
dispatcher = getProxyAgent(this.params, this.originalDispatcher, proxyURL, callerOptions.allowH2, requestCA, proxyCA, addCerts);
} else if (addCerts) {
dispatcher = getAgent(this.originalDispatcher, callerOptions.allowH2, requestCA, addCerts)!;
dispatcher = getProxyAgent(this.params, this.originalDispatcher, proxyURL, callerOptions.allowH2, requestCA, proxyCA, this.addCerts);
} else if (this.addCerts) {
dispatcher = getAgent(this.originalDispatcher, callerOptions.allowH2, requestCA, this.addCerts)!;
} else if (this.originalDispatcher) {
dispatcher = this.originalDispatcher;
} else {
Expand Down
17 changes: 9 additions & 8 deletions tests/test-client/src/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as http from 'http';
import * as https from 'https';
import * as undici from 'undici';
import * as assert from 'assert';
Expand Down Expand Up @@ -58,8 +59,9 @@ describe('Proxied client', function () {
});

it('should fail with 407 when auth is missing', async function () {
try {
await testRequest(https, {
// Use the https module directly because https-proxy-agent doesn't always trigger 'end' on the body.
const res = await new Promise<http.IncomingMessage>((resolve, reject) => {
const req = https.request({
hostname: 'test-https-server',
path: '/test-path',
agent: createPacProxyAgent(async () => 'PROXY test-http-auth-proxy:3128', {
Expand All @@ -68,12 +70,11 @@ describe('Proxied client', function () {
},
}),
ca,
});
} catch (err) {
assert.strictEqual((err as any).statusCode, 407);
return;
}
assert.fail('Should have failed');
}, resolve);
req.on('error', reject);
req.end();
});
assert.strictEqual(res.statusCode, 407);
});

it('should fail with 407 when auth is missing (fetch)', async function () {
Expand Down
Loading