-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
http2: allow Host in HTTP/2 requests
The HTTP/2 spec allows Host to be used instead of :authority in requests, and this is in fact *preferred* when converting from HTTP/1. We erroneously treated Host as a connection header, thus disallowing it in requests. The patch corrects this, aligning Node.js behaviour with the HTTP/2 spec and with nghttp2: - Treat Host as a single-value header instead of a connection header. - Don't autofill :authority if Host is present. - The compatibility API (request.authority) falls back to using Host if :authority is not present. This is semver-major because requests are no longer guaranteed to have :authority set. An explanatory note was added to the docs. Fixes: #29858 PR-URL: #34664 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ricky Zhou <0x19951125@gmail.com>
- Loading branch information
1 parent
42a3a7f
commit f5c0e28
Showing
6 changed files
with
125 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
if (!common.hasCrypto) | ||
common.skip('missing crypto'); | ||
const assert = require('assert'); | ||
const h2 = require('http2'); | ||
|
||
// Requests using host instead of :authority should be allowed | ||
// and Http2ServerRequest.authority should fall back to host | ||
|
||
// :authority should NOT be auto-filled if host is present | ||
|
||
const server = h2.createServer(); | ||
server.listen(0, common.mustCall(function() { | ||
const port = server.address().port; | ||
server.once('request', common.mustCall(function(request, response) { | ||
const expected = { | ||
':path': '/foobar', | ||
':method': 'GET', | ||
':scheme': 'http', | ||
'host': `localhost:${port}` | ||
}; | ||
|
||
assert.strictEqual(request.authority, expected.host); | ||
|
||
const headers = request.headers; | ||
for (const [name, value] of Object.entries(expected)) { | ||
assert.strictEqual(headers[name], value); | ||
} | ||
|
||
const rawHeaders = request.rawHeaders; | ||
for (const [name, value] of Object.entries(expected)) { | ||
const position = rawHeaders.indexOf(name); | ||
assert.notStrictEqual(position, -1); | ||
assert.strictEqual(rawHeaders[position + 1], value); | ||
} | ||
|
||
assert(!Object.hasOwnProperty.call(headers, ':authority')); | ||
assert(!Object.hasOwnProperty.call(rawHeaders, ':authority')); | ||
|
||
response.on('finish', common.mustCall(function() { | ||
server.close(); | ||
})); | ||
response.end(); | ||
})); | ||
|
||
const url = `http://localhost:${port}`; | ||
const client = h2.connect(url, common.mustCall(function() { | ||
const headers = { | ||
':path': '/foobar', | ||
':method': 'GET', | ||
':scheme': 'http', | ||
'host': `localhost:${port}` | ||
}; | ||
const request = client.request(headers); | ||
request.on('end', common.mustCall(function() { | ||
client.close(); | ||
})); | ||
request.end(); | ||
request.resume(); | ||
})); | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters