Статья из разряда «заметки на полях».
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, но я-то знаю, что запрос я не прерывал! Начал ковырять, что же может пойти не так. А все оказалось очень просто:
listen 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 (или столько, сколько наверняка хватит) — решаем проблему.
Такие дела.
Автор: Porfel