简体   繁体   中英

PRI method in http2 implementation causing issue

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM