Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP/2 Host header disallowed #29858

Closed
mildsunrise opened this issue Oct 6, 2019 · 5 comments
Closed

HTTP/2 Host header disallowed #29858

mildsunrise opened this issue Oct 6, 2019 · 5 comments
Labels
http2 Issues or PRs related to the http2 subsystem.

Comments

@mildsunrise
Copy link
Member

mildsunrise commented Oct 6, 2019

Node.JS currently treats Host as a connection header, and connection headers can't be used in an HTTP/2 request.

TypeError [ERR_HTTP2_INVALID_CONNECTION_HEADERS]: HTTP/1 Connection specific headers are forbidden: "host"

I'm not sure it should be considered a connection header. The HTTP/2 spec recommends using the Host header instead of :authority if you are converting from an HTTP/1 request. This is an excerpt of the examples section:

   This section shows HTTP/1.1 requests and responses, with
   illustrations of equivalent HTTP/2 requests and responses.

   An HTTP GET request includes request header fields and no payload
   body and is therefore transmitted as a single HEADERS frame, followed
   by zero or more CONTINUATION frames containing the serialized block
   of request header fields.  The HEADERS frame in the following has
   both the END_HEADERS and END_STREAM flags set; no CONTINUATION frames
   are sent.

     GET /resource HTTP/1.1           HEADERS
     Host: example.org          ==>     + END_STREAM
     Accept: image/jpeg                 + END_HEADERS
                                          :method = GET
                                          :scheme = https
                                          :path = /resource
                                          host = example.org
                                          accept = image/jpeg

I think the correct behaviour would be for Node.JS to allow host, and omit auto-filling :authority if it's supplied.

The current behaviour was there from the very introduction of http2 (#14239), so I'm not sure if there was a special motivation for considering host a connection header? Does it interact with something else?

I don't know what we should do... But I strongly think we should at least give users a way to supply host without an error.

@Fishrock123 Fishrock123 added the http2 Issues or PRs related to the http2 subsystem. label Oct 14, 2019
@ejames17
Copy link

@mildsunrise +1 for this.

@codedrift
Copy link

+1

I'm trying to use AWS transcribe streaming which requires a host header to be present because it is signed before sending the request. See https://docs.aws.amazon.com/transcribe/latest/dg/how-streaming.html -> "Required Headers"

@mildsunrise
Copy link
Member Author

@codedrift Fortunately they also seem to allow :authority :) The catch is, you need to use Host when signing, then rename the header to :authority when sending the request.
If it's useful, here's a demo on accessing the Transcribe Streaming API, which uses my a4s library for signing.

@codedrift
Copy link

@codedrift Fortunately they also seem to allow :authority :) The catch is, you need to use Host when signing, then rename the header to :authority when sending the request.
If it's useful, here's a demo on accessing the Transcribe Streaming API, which uses my a4s library for signing.

Awesome! Thank you very much!

@codedrift
Copy link

@mildsunrise So i adapted your library and it works perfectly! 🚀

mildsunrise added a commit to mildsunrise/node that referenced this issue Aug 7, 2020
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: nodejs#29858
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
http2 Issues or PRs related to the http2 subsystem.
Projects
None yet
Development

No branches or pull requests

4 participants