diff options
author | Alba Mendez <me@alba.sh> | 2020-08-07 13:54:08 +0300 |
---|---|---|
committer | Alba Mendez <me@alba.sh> | 2020-08-17 14:49:59 +0300 |
commit | f5c0e282ccf98e17f295c11850649ad19a6fff51 (patch) | |
tree | ba580ab119454eee33c3d0aa18968008d7ad2a31 /doc/api/http2.md | |
parent | 42a3a7f97d3b565763671047c774c858c1e0d5c1 (diff) |
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: https://github.com/nodejs/node/issues/29858
PR-URL: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'doc/api/http2.md')
-rw-r--r-- | doc/api/http2.md | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/doc/api/http2.md b/doc/api/http2.md index c8c51ed92ef..5adf84e27f8 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -2,6 +2,10 @@ <!-- YAML added: v8.4.0 changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/34664 + description: Requests with the `host` header (with or without + `:authority`) can now be sent/received. - version: v10.10.0 pr-url: https://github.com/nodejs/node/pull/22466 description: HTTP/2 is now Stable. Previously, it had been Experimental. @@ -2530,7 +2534,7 @@ For incoming headers: `access-control-max-age`, `access-control-request-method`, `content-encoding`, `content-language`, `content-length`, `content-location`, `content-md5`, `content-range`, `content-type`, `date`, `dnt`, `etag`, `expires`, `from`, - `if-match`, `if-modified-since`, `if-none-match`, `if-range`, + `host`, `if-match`, `if-modified-since`, `if-none-match`, `if-range`, `if-unmodified-since`, `last-modified`, `location`, `max-forwards`, `proxy-authorization`, `range`, `referer`,`retry-after`, `tk`, `upgrade-insecure-requests`, `user-agent` or `x-content-type-options` are @@ -2909,8 +2913,10 @@ added: v8.4.0 * {string} -The request authority pseudo header field. It can also be accessed via -`req.headers[':authority']`. +The request authority pseudo header field. Because HTTP/2 allows requests +to set either `:authority` or `host`, this value is derived from +`req.headers[':authority']` if present. Otherwise, it is derived from +`req.headers['host']`. #### `request.complete` <!-- YAML @@ -3709,6 +3715,18 @@ following additional properties: * `type` {string} Either `'server'` or `'client'` to identify the type of `Http2Session`. +## Note on `:authority` and `host` + +HTTP/2 requires requests to have either the `:authority` pseudo-header +or the `host` header. Prefer `:authority` when constructing an HTTP/2 +request directly, and `host` when converting from HTTP/1 (in proxies, +for instance). + +The compatibility API falls back to `host` if `:authority` is not +present. See [`request.authority`][] for more information. However, +if you don't use the compatibility API (or use `req.headers` directly), +you need to implement any fall-back behaviour yourself. + [ALPN Protocol ID]: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids [ALPN negotiation]: #http2_alpn_negotiation [Compatibility API]: #http2_compatibility_api @@ -3749,6 +3767,7 @@ following additional properties: [`net.Socket.prototype.unref()`]: net.html#net_socket_unref [`net.Socket`]: net.html#net_class_net_socket [`net.connect()`]: net.html#net_net_connect +[`request.authority`]: #http2_request_authority [`request.socket`]: #http2_request_socket [`request.socket.getPeerCertificate()`]: tls.html#tls_tlssocket_getpeercertificate_detailed [`response.end()`]: #http2_response_end_data_encoding_callback |