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

时间:2018-05-20 11:16:51

标签: http go http2

我正在尝试使用 HTTP / 2 扩展服务器,该服务器已经支持 HTTP / 1.1 TLS v1.2 。我是在 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,
            }

很明显,我使用“ h2 ”字符串来设置ALPN握手。

现在当我通过curl发出请求时,我收到了这个请求 -

$ curl -v https://127.0.0.1:8000 -k --http2

当我解析请求时,它会先显示 PRI 方法,而不是 GET -

HTTP/2.0
PRI

我对来自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. 

我现在的问题是,为什么发送了 PRI 请求,显然服务器支持 HTTP / 2 ?我是否需要根据HTTP / 2规范解析它并使用空的 SETTINGS 帧进行响应,或者Go http2运行时是否应该处理它?<​​/ p>

我使用http.ReadRequest来解析客户端请求,但即使忽略 PRI 请求,这似乎也不适用于 HTTP / 2 请求(如下所述)。

1 个答案:

答案 0 :(得分:2)

HTTP / 2客户端应发送的第一条消息是此PRI消息。来自HTTP/2 specification

  

在HTTP / 2中,每个端点都需要发送连接前言作为正在使用的协议的最终确认,并建立HTTP / 2连接的初始设置。客户端和服务器各自发送不同的连接前言。

     

客户端连接前言以24个八位字节的序列开头,以十六进制表示法为:

0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
     

也就是说,连接前言以字符串PRI * HTTP / 2.0 \ r \ n \ r \ nSM \ r \ n \ n \ n \ n \ n开头)。这个序列必须跟一个SETTINGS框(第6.5节),它可以是空的。

     

...

     

注意:选择客户端连接前言,以便大部分HTTP / 1.1或HTTP / 1.0服务器和中介不会尝试处理更多帧。

此消息的要点是它是一个伪HTTP / 1类型的消息,因此任何不支持HTTP / 2的服务器都应该响应错误。

任何HTTP / 2服务器都应该发送此消息,然后应该忽略它,并继续说HTTP / 2.

实际上,如果未发送此消息,则服务器应将此视为错误而不是继续:

  

客户端和服务器必须将无效的连接前言视为PROTOCOL_ERROR类型的连接错误(第5.4.1节)。在这种情况下可以省略GOAWAY帧(第6.8节),因为无效的前言表明对等方没有使用HTTP / 2.