AWS ALB截断HTTP响应 [英] AWS ALB Truncating HTTP response

查看:239
本文介绍了AWS ALB截断HTTP响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个目标组和运行PHP API的ECS集群的ALB.

I have an ALB with a target group and ECS cluster running PHP API.

我正在尝试向API查询CSV响应,但是如果请求是通过ALB发送的,我会得到截断的结果.

I am trying to query the API for a CSV response but I am getting truncated results if the Request is coming through the ALB.

当我通过SSH进入运行集群的EC2实例并尝试手动运行curl(通过负载均衡器)时,响应将被截断:

When I SSH into the EC2 instance running the cluster and try to run curl manually (going through the load balancer) the response gets truncated:

curl -sSL -D - 'https://my.domain.com/api/export?token=foobar&start_date=01-01-2015&end_date=01-01-2019' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' -o /dev/null

我正在获取这些标题:

HTTP/2 200 
date: Wed, 21 Nov 2018 20:25:27 GMT
content-type: text/csv; charset=utf-8
content-length: 173019
server: nginx
content-transfer-encoding: binary
content-description: File Transfer
content-disposition: attachment;filename=export.csv
cache-control: private, must-revalidate
etag: "b90d0da7b482da96e1a478d59eedd0d16552fbfd"
strict-transport-security: max-age=2592000; includeSubDomains; preload
content-security-policy-report-only: default-src 'self';
x-frame-options: DENY
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
referrer-policy: origin

curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR (err 2)

如果我尝试对容器运行相同的卷曲(在本地运行-不通过ALB运行)

If I try to run the same curl against the container (running locally - not through ALB)

curl -sSL -D - 'http://localhost:32776/api/export?token=foobar&start_date=01-01-2015&end_date=01-01-2019' \
  -H 'Content-Type: application/json' \
  -H 'cache-control: no-cache' -o /dev/null

响应:

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/csv; charset=utf-8
Content-Length: 173019
Connection: keep-alive
Content-Transfer-Encoding: binary
Content-Description: File Transfer
content-disposition: attachment;filename=export.csv
Cache-Control: private, must-revalidate
Date: Wed, 21 Nov 2018 20:36:55 GMT
ETag: "b90d0da7b482da96e1a478d59eedd0d16552fbfd"
Strict-Transport-Security: max-age=2592000; includeSubDomains; preload
Content-Security-Policy-Report-Only: default-src 'self;
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Referrer-Policy: origin

当我比较它们时,HTTP版本有所不同.我尝试在ALB中切换到HTTP1,但仍然遇到相同(或相似)问题:curl: (18) transfer closed with 130451 bytes remaining to read.

When I compare them, there is a difference in the HTTP version. I tried switching to HTTP1 in ALB but still getting the same (or similar) issue: curl: (18) transfer closed with 130451 bytes remaining to read.

另一个区别是Keep-Alive选项.我不确定这是否是我可以在ALB上启用的属性.

Another difference is the Keep-Alive option. I am not sure if this is an attribute I can enable on the ALB.

当我尝试返回不同的响应(复杂的网页/很长)时,响应通过ALB顺利进行(未截断).根据错误消息,当启用ALB HTTP/1.1时,每次在42568字节之后响应都会被截断.

When I try to return a different response (complex web page/really long) the response goes through ALB without a problem (not truncated). According to the error message when ALB has HTTP/1.1 enabled the Response is truncated every time after 42568 bytes.

有什么想法吗?

更新

如果我在响应中省略了Content-Type标头,它不会被截断.

If I leave out the Content-Type header in the response, it doesn't get truncated.

return new Response($content, Response::HTTP_OK, [
    # Works without this:
    # 'Content-Type' => 'text/csv; charset=utf-8',
    'Content-Transfer-Encoding' => 'binary',
    'Content-Description' => 'File Transfer',
    'Content-Disposition' => "attachment;filename=export.csv",
    'Content-Length' => strlen($content),  
]);

更新2

将响应Content-Type更改为text/html可以正确返回响应.

Changing the response Content-Type to be text/html returns the response properly.

推荐答案

因此,经过一些愉快的调试之后,我在容器的Nginx日志中发现了这一点:

So after some joyful debugging, I found this in the Nginx logs from the container:

nginx stderr | 2018/11/22 01:03:59 [warn] 39#39: *65 an upstream response is 
buffered to a temporary file /var/tmp/nginx/fastcgi/4/01/0000000014 while reading 
upstream, client: 10.1.1.163, server: _, request: "GET /api/export?
token=foobar&start_date=01-01-2015&end_date=01-01-2019 HTTP/1.1", upstream: 
"fastcgi://unix:/var/run/php-fpm.sock:", host: "my.domain.com"

基本上可以通过将这两行烘焙到我的nginx配置中来解决:

Which can basically be solved by baking in these two lines into my nginx config:

client_body_temp_path /tmp 1 2;
fastcgi_temp_path /tmp 1 2;

为什么仅在csv输出中会发生这种问题仍然是个谜.

The question why was this happening only for csv output will remain a mystery.

感谢您的帮助!

这篇关于AWS ALB截断HTTP响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆