AWS ALB 截断 HTTP 响应
AWS ALB Truncating HTTP response
我有一个带有目标组和 ECS 集群的 ALB 运行ning PHP API.
我正在尝试查询 API 以获取 CSV 响应,但如果请求来自 ALB,我将得到 t运行 分类结果。
当我通过 SSH 进入 EC2 实例 运行 连接集群并尝试 运行 手动卷曲(通过负载均衡器)时,响应得到 t运行cated:
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
我收到这些 headers:
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)
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
.
另一个区别是 Keep-Alive
选项。我不确定这是否是我可以在 ALB 上启用的属性。
当我尝试 return 不同的响应(复杂的网络 page/really 长)时,响应通过 ALB 没有问题(不是 t运行cated)。根据 ALB 启用 HTTP/1.1
时的错误消息,每次在 42568 字节后都会对响应进行 t运行 处理。
有什么想法吗?
更新
如果我在响应中遗漏 Content-Type
header,它不会得到 t运行。
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
return 正确响应。
您应该在您的 EC2 实例上启用 keep-alive。
You can enable HTTP keep-alive in the web server settings for your EC2
instances.
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#connection-idle-timeout
还要仔细检查 Content-Length header 是否准确。此处的大小不正确将导致您看到的错误。
经过愉快的调试,我在容器的 Nginx 日志中发现了这个:
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 配置中加入这两行基本上可以解决:
client_body_temp_path /tmp 1 2;
fastcgi_temp_path /tmp 1 2;
为什么仅 csv
输出会发生这种情况的问题仍然是个谜。
感谢您的帮助!
我有一个带有目标组和 ECS 集群的 ALB 运行ning PHP API.
我正在尝试查询 API 以获取 CSV 响应,但如果请求来自 ALB,我将得到 t运行 分类结果。
当我通过 SSH 进入 EC2 实例 运行 连接集群并尝试 运行 手动卷曲(通过负载均衡器)时,响应得到 t运行cated:
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
我收到这些 headers:
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)
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
.
另一个区别是 Keep-Alive
选项。我不确定这是否是我可以在 ALB 上启用的属性。
当我尝试 return 不同的响应(复杂的网络 page/really 长)时,响应通过 ALB 没有问题(不是 t运行cated)。根据 ALB 启用 HTTP/1.1
时的错误消息,每次在 42568 字节后都会对响应进行 t运行 处理。
有什么想法吗?
更新
如果我在响应中遗漏 Content-Type
header,它不会得到 t运行。
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
return 正确响应。
您应该在您的 EC2 实例上启用 keep-alive。
You can enable HTTP keep-alive in the web server settings for your EC2 instances. https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#connection-idle-timeout
还要仔细检查 Content-Length header 是否准确。此处的大小不正确将导致您看到的错误。
经过愉快的调试,我在容器的 Nginx 日志中发现了这个:
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 配置中加入这两行基本上可以解决:
client_body_temp_path /tmp 1 2;
fastcgi_temp_path /tmp 1 2;
为什么仅 csv
输出会发生这种情况的问题仍然是个谜。
感谢您的帮助!