【问题标题】:Getting "curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)"获取“卷曲:(92)HTTP/2 流 1 未完全关闭:INTERNAL_ERROR(错误 2)”
【发布时间】:2019-06-02 08:09:10
【问题描述】:

我有一个 Django 应用程序,它在调用 API 时返回一个大的 JSON。 问题是当我请求数据时,数据本身被截断,导致前端崩溃。

我将云前端用于 DNS 和 SSL 以及它们提供的其他功能以进行缓存和提高性能。

我尝试 curl API 并从 curl 中得到以下错误:

curl: (92) HTTP/2 流 1 未完全关闭:INTERNAL_ERROR (err 2)

我尝试禁用 Cloudflare,但没有成功。但是,在我的本地主机上,一切正常。

HTTP/2 流 1 未完全关闭:INTERNAL_ERROR (err 2)

  • 关闭连接 0
  • TLSv1.2 (OUT)、TLS 警报、客户端问候 (1):curl:(92) HTTP/2 流 1 未完全关闭:INTERNAL_ERROR (err 2)

JSON 应该被完全提取而不被分块。

【问题讨论】:

  • 通过在 nginx 中将 proxy_buffering 设置为 false 来修复

标签: django amazon-web-services rest curl cloudflare


【解决方案1】:

我在使用 AWS 的 Application Load Balancer (ALB) 时遇到了这个问题。这个问题是我将 Apache 配置为使用 http2,但在 ALB 之后。 ALB 默认支持 http2:

Application Load Balancer 通过 HTTPS 侦听器为 HTTP/2 提供本机支持。您可以使用一个 HTTP/2 连接并行发送多达 128 个请求。负载均衡器将这些转换为单独的 HTTP/1.1 请求,并将它们分布在目标组中的健康目标上。由于 HTTP/2 更有效地使用前端连接,您可能会注意到客户端和负载均衡器之间的连接更少。你不能使用 HTTP/2 的 server-push 特性。 1

因此,curl 使用 HTTP/2 与 ALB 连接,然后将其转换为 HTTP/1 请求。 Apache 正在向响应中添加标头,要求客户端将 Upgrade 发送到 HTTP/2,ALB 刚刚将其传递回客户端,并且 curl 将其读取为无效,因为它已经在使用 HTTP/2 连接。我通过在我的 Apache 实例上禁用 HTTP/2 解决了这个问题。因为它总是在 ALB 之后,而且 ALB 永远不会使用 HTTP/2,所以没有它的意义。

【讨论】:

  • 经过数小时调试对 NLB 的 curl 调用错误后,我终于发现这是由于我的后端服务器上禁用了 HTTP/2。非常感谢!
【解决方案2】:

我在 AWS 应用程序负载均衡器后面的应用程序中遇到了同样的错误,使用命令:

curl "https://console.aws.example/api/xxx" -b "SESSION=$SESSION"
                                                                         

15:14:30 curl:(92)HTTP/2 流 1 未完全关闭: PROTOCOL_ERROR(错误 1)

我不得不强制使用带有参数--http1.1HTTP/1.1

所以最后的命令是:

curl "https://console.aws.example/api/xxx" -b "SESSION=$SESSION" --http1.1

【讨论】:

  • 这行得通!非常感谢!但现在我得到“服务不可用”而不是 curl 错误消息...o_O
  • 而且有时我仍然会收到旧的错误消息;/ - 我在服务器上使用 uvicorn,但不确定我是否正确配置它(我使用 curl 来测试我的服务器)
  • 计算资源不足也会触发这个curl问题吗?
【解决方案3】:

修复或删除 HTTP 请求中的 Content-Length 标头。

当我遇到此问题时,我正在尝试连接到 AWS 网关。我能够使用 POSTMAN 获得正确的响应,但如果我将相同的标题复制到 curl,它会给我这个错误。

最后对我有用的是删除 Content-Length 标头,因为 curl 中的请求长度与 POSTMAN 中的不匹配。

因为我只是在测试 API,所以这很好,但我不建议在生产中删除此标头。如果您在代码库中发生这种情况,请检查以确保长度计算正确。

【讨论】:

    【解决方案4】:

    使用 Nginx,您可以通过让两个 http2 虚拟主机侦听相同的服务器名称来在 curl 中遇到此错误。对你的 nginx 配置文件运行检查会抛出一个警告,让你知道有些事情是不对的。修复/删除重复列表可解决此问题。

    # nginx -t
    nginx: [warn] conflicting server name "example.com" on 0.0.0.0:443, ignored
    nginx: [warn] conflicting server name "example.com" on [::]:443, ignored
    

    【讨论】:

      猜你喜欢
      • 2021-08-03
      • 2021-10-25
      • 2020-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-07
      • 2021-04-29
      • 2021-12-09
      相关资源
      最近更新 更多