AWS ALB Усечение HTTP-ответа - PullRequest
       9

AWS ALB Усечение HTTP-ответа

0 голосов
/ 21 ноября 2018

У меня есть ALB с целевой группой и кластером ECS с PHP API.

Я пытаюсь запросить у API ответ CSV, но я получаю усеченные результаты, если запрос поступает через ALB.

Когда я запускаю SSH в экземпляре EC2, на котором работает кластер, и пытаюсь запустить curl вручную (через балансировщик нагрузки), ответ усекается:

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)

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.Я попытался переключиться на HTTP1 в ALB, но все еще получал ту же (или похожую) проблему: curl: (18) transfer closed with 130451 bytes remaining to read.

Другое отличие - опция Keep-Alive.Я не уверен, что это атрибут, который я могу включить в ALB.

Когда я пытаюсь вернуть другой ответ (сложная веб-страница / очень длинный), ответ проходит через ALB без проблем (не обрезается),Согласно сообщению об ошибке, когда ALB активировал HTTP/1.1, ответ усекается каждый раз после 42568 байт.

Есть идеи?

ОБНОВЛЕНИЕ

Если в ответе пропустить заголовок Content-Type, он не будет усечен.

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 наbe text/html возвращает ответ правильно.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Итак, после некоторой радостной отладки я обнаружил это в логах 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, останется загадкой.

Спасибо за помощь!

0 голосов
/ 22 ноября 2018

Вы должны включить поддержку активности на ваших экземплярах EC2.

Вы можете включить поддержку активности HTTP в настройках веб-сервера для ваших экземпляров EC2.https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#connection-idle-timeout

Также дважды проверьте правильность заголовка Content-Length.Неверный размер приведет к появившейся ошибке.

...