找不到这方面的工作示例(可以使用
curl -v --http2-prior-knowledge http://localhost:8081
命令检查),所以在这里询问。
curl -v --http2-prior-knowledge http://localhost:8081
* Trying 127.0.0.1:8081...
* Connected to localhost (127.0.0.1) port 8081 (#0)
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: http]
* h2h3 [:authority: localhost:8081]
* h2h3 [user-agent: curl/7.88.1]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x56425e0e6c80)
> GET / HTTP/2
> Host: localhost:8081
> user-agent: curl/7.88.1
> accept: */*
>
* HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
* Connection #0 to host localhost left intact
curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
我尝试使用https://github.com/hyperium/tonic/blob/master/examples/src/h2c/server.rs但它只是失败了
called `Result::unwrap()` on an `Err` value: hyper::Error(User(NoUpgrade))
在这条线上
let upgraded_io = hyper::upgrade::on(&mut req).await.unwrap();
当尝试与 Postman 连接时,使用 TLS(当然)会失败,如果没有它,它会显示
Received RST_STREAM with code 1
此服务器设计为在收到带有
Upgrade
标头的 HTTP/1.1 响应后接受 HTTP/2,因此您想要的 curl 命令行参数是 --http2
,而不是 --http2-prior-knowledge
。
一般来说,问题在于 HTTP/1.1 和 HTTP/2 使用完全不同的语法和框架,因此除非您的服务器完全仅使用 HTTP/2 并且绝对不执行 HTTP/1.1,否则您需要某种方法来确定您使用的语法重新使用。使用 TLS,您可以与 ALPN 协商 HTTP/2,但如果没有 TLS,您通常需要使用
Upgrade
方法。使用 --http2-prior-knowledge
表示这不是必需的,但在本例中是必需的。