这主要是出于好奇;说我有一个HTTP1.1兼容服务器。我没有资源,无法向该服务器添加完整的HTTP2支持。
仍然我希望通过告诉他们使用HTTP1.1来提供clients which open a connection with a HTTP2 connection preface(PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
)。请注意,这是关于do n't >>通过带有Upgrade
标头的HTTP1.1请求启动连接的客户端。
这是我想要实现的行为:
CLIENT SERVER | ------ http2 GET --> | | <----need http1 ---- | | ------ http1 GET --> | ... (normal http1 processing)
该规范包含错误代码
HTTP_1_1_REQUIRED (0xd)
,这听起来与我所需要的差不多。而且,从阅读的情况来看,该错误代码似乎在必要时用于降级连接(显然是TLS重新协商?)。但是我似乎似乎无法使它正常工作...
char const Http2EmptySettingsFrame[] = { // Frame Header 0, 0, 0, 0x4, 0, 0 & 0x7F, 0, 0, 0 }; char const Http2RstStreamFrame[] = { // Frame Header 0, 0, 4, // Length of frame content 0x3, // Type: RST_STREAM 0, // Flags 0 & 0x7F, 0, 0, 1, // Stream identifier 1 ; also tried with 0 // Frame content 0, 0, 0, 0xD // Error code (RST_STREAM frame) }; char const Http2GoAwayFrame[] = { // Frame Header 0, 0, 8, 0x7, 0, 0 & 0x7F, 0, 0, 0, 0 & 0x7F, 0, 0, 0, // GO_AWAY stream id 0, 0, 0, 0xD // GO_AWAY error code: HTTP_1_1_REQUIRED };
使用上面的代码和
fwrite(frame, sizeof(frame), 1, stdout)
在一个小的测试程序中,我创建了要发送到客户端的帧[(C0])。然后,我启动我的“服务器”:
./a.out > frame.bin
使用http2客户端,然后得到...
cat emptysettings.bin rststream.bin goaway.bin - | netcat -l -p 8888 -s 127.0.0.1
...或使用curl ...
# this was when just sending empty SETTINGS and RST_STREAM frame nghttp -v http://127.0.0.1:8888 [ 0.000] Connected [ 0.000] recv SETTINGS frame <length=0, flags=0x00, stream_id=0> (niv=0) [ 0.000] [INVALID; error=Protocol error] recv RST_STREAM frame <length=4, flags=0x00, stream_id=1> (error_code=HTTP_1_1_REQUIRED(0x0d)) [ 0.000] send SETTINGS frame <length=12, flags=0x00, stream_id=0> (niv=2) [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100] [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535] [ 0.000] send GOAWAY frame <length=34, flags=0x00, stream_id=0> (last_stream_id=0, error_code=PROTOCOL_ERROR(0x01), opaque_data(26)=[RST_STREAM: stream in idle]) [ERROR] request http://127.0.0.1:8888 failed: request HEADERS is not allowed Some requests were not processed. total=1, processed=0
...因此:我需要向客户端发起一个HTTP2连接以将其降级到HTTP1.1的方式发送给客户端什么响应?
发送curl -v --http2-prior-knowledge http://127.0.0.1:8888
* Trying 127.0.0.1:8888...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x16887f0)
> GET / HTTP/2
> Host: 127.0.0.1:8888
> User-Agent: curl/7.66.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 4294967295)!
* stopped the pause stream!
* Connection #0 to host 127.0.0.1 left intact
curl: (16) Error in the HTTP2 framing layer
(505 = HTTP/1.1 505 hmmm\n\n
)也无济于事...
这主要是出于好奇;说我有一个HTTP1.1兼容服务器。我没有资源/无法向该服务器添加完整的HTTP2支持。我还是想服务...
我需要向客户端发起http2连接以将其降级到HTTP1.1的发送给客户端什么响应?