Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.Sign up
net/http: Server with TLS consumes "Upgrade" header #30204
What version of Go are you using (
Hello @ssttevee, thank you for filing this issue and welcome to the Go project!
So firstly, cURL will fix the headers for you and include "Connection": "upgrade" after seeing "Upgrade": "Websocket" which it fixed from "Upgrade": "websocket".
GET / HTTP/2 Host: localhost:8844 User-Agent: curl/7.54.0 Accept: */* Upgrade:Websocket Connection:upgrade
Now since "Connection" is a hop-by-by and connection-specific header but also not supported by HTTP/2.0 (well for Go, except only if "Connection": "close" that means a graceful shutdown), including it in an HTTP/2.0 response violates the spec at Section 184.108.40.206
HTTP/2 does not use the Connection header field to indicate connection-specific header fields; in this protocol, connection-specific metadata is conveyed by other means. An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields; any message containing connection-specific header fields MUST be treated as malformed (Section 220.127.116.11).
The only exception to this is the TE header field, which MAY be present in an HTTP/2 request; when it is, it MUST NOT contain any value other than "trailers".
This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need to remove any header fields nominated by the Connection header field, along with the Connection header field itself. Such intermediaries SHOULD also remove other connection-specific header fields, such as Keep-Alive, Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field.
as you can see from above, the spec mandates that a valid HTTP/2.0 server remove connection-specific headers and in this case "Connection" and "Upgrade" are pruned out.
If you use Go's HTTP client, it will automatically instead use an HTTP/1.1 connection and your HTTP/1.1 response will include the headers back such as
HTTP/1.1 200 OK Content-Length: 137 Content-Type: text/plain; charset=utf-8 Date: Wed, 13 Feb 2019 14:07:11 GMT GET / HTTP/1.1 Host: localhost:8844 Accept-Encoding: gzip Connection: upgrade Upgrade: Websocket User-Agent: Go-http-client/1.1
Thus I believe this is working as intended and not a bug.
Kindly paging @bradfitz to help me double check my assessment.
Yeah, what @odeke-em said. You can see the same behavior on http2.golang.org which is running Go 1.11, not Go 1.12rc1:
I'm closing this as not a bug, but let us know if there's some other problem you're hitting that led you to debugging and suspecting this.