I am trying to extend a server with HTTP/2 which already supports HTTP/1.1 with TLS v1.2 . I am writing it in Go where I define tls config like this -
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
ServerName: "mysrvr",
NextProtos: []string{"h2", "http/1.1", "http/1.0"},
Time: time.Now,
Rand: rand.Reader,
}
As is evident, I have used " h2 " string to set up ALPN handshake.
Now when I make request via curl, I receive this request -
$ curl -v https://127.0.0.1:8000 -k --http2
When I parse request, it shows a PRI method being sent first instead of GET -
HTTP/2.0
PRI
I got some idea on PRI method from https://tools.ietf.org/html/rfc7540#page-78 wherein it says the following -
This method is never used by an actual client.
This method will appear to be used when an HTTP/1.1 server or
intermediary attempts to parse an HTTP/2 connection preface.
My question now is why was PRI request sent, when clearly the server supports HTTP/2 ? Do I need to parse it and respond with empty SETTINGS frame in accordance with HTTP/2 spec or should the Go http2 runtime should have taken care of it?
I am using http.ReadRequest
to parse client requests, but that doesn't seem to be working for HTTP/2 requests even when I ignore PRI requests (as suggested below).
The first message a HTTP/2 client should send is this PRI message. From the HTTP/2 specification :
In HTTP/2, each endpoint is required to send a connection preface as a final confirmation of the protocol in use and to establish the initial settings for the HTTP/2 connection. The client and server each send a different connection preface.
The client connection preface starts with a sequence of 24 octets, which in hex notation is:
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
That is, the connection preface starts with the string PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n). This sequence MUST be followed by a SETTINGS frame (Section 6.5), which MAY be empty.
...
Note : The client connection preface is selected so that a large proportion of HTTP/1.1 or HTTP/1.0 servers and intermediaries do not attempt to process further frames.
The point of this message is that it is a fake HTTP/1-like message so any server which is not HTTP/2 aware should response with an error.
Any HTTP/2 server should expect this message to be sent, and then should just ignore it, and the carry on speaking HTTP/2.
In fact if this message is NOT sent, then the server should treat this as an error and not continue:
Clients and servers MUST treat an invalid connection preface as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. A GOAWAY frame (Section 6.8) MAY be omitted in this case, since an invalid preface indicates that the peer is not using HTTP/2.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.