如何要求客户端将HTTP2连接降级到HTTP1.1
这主要是出于好奇;假设我有一台兼容HTTP1.1的服务器。我没有资源/无法向该服务器添加完整的HTTP2支持 我仍然希望能够通过告诉他们使用HTTP1.1来服务(如何要求客户端将HTTP2连接降级到HTTP1.1,http,http2,Http,Http2,这主要是出于好奇;假设我有一台兼容HTTP1.1的服务器。我没有资源/无法向该服务器添加完整的HTTP2支持 我仍然希望能够通过告诉他们使用HTTP1.1来服务(PRI*HTTP/2.0\r\n\r\nSM\r\n\r\n)。请注意,这是关于不使用带有升级头的HTTP1.1请求启动连接的客户端 这是我想要实现的行为: CLIENT SERVER | ------ http2 GET --> | | <----need http1 ---- |
PRI*HTTP/2.0\r\n\r\nSM\r\n\r\n
)。请注意,这是关于不使用带有升级
头的HTTP1.1请求启动连接的客户端
这是我想要实现的行为:
CLIENT SERVER
| ------ http2 GET --> |
| <----need http1 ---- |
| ------ http1 GET --> |
... (normal http1 processing)
在一个小测试程序中,使用上面的和fwrite(frame,sizeof(frame),1,stdout)
创建要发送到客户端的帧(/a.out>frame.bin
)。然后我启动我的“服务器”:
cat emptysettings.bin rststream.bin goaway.bin-| netcat-l-p 8888-s 127.0.0.1
使用http2客户端,我得到
#这是在发送空设置和RST#U流帧时发生的
nghttp-vhttp://127.0.0.1:8888
[0.000]已连接
[0.000]recv设置帧
(niv=0)
[0.000][无效;错误=协议错误]recv RST_流帧
(错误代码=需要HTTP_1_1_(0x0d))
[0.000]发送设置帧
(niv=2)
[设置\u最大\u并发\u流(0x03):100]
[设置\初始\窗口大小(0x04):65535]
[0.000]发送采空区框架
(最后一个\u流\u id=0,错误\u代码=协议\u错误(0x01),不透明\u数据(26)=[RST\u流:流处于空闲状态])
[错误]请求http://127.0.0.1:8888 失败:不允许请求标头
有些请求没有得到处理。总计=1,已处理=0
。。。或者使用卷曲
curl-v--http2先验知识http://127.0.0.1:8888
*正在尝试127.0.0.1:8888。。。
*TCP_节点集
*连接到127.0.0.1(127.0.0.1)端口8888(#0)
*使用HTTP2,服务器支持多用途
*连接状态已更改(HTTP/2已确认)
*升级后正在将流缓冲区中的HTTP/2数据复制到连接缓冲区:len=0
*使用流ID:1(易处理0x16887f0)
>GET/HTTP/2
>主持人:127.0.0.1:8888
>用户代理:curl/7.66.0
>接受:*/*
>
*连接状态已更改(最大并发流==4294967295)!
*停止暂停流!
*0到主机127.0.0.1的连接保持不变
curl:(16)HTTP2帧层中的错误
。。。因此:我需要向启动http2连接的客户端发送什么响应,以便他们将连接降级到HTTP1.1?
发送HTTP/1.1505 hmmm\n\n
(505=)也没有帮助
我需要向启动http2连接的客户端发送什么响应,以便他们将连接降级到HTTP1.1
我认为你想做的没有意义。首先,您为什么要接受HTTP/2连接?只要预先拒绝就行了。为什么实现HTTP/2只是为了说你不支持HTTP/2
但是,如果确实要这样做,则需要使用GOAWAY
帧和HTTP\u 1\u REQUIRED
错误代码关闭连接。您不能降级连接
为了给这个答案提供更多的背景知识,我们考虑了很多方法来确保在不支持HTTP/2的情况下不建立HTTP/2连接。基本上有3种建立HTTP/2连接的方法:
RST\u流
帧上使用错误代码HTTP\u 1\u REQUIRED
,旨在拒绝单个流,而不是整个连接。因此,需要WebSocket的客户端证书(HTTP/2-不支持)的请求(最初在HTTP/2下不支持,但)应该拒绝带有此错误代码、带有RST\u流和该错误代码的请求。连接应该保持在原位,以便可以发出任何其他兼容HTTP/2的请求。理论上,您可以用相同的方式拒绝每个流请求,但如果只为了对发送的每个请求说“请使用HTTP/1.1”,而费心建立HTTP/2连接,这似乎有点愚蠢和低效
如果要拒绝整个连接,则应不要使用RST\u流
frame(),而是使用GOAWAY
frame()。此GOAWAY
消息可以使用错误代码HTTP\u 1\u REQUIRED
。这将关闭整个连接,客户端将需要重新连接-在这一点上,如上所述,您不应该接受HTTP/2连接。无法降级连接。从技术上讲,它可以使用升级方法来实现这一点,但这只是一个建议,而不是命令
现在,让我们看看您的代码和错误:
0x3, // Type: RST_STREAM
0, // Flags
0 & 0x7F, 0, 0, 1, // Stream identifier 1 ; also tried with 0
首先,您不能在流0上使用RST\u STREAM
,因此您应该只在流id>0上发送此消息:
RST_流帧必须是asso
[INVALID; error=Protocol error] recv RST_STREAM frame <length=4, flags=0x00, stream_id=1>
(error_code=HTTP_1_1_REQUIRED(0x0d))