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

问题描述 投票:0回答:1

我正在尝试使用HTTP / 2扩展服务器,该服务器已经支持带有TLS v1.2的HTTP / 1.1。我在Go中写它,我在这里定义tls配置 -

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运行时是否应该处理它?

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

http go http2
1个回答
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开头)。该序列必须后跟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。

© www.soinside.com 2019 - 2024. All rights reserved.