Skip to content

Commit a09d380

Browse files
committed
Add HTTPS proxy automated tests (microsoft/vscode#235410)
1 parent ab908e6 commit a09d380

File tree

9 files changed

+114
-24
lines changed

9 files changed

+114
-24
lines changed

src/agent.ts

+1
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,5 @@ type PacProxyAgentOptions =
262262
SocksProxyAgentOptions & {
263263
fallbackToDirect?: boolean;
264264
originalAgent?: false | http.Agent;
265+
_vscodeTestReplaceCaCerts?: boolean;
265266
}

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ export function createHttpPatch(params: ProxyAgentParams, originals: typeof http
395395
originalAgent: (!useProxySettings || isLocalhost || config === 'fallback') ? originalAgent : undefined,
396396
lookupProxyAuthorization: params.lookupProxyAuthorization,
397397
// keepAlive: ((originalAgent || originals.globalAgent) as { keepAlive?: boolean }).keepAlive, // Skipping due to https://github.com/microsoft/vscode/issues/228872.
398+
_vscodeTestReplaceCaCerts: (options as SecureContextOptionsPatch)._vscodeTestReplaceCaCerts,
398399
}, opts => new Promise<void>(resolve => addCertificatesToOptionsV1(params, params.addCertificatesV1(), opts, resolve)));
399400
agent.protocol = isHttps ? 'https:' : 'http:';
400401
options.agent = agent

tests/docker-compose.yml

+21
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ services:
1919
build: test-proxy-client
2020
volumes:
2121
- ..:/repo
22+
- ./test-https-proxy/mitmproxy-config:/root/.mitmproxy
2223
networks:
2324
- test-proxies
2425
working_dir: /repo/tests/test-client
2526
environment:
2627
- MOCHA_TESTS=src/proxy.test.ts
2728
command: /bin/sh -c '
29+
while [ ! -f /root/.mitmproxy/mitmproxy-ca-cert.pem ]; do sleep 1; done &&
30+
cp /root/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt &&
31+
update-ca-certificates &&
2832
/usr/local/bin/configure-kerberos-client.sh &&
2933
rm -rf /root/.npm &&
3034
npm run test:watch'
@@ -35,6 +39,8 @@ services:
3539
condition: service_started
3640
test-http-kerberos-proxy:
3741
condition: service_started
42+
test-https-proxy:
43+
condition: service_started
3844
test-http-proxy:
3945
image: ubuntu/squid:latest
4046
networks:
@@ -68,6 +74,21 @@ services:
6874
depends_on:
6975
test-https-server:
7076
condition: service_healthy
77+
test-https-proxy:
78+
image: mitmproxy/mitmproxy:latest
79+
# https://stackoverflow.com/q/61453754
80+
command: /bin/sh -c 'update-ca-certificates && mitmdump --set ssl_insecure=true'
81+
volumes:
82+
- ./test-https-proxy/mitmproxy-config:/root/.mitmproxy
83+
- ./test-https-server/ssl_cert.pem:/usr/local/share/ca-certificates/test-https-server.crt
84+
networks:
85+
- test-proxies
86+
- test-proxies-and-servers
87+
ports:
88+
- 8080
89+
depends_on:
90+
test-https-server:
91+
condition: service_healthy
7192
test-https-server:
7293
image: test-https-server:latest
7394
build: test-https-server

tests/test-client/package-lock.json

+55-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/test-client/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
"devDependencies": {
1414
"@types/kerberos": "^1.1.2",
1515
"@types/mocha": "5.2.5",
16-
"@types/node": "^16.17.1",
16+
"@types/node": "^20.8.4",
1717
"kerberos": "^2.0.1",
1818
"mocha": "10.2.0",
1919
"ts-node": "9.1.1",
20-
"typescript": "^4.2.2"
20+
"typescript": "^5.2.2",
21+
"undici": "^6.20.1"
2122
}
2223
}

tests/test-client/src/proxy.test.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import * as https from 'https';
2+
import * as tls from 'tls';
23
import * as assert from 'assert';
4+
import * as fs from 'fs';
5+
import * as path from 'path';
36
import * as vpa from '../../..';
47
import { createPacProxyAgent } from '../../../src/agent';
5-
import { testRequest, ca, unusedCa, proxiedProxyAgentParamsV1 } from './utils';
8+
import { testRequest, ca, unusedCa, proxiedProxyAgentParamsV1, tlsProxiedProxyAgentParamsV1 } from './utils';
69

710
describe('Proxied client', function () {
811
it('should use HTTP proxy for HTTPS connection', function () {
@@ -14,6 +17,27 @@ describe('Proxied client', function () {
1417
});
1518
});
1619

20+
it('should use HTTPS proxy for HTTPS connection', function () {
21+
const { resolveProxyWithRequest: resolveProxy } = vpa.createProxyResolver(tlsProxiedProxyAgentParamsV1);
22+
const patchedHttps: typeof https = {
23+
...https,
24+
...vpa.createHttpPatch(tlsProxiedProxyAgentParamsV1, https, resolveProxy),
25+
} as any;
26+
return testRequest(patchedHttps, {
27+
hostname: 'test-https-server',
28+
path: '/test-path',
29+
_vscodeTestReplaceCaCerts: true,
30+
});
31+
});
32+
33+
it('should use HTTPS proxy for HTTPS connection (fetch)', async function () {
34+
const { resolveProxyURL } = vpa.createProxyResolver(tlsProxiedProxyAgentParamsV1);
35+
const patchedFetch = vpa.createFetchPatch(tlsProxiedProxyAgentParamsV1, globalThis.fetch, resolveProxyURL);
36+
const res = await patchedFetch('https://test-https-server/test-path');
37+
assert.strictEqual(res.status, 200);
38+
assert.strictEqual((await res.json()).status, 'OK!');
39+
});
40+
1741
it('should support basic auth', function () {
1842
return testRequest(https, {
1943
hostname: 'test-https-server',

tests/test-client/src/utils.ts

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const directProxyAgentParams: vpa.ProxyAgentParams = {
1818
resolveProxy: async () => 'DIRECT',
1919
getProxyURL: () => undefined,
2020
getProxySupport: () => 'override',
21+
isAdditionalFetchSupportEnabled: () => true,
2122
addCertificatesV1: () => false,
2223
addCertificatesV2: () => true,
2324
log: console,
@@ -42,6 +43,11 @@ export const proxiedProxyAgentParamsV1: vpa.ProxyAgentParams = {
4243
resolveProxy: async () => 'PROXY test-http-proxy:3128',
4344
};
4445

46+
export const tlsProxiedProxyAgentParamsV1: vpa.ProxyAgentParams = {
47+
...directProxyAgentParamsV1,
48+
resolveProxy: async () => 'HTTPS test-https-proxy:8080',
49+
};
50+
4551
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; } = {}) {
4652
return new Promise<void>((resolve, reject) => {
4753
const req = client.request(options, res => {

tests/test-client/tsconfig.json

+1-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@
44
"target": "es2015",
55
"esModuleInterop": true,
66
"strict": true,
7-
"resolveJsonModule": true,
8-
"lib": [
9-
"esnext"
10-
]
7+
"resolveJsonModule": true
118
},
129
"exclude": [
1310
"node_modules"

tests/test-https-proxy/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mitmproxy-config

0 commit comments

Comments
 (0)