【问题标题】:curl post request is not working with option --http2, but it works fine when I use --http2-prior-knowledgecurl post请求不适用于选项--http2,但是当我使用--http2-prior-knowledge时它可以正常工作
【发布时间】:2019-03-30 00:10:06
【问题描述】:

我已经使用 tomcat 9.0.16、spring-boot 2.1.3.RELEASE、JDK1.8 创建了 spring-boot 应用程序。 当我使用 --http2 发出 curl 发布请求时,它说“curl: (56) Recv failure: Connection reset by peer”。

但是当我使用 --http-prior-knowledge 时它工作正常。

我的 application.property 文件

server.port=8080
server.http2.enabled=true

和配置文件

@Bean
    public WebServerFactoryCustomizer tomcatCustomizer() {
        return (container) -> {
            if (container instanceof TomcatServletWebServerFactory) {
                ((TomcatServletWebServerFactory) container)
                        .addConnectorCustomizers((connector) -> {
                            connector.addUpgradeProtocol(new Http2Protocol());
                        });
            }
        };
    }
  1. 对于 curl -vvv --http2 -H 'Content-Type: application/json' -H 'cache-control: no-cache' -XPOST http://localhost:8080/save -d '{"xyz":"xyz"}' curl的日志->
*   Trying ::1...
* TCP_NODELAY set
* Expire in 150000 ms for 3 (transfer 0x7fc78a808a00)
* Expire in 200 ms for 4 (transfer 0x7fc78a808a00)
* Connected to localhost (::1) port 8080 (#0)
> POST /save HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.64.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> Content-Type: application/json
> Postman-Token: 52e0708b-ce97-4baa-a567-2dabc675f3dd
> cache-control: no-cache
> Content-Length: 702
>
* upload completely sent off: 702 out of 702 bytes
< HTTP/1.1 101
< Connection: Upgrade
< Upgrade: h2c
< Date: Wed, 27 Mar 2019 12:29:18 GMT
* Received 101
* 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
* Connection state changed (MAX_CONCURRENT_STREAMS == 200)!
* Recv failure: Connection reset by peer
* Failed receiving HTTP2 data
* Send failure: Broken pipe
* Failed sending HTTP2 data
* Connection #0 to host localhost left intact
curl: (56) Recv failure: Connection reset by peer
  1. curl -vvv --http2-prior-knowledge -H 'Content-Type: application/json' -H 'Postman-Token: 52e0708b-ce97-4baa-a567-2dabc675f3dd' -H 'cache-control: no-缓存' -XPOST http://localhost:8080/save -d '{"xyz":"xyz"}'
* Expire in 0 ms for 6 (transfer 0x7fc5c0808a00)
*   Trying ::1...
* TCP_NODELAY set
* Expire in 150000 ms for 3 (transfer 0x7fc5c0808a00)
* Expire in 200 ms for 4 (transfer 0x7fc5c0808a00)
* Connected to localhost (::1) port 8080 (#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 0x7fc5c0808a00)
> POST /save HTTP/2
> Host: localhost:8080
> User-Agent: curl/7.64.0
> Accept: */*
> Content-Type: application/json
> Postman-Token: 52e0708b-ce97-4baa-a567-2dabc675f3dd
> cache-control: no-cache
> Content-Length: 702
>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS == 200)!
< HTTP/2 200
< content-type: application/json;charset=UTF-8
< date: Wed, 27 Mar 2019 12:32:26 GMT
<
* Connection #0 to host localhost left intact
true%

【问题讨论】:

    标签: spring-boot curl tls1.2 http2 tomcat9


    【解决方案1】:

    您不能使用 POST 方法执行 HTTP/1.1 升级,因此 Tomcat 可能会因为这个原因在您的第一个请求 (curl --http2 ...) 上阻塞。

    我是 Jetty 中的 HTTP/2 实现者,在这种情况下,Jetty 也不会升级到 HTTP/2,尽管它以 HTTP/1.1 200 响应请求,而不是阻塞。

    将第一个请求转换为没有内容的 GET,升级在 Jetty 中成功,并带有 HTTP/1.1 101 响应,正如预期的那样。

    第二个请求不是HTTP/1.1升级,而是先验知识HTTP/2请求;没有升级,因此对可以使用的 HTTP 方法没有限制,因此请求在 Jetty 和 Tomcat 中都成功。

    【讨论】:

    • 虽然这是公认的答案,而且非常正确,但这实际上是一个缺陷。 http2 规范不强制要求GET 请求h2c 升级。因此,从最初的 POST 请求升级是非常好的,也是应用程序开发人员所期望的(它是 works with netty)。
    猜你喜欢
    • 2017-03-07
    • 1970-01-01
    • 2015-08-29
    • 2023-04-06
    • 1970-01-01
    • 2018-09-03
    • 2018-07-28
    • 1970-01-01
    • 2021-08-07
    相关资源
    最近更新 更多