diff --git a/CHANGELOG.md b/CHANGELOG.md index c946b00..d6660f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/package.json b/package.json index f33c7fc..03c07c0 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/index.ts b/src/index.ts index e6b4f84..20ab2b1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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', { @@ -822,6 +822,8 @@ class ProxyDispatcher extends undici.Dispatcher { constructor( private params: ProxyAgentParams, private resolveProxyURL: (url: string) => Promise, + private doResolveProxy: boolean, + private addCerts: boolean, private originalDispatcher: undici.Dispatcher | undefined, ) { super(); @@ -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 { diff --git a/tests/test-client/src/proxy.test.ts b/tests/test-client/src/proxy.test.ts index 686e0f3..ddb6154 100644 --- a/tests/test-client/src/proxy.test.ts +++ b/tests/test-client/src/proxy.test.ts @@ -1,3 +1,4 @@ +import * as http from 'http'; import * as https from 'https'; import * as undici from 'undici'; import * as assert from 'assert'; @@ -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((resolve, reject) => { + const req = https.request({ hostname: 'test-https-server', path: '/test-path', agent: createPacProxyAgent(async () => 'PROXY test-http-auth-proxy:3128', { @@ -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 () {