简体   繁体   English

http2实现中的PRI方法导致问题

[英]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 . 我正在尝试使用HTTP / 2扩展服务器,该服务器已经支持TLS v1.2的 HTTP / 1.1 I am writing it in Go where I define tls config like this - 我在Go中编写它,我在其中定义了tls config-

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. 显而易见,我使用了“ h2 ”字符串来设置ALPN握手。

Now when I make request via curl, I receive this request - 现在,当我通过curl发出请求时,我收到了此请求-

$ 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 - 当我解析请求时,它显示了先发送PRI方法而不是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 - 我从https://tools.ietf.org/html/rfc7540#page-78了解了有关PRI方法的一些想法,其中表示以下内容-

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 ? 现在我的问题是,当服务器明显支持HTTP / 2时,为什么发送了PRI请求? 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? 我是否需要解析它并根据HTTP / 2规范用空的SETTINGS帧进行响应,还是应该使用Go http2运行时来处理它?

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). 我正在使用http.ReadRequest来解析客户端请求,但是即使我忽略PRI请求(如下所示),这对于HTTP / 2请求也似乎不起作用。

The first message a HTTP/2 client should send is this PRI message. HTTP / 2客户端应发送的第一条消息是此PRI消息。 From the HTTP/2 specification : 根据HTTP / 2规范

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. 在HTTP / 2中,要求每个端点发送连接序言作为对所使用协议的最终确认,并为HTTP / 2连接建立初始设置。 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: 客户端连接序言以24个八位位组的序列开头,十六进制表示为:

 0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a 

That is, the connection preface starts with the string PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n). 也就是说,连接序言以字符串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. 此序列之后必须是一个SETTINGS框架(第6.5节),该框架可以为空。

... ...

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. 注意 :选择客户端连接前言是为了使大部分HTTP / 1.1或HTTP / 1.0服务器和中介都不会尝试处理其他帧。

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. 该消息的重点是它是伪造的类似于HTTP / 1的消息,因此任何不支持HTTP / 2的服务器都应返回错误。

Any HTTP/2 server should expect this message to be sent, and then should just ignore it, and the carry on speaking HTTP/2. 任何HTTP / 2服务器都应该期望发送此消息,然后应该忽略它,并继续使用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. 客户端和服务器必须将无效的连接前言视为类型为PROTOCOL_ERROR的连接错误(第5.4.1节)。 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. 在这种情况下,可以忽略一个GOAWAY帧(第6.8节),因为无效的前言表示该对等体未使用HTTP / 2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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