http,https: handle IPv6 with proxies · nodejs/node@6695067

1+

// This tests making HTTPS requests through an HTTP proxy using IPv6 addresses.

2+3+

import * as common from '../common/index.mjs';

4+

import fixtures from '../common/fixtures.js';

5+

import assert from 'node:assert';

6+

import { once } from 'events';

7+

import { createProxyServer, runProxiedRequest } from '../common/proxy-server.js';

8+9+

if (!common.hasIPv6) {

10+

common.skip('missing IPv6 support');

11+

}

12+13+

if (!common.hasCrypto) {

14+

common.skip('missing crypto');

15+

}

16+17+

// https must be dynamically imported so that builds without crypto support

18+

// can skip it.

19+

const { default: https } = await import('node:https');

20+21+

// Start a server to process the final request.

22+

const server = https.createServer({

23+

cert: fixtures.readKey('agent8-cert.pem'),

24+

key: fixtures.readKey('agent8-key.pem'),

25+

}, common.mustCall((req, res) => {

26+

res.end('Hello world');

27+

}, 2));

28+

server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));

29+

server.listen(0);

30+

await once(server, 'listening');

31+32+

// Start a minimal proxy server.

33+

const { proxy, logs } = createProxyServer();

34+

proxy.listen(0);

35+

await once(proxy, 'listening');

36+37+

{

38+

const serverHost = `localhost:${server.address().port}`;

39+

const requestUrl = `https://${serverHost}/test`;

40+

const expectedLogs = [{

41+

method: 'CONNECT',

42+

url: serverHost,

43+

headers: {

44+

'proxy-connection': 'keep-alive',

45+

'host': serverHost,

46+

},

47+

}];

48+49+

const { code, signal, stdout } = await runProxiedRequest({

50+

NODE_USE_ENV_PROXY: 1,

51+

REQUEST_URL: requestUrl,

52+

HTTPS_PROXY: `http://[::1]:${proxy.address().port}`,

53+

NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),

54+

});

55+

assert.deepStrictEqual(logs, expectedLogs);

56+

assert.match(stdout, /Hello world/);

57+

assert.strictEqual(code, 0);

58+

assert.strictEqual(signal, null);

59+

}

60+61+

// Test with IPv6 address in the request URL.

62+

{

63+

logs.splice(0, logs.length); // Clear the logs.

64+

const serverHost = `[::1]:${server.address().port}`;

65+

const requestUrl = `https://${serverHost}/test`;

66+

const expectedLogs = [{

67+

method: 'CONNECT',

68+

url: serverHost,

69+

headers: {

70+

'proxy-connection': 'keep-alive',

71+

'host': serverHost,

72+

},

73+

}];

74+75+

const { code, signal, stdout } = await runProxiedRequest({

76+

NODE_USE_ENV_PROXY: 1,

77+

REQUEST_URL: requestUrl,

78+

HTTPS_PROXY: `http://[::1]:${proxy.address().port}`,

79+

// Disable certificate verification for this request, for we don't have

80+

// a certificate for [::1].

81+

NODE_TLS_REJECT_UNAUTHORIZED: '0',

82+

});

83+

assert.deepStrictEqual(logs, expectedLogs);

84+

assert.match(stdout, /Hello world/);

85+

assert.strictEqual(code, 0);

86+

assert.strictEqual(signal, null);

87+

}

88+89+

proxy.close();

90+

server.close();