Skip to content

Commit ed64f1c

Browse files
committed
http2: omit server name when HTTP2 host is IP address
Fixes: nodejs#56189
1 parent 67b647e commit ed64f1c

File tree

2 files changed

+74
-9
lines changed

2 files changed

+74
-9
lines changed

lib/internal/http2/core.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -636,15 +636,21 @@ function initOriginSet(session) {
636636
if (originSet === undefined) {
637637
const socket = session[kSocket];
638638
session[kState].originSet = originSet = new SafeSet();
639-
if (socket.servername != null) {
640-
let originString = `https://${socket.servername}`;
641-
if (socket.remotePort != null)
642-
originString += `:${socket.remotePort}`;
643-
// We have to ensure that it is a properly serialized
644-
// ASCII origin string. The socket.servername might not
645-
// be properly ASCII encoded.
646-
originSet.add(getURLOrigin(originString));
639+
let hostName = socket.servername;
640+
if (hostName === null || hostName === false) {
641+
if (socket.remoteFamily === 'IPv6') {
642+
hostName = `[${socket.remoteAddress}]`;
643+
} else {
644+
hostName = socket.remoteAddress;
645+
}
647646
}
647+
let originString = `https://${hostName}`;
648+
if (socket.remotePort != null)
649+
originString += `:${socket.remotePort}`;
650+
// We have to ensure that it is a properly serialized
651+
// ASCII origin string. The socket.servername might not
652+
// be properly ASCII encoded.
653+
originSet.add(getURLOrigin(originString));
648654
}
649655
return originSet;
650656
}
@@ -3333,7 +3339,7 @@ function connect(authority, options, listener) {
33333339
socket = net.connect({ port, host, ...options });
33343340
break;
33353341
case 'https:':
3336-
socket = tls.connect(port, host, initializeTLSOptions(options, host));
3342+
socket = tls.connect(port, host, initializeTLSOptions(options, net.isIP(host) ? undefined : host));
33373343
break;
33383344
default:
33393345
throw new ERR_HTTP2_UNSUPPORTED_PROTOCOL(protocol);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict';
2+
3+
const common = require('../common'); if (!common.hasCrypto) { common.skip('missing crypto'); };
4+
const assert = require('assert');
5+
const fixtures = require('../common/fixtures');
6+
const h2 = require('http2');
7+
8+
function loadKey(keyname) {
9+
return fixtures.readKey(keyname, 'binary');
10+
}
11+
12+
const key = loadKey('agent8-key.pem');
13+
const cert = fixtures.readKey('agent8-cert.pem');
14+
15+
const server = h2.createSecureServer({ key, cert });
16+
server.on('stream', common.mustCall((stream) => {
17+
const session = stream.session;
18+
assert.strictEqual(session.servername, undefined);
19+
stream.respond({ 'content-type': 'application/json' });
20+
stream.end(JSON.stringify({
21+
servername: session.servername,
22+
originSet: session.originSet
23+
})
24+
);
25+
}, 2));
26+
server.on('close', common.mustCall());
27+
server.listen(0, common.mustCall(async () => {
28+
await new Promise((resolve) => {
29+
const client = h2.connect(`https://127.0.0.1:${server.address().port}`,
30+
{ rejectUnauthorized: false });
31+
const req = client.request();
32+
let data = '';
33+
req.setEncoding('utf8');
34+
req.on('data', (d) => data += d);
35+
req.on('end', common.mustCall(() => {
36+
const originSet = req.session.originSet;
37+
assert.strictEqual(originSet[0], `https://127.0.0.1:${server.address().port}`);
38+
client.close();
39+
resolve();
40+
}));
41+
});
42+
43+
await new Promise((resolve) => {
44+
// Test with IPv6 address
45+
const client = h2.connect(`https://[::1]:${server.address().port}`,
46+
{ rejectUnauthorized: false });
47+
const req = client.request();
48+
let data = '';
49+
req.setEncoding('utf8');
50+
req.on('data', (d) => data += d);
51+
req.on('end', common.mustCall(() => {
52+
const originSet = req.session.originSet;
53+
assert.strictEqual(originSet[0], `https://[::1]:${server.address().port}`);
54+
client.close();
55+
resolve();
56+
}));
57+
});
58+
server.close();
59+
}));

0 commit comments

Comments
 (0)