Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -2732,6 +2732,10 @@ a given number of milliseconds set using `http2secureServer.setTimeout()`.
<!-- YAML
added: v8.4.0
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/64493
description: The event is emitted when a custom `ALPNCallback` selects an
unsupported protocol.
- version: v19.0.0
pr-url: https://github.com/nodejs/node/pull/44031
description: This event will only be emitted if the client did not transmit
Expand All @@ -2750,9 +2754,12 @@ In earlier versions of Node.js, this event would be emitted if `allowHTTP1` is
`false` and, during the TLS handshake, the client either does not send an ALPN
extension or sends an ALPN extension that does not include HTTP/2 (`h2`). Newer
versions of Node.js only emit this event if `allowHTTP1` is `false` and the
client does not send an ALPN extension. If the client sends an ALPN extension
that does not include HTTP/2 (or HTTP/1.1 if `allowHTTP1` is `true`), the TLS
handshake will fail and no secure connection will be established.
client does not send an ALPN extension. The event is also emitted when a custom
`ALPNCallback` selects a protocol other than `h2` (or `http/1.1` when
`allowHTTP1` is `true`). With the default ALPN configuration, if the client
sends an ALPN extension that does not include HTTP/2 (or HTTP/1.1 if
`allowHTTP1` is `true`), the TLS handshake will fail and no secure connection
will be established.

See the [Compatibility API][].

Expand Down
6 changes: 4 additions & 2 deletions lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -3523,9 +3523,11 @@ function connectionListener(socket) {
debug('Http2Session server: received a connection');
const options = this[kOptions] || {};

if (socket.alpnProtocol === false || socket.alpnProtocol === 'http/1.1') {
if (socket.alpnProtocol !== undefined && socket.alpnProtocol !== 'h2') {
// Fallback to HTTP/1.1
if (options.allowHTTP1 === true) {
if (options.allowHTTP1 === true &&
(socket.alpnProtocol === false ||
socket.alpnProtocol === 'http/1.1')) {
return httpConnectionListener.call(this, socket);
}
// Let event handler deal with the socket
Expand Down
9 changes: 7 additions & 2 deletions test/parallel/test-http2-alpn.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@ const tls = require('tls');
}), (error) => error.code === 'ERR_TLS_ALPN_CALLBACK_WITH_PROTOCOLS');
}

{
for (const allowHTTP1 of [false, true]) {
const server = h2.createSecureServer({
key: fixtures.readKey('rsa_private.pem'),
cert: fixtures.readKey('rsa_cert.crt'),
ALPNCallback: () => 'a',
allowHTTP1,
});

server.on('unknownProtocol', common.mustCall((socket) => {
assert.strictEqual(socket.alpnProtocol, 'a');
}));
server.on('session', common.mustNotCall());
server.on(
'secureConnection',
common.mustCall((socket) => {
assert.strictEqual(socket.alpnProtocol, 'a');
socket.end();
server.close();
})
}),
);

server.listen(0, common.mustCall(() => {
Expand Down
Loading