[Nginx] Як перемогти response_status = 0

Стаття із розряду «нотатки на полях».

TL: DR:

http2_max_field_size 8k; # всех спасет!

На одному з проектів, після зміни деякої внутрішньої логіки бекенда, почав спостерігати дивний response_code у логах, а саме 0. У логах виглядає приблизно так:

{
  "timestamp": "2020-01-17T08:41:51+00:00",
  "remote_addr": "zzz.zzz.zzz.zzz",
  "request_time": 0,
  "upstream_response_time": "",
  "upstream_header_time": "",
  "http_accept_language": "-language",
  "response_status": 0,
  "request": "",
  "host": "example.com",
  "upstream_addr": "",
  "http_referrer": "",
  "request_length": 5854,
  "bytes_sent": 0,
  "http_user_agent": ""
}


Читання документації і гугление на цю тему дало зовсім нічого — т.к. стверджується, що така поведінка виникає, коли клієнт закрив з'єднання, не передавши заголовки. Та й різна екзотика з розміром буффера для wsgi_, що в нашому випадку не підходило від слова «ніяк».

Загалом вирішили, що проблема — не проблема, з огляду на те, що на наших обсягах вона абсолютно не критична.

Рівно до того моменту, поки мене не збентежили наступною проблемою: в деяких випадках посилання без проблем відкриваються http, але зовсім відмовляються працювати по https, видаючи чудове: Connection #0 to host example.com left intact
curl: (52) Empty reply from server

У логах відстежити цю штуку вдалося тільки по IP - ні реквеста, ні якихось інших даних, як видно з прикладу вище, - немає. Тільки горезвісний статус 0, але я знаю, що запит я не переривав! Почав колупати, що може піти не так. А все виявилося дуже просто:

слухати 443 ssl http2 backlog = 8192;

Ну так ось - якщо використовувати http2 для ssl-з'єднань, то недостатньо просто конфігурувати буфери запиту, конфігурувати їх треба і в ngx_http_v2_module, а саме:

Синтаксис:	http2_max_field_size размер;
Умолчание:	http2_max_field_size 4k;
Контекст:	http, server

Обмежує максимальний розмір заголовка запиту, стисненого за допомогою HPACK. Обмеження застосовується однаково як до імені, і до значення. Якщо застосовується кодування Хаффмана, то фактичний розмір розпакованих рядків імені та значення може бути більшим. Обмеження за замовчуванням підходить для більшості запитів.

Загалом це воно. А чому? Тому що довжина посилання була великою – більше, ніж ті самі 4k.

Виставивши його в, наприклад, 8kb (або стільки, скільки, напевно, вистачить) — вирішуємо проблему.
Такі справи.

Джерело: habr.com

Додати коментар або відгук