Skip to content

Commit

Permalink
Add HTTPS proxy automated tests (microsoft/vscode#235410)
Browse files Browse the repository at this point in the history
  • Loading branch information
chrmarti committed Dec 5, 2024
1 parent bc806c6 commit d1d4889
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,5 @@ type PacProxyAgentOptions =
SocksProxyAgentOptions & {
fallbackToDirect?: boolean;
originalAgent?: false | http.Agent;
_vscodeTestReplaceCaCerts?: boolean;
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ export function createHttpPatch(params: ProxyAgentParams, originals: typeof http
originalAgent: (!useProxySettings || isLocalhost || config === 'fallback') ? originalAgent : undefined,
lookupProxyAuthorization: params.lookupProxyAuthorization,
// keepAlive: ((originalAgent || originals.globalAgent) as { keepAlive?: boolean }).keepAlive, // Skipping due to https://github.com/microsoft/vscode/issues/228872.
_vscodeTestReplaceCaCerts: (options as SecureContextOptionsPatch)._vscodeTestReplaceCaCerts,
}, opts => new Promise<void>(resolve => addCertificatesToOptionsV1(params, params.addCertificatesV1(), opts, resolve)));
agent.protocol = isHttps ? 'https:' : 'http:';
options.agent = agent
Expand Down
21 changes: 21 additions & 0 deletions tests/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ services:
build: test-proxy-client
volumes:
- ..:/repo
- ./test-https-proxy/mitmproxy-config:/root/.mitmproxy
networks:
- test-proxies
working_dir: /repo/tests/test-client
environment:
- MOCHA_TESTS=src/proxy.test.ts
command: /bin/sh -c '
while [ ! -f /root/.mitmproxy/mitmproxy-ca-cert.pem ]; do sleep 1; done &&
cp /root/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt &&
update-ca-certificates &&
/usr/local/bin/configure-kerberos-client.sh &&
rm -rf /root/.npm &&
npm run test:watch'
Expand All @@ -35,6 +39,8 @@ services:
condition: service_started
test-http-kerberos-proxy:
condition: service_started
test-https-proxy:
condition: service_started
test-http-proxy:
image: ubuntu/squid:latest
networks:
Expand Down Expand Up @@ -68,6 +74,21 @@ services:
depends_on:
test-https-server:
condition: service_healthy
test-https-proxy:
image: mitmproxy/mitmproxy:latest
# https://stackoverflow.com/q/61453754
command: /bin/sh -c 'update-ca-certificates && mitmdump --set ssl_insecure=true'
volumes:
- ./test-https-proxy/mitmproxy-config:/root/.mitmproxy
- ./test-https-server/ssl_cert.pem:/usr/local/share/ca-certificates/test-https-server.crt
networks:
- test-proxies
- test-proxies-and-servers
ports:
- 8080
depends_on:
test-https-server:
condition: service_healthy
test-https-server:
image: test-https-server:latest
build: test-https-server
Expand Down
72 changes: 55 additions & 17 deletions tests/test-client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions tests/test-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
"devDependencies": {
"@types/kerberos": "^1.1.2",
"@types/mocha": "5.2.5",
"@types/node": "^16.17.1",
"@types/node": "^20.8.4",
"kerberos": "^2.0.1",
"mocha": "10.2.0",
"ts-node": "9.1.1",
"typescript": "^4.2.2"
"typescript": "^5.2.2",
"undici": "^6.20.1"
}
}
26 changes: 25 additions & 1 deletion tests/test-client/src/proxy.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import * as https from 'https';
import * as tls from 'tls';
import * as assert from 'assert';
import * as fs from 'fs';
import * as path from 'path';
import * as vpa from '../../..';
import { createPacProxyAgent } from '../../../src/agent';
import { testRequest, ca, unusedCa, proxiedProxyAgentParamsV1 } from './utils';
import { testRequest, ca, unusedCa, proxiedProxyAgentParamsV1, tlsProxiedProxyAgentParamsV1 } from './utils';

describe('Proxied client', function () {
it('should use HTTP proxy for HTTPS connection', function () {
Expand All @@ -14,6 +17,27 @@ describe('Proxied client', function () {
});
});

it('should use HTTPS proxy for HTTPS connection', function () {
const { resolveProxyWithRequest: resolveProxy } = vpa.createProxyResolver(tlsProxiedProxyAgentParamsV1);
const patchedHttps: typeof https = {
...https,
...vpa.createHttpPatch(tlsProxiedProxyAgentParamsV1, https, resolveProxy),
} as any;
return testRequest(patchedHttps, {
hostname: 'test-https-server',
path: '/test-path',
_vscodeTestReplaceCaCerts: true,
});
});

it('should use HTTPS proxy for HTTPS connection (fetch)', async function () {
const { resolveProxyURL } = vpa.createProxyResolver(tlsProxiedProxyAgentParamsV1);
const patchedFetch = vpa.createFetchPatch(tlsProxiedProxyAgentParamsV1, globalThis.fetch, resolveProxyURL);
const res = await patchedFetch('https://test-https-server/test-path');
assert.strictEqual(res.status, 200);
assert.strictEqual((await res.json()).status, 'OK!');
});

it('should support basic auth', function () {
return testRequest(https, {
hostname: 'test-https-server',
Expand Down
6 changes: 6 additions & 0 deletions tests/test-client/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const directProxyAgentParams: vpa.ProxyAgentParams = {
resolveProxy: async () => 'DIRECT',
getProxyURL: () => undefined,
getProxySupport: () => 'override',
isAdditionalFetchSupportEnabled: () => true,
addCertificatesV1: () => false,
addCertificatesV2: () => true,
log: console,
Expand All @@ -42,6 +43,11 @@ export const proxiedProxyAgentParamsV1: vpa.ProxyAgentParams = {
resolveProxy: async () => 'PROXY test-http-proxy:3128',
};

export const tlsProxiedProxyAgentParamsV1: vpa.ProxyAgentParams = {
...directProxyAgentParamsV1,
resolveProxy: async () => 'HTTPS test-https-proxy:8080',
};

export async function testRequest<C extends typeof https | typeof http>(client: C, options: C extends typeof https ? (https.RequestOptions & vpa.SecureContextOptionsPatch) : http.RequestOptions, testOptions: { assertResult?: (result: any, req: http.ClientRequest, res: http.IncomingMessage) => void; } = {}) {
return new Promise<void>((resolve, reject) => {
const req = client.request(options, res => {
Expand Down
5 changes: 1 addition & 4 deletions tests/test-client/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
"target": "es2015",
"esModuleInterop": true,
"strict": true,
"resolveJsonModule": true,
"lib": [
"esnext"
]
"resolveJsonModule": true
},
"exclude": [
"node_modules"
Expand Down
1 change: 1 addition & 0 deletions tests/test-https-proxy/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mitmproxy-config

0 comments on commit d1d4889

Please sign in to comment.