[Nginx] Wie man response_status = 0 besiegt

Ein Artikel der Gattung „Notizen am Rande“.

TL:DR:

http2_max_field_size 8k; # wird alle retten!

In einem der Projekte begann ich, nach einer Änderung der internen Logik im Backend einen seltsamen response_code in den Logs zu beobachten, nämlich — 0. In den Logs sieht es ungefähr so aus:

{
  "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": ""
}


Das Lesen der Dokumentation und das Googeln zu diesem Thema hat genau nichts ergeben — da behauptet wird, dass solches Verhalten auftritt, wenn der Client die Verbindung schließt, ohne die Header zu übermitteln. Und es gibt verschiedene Exoten beim Umfang des Buffers für wsgi_, die in unserem Fall überhaupt nicht passten.

Insgesamt entschieden wir, dass das Problem — kein Problem ist, wenn man bedenkt, dass es bei unseren Volumina völlig unkritisch ist.

Genau bis zu dem Moment, als ich mit dem nächsten Problem konfrontiert wurde: In einigen Fällen öffneten Links problemlos über http, weigerten sich jedoch völlig, über https zu funktionieren, und lieferten das wunderbare: Connection #0 to host example.com left intact
curl: (52) Leere Antwort vom Server

In den Logs konnte ich dieses Problem nur über die IP nachverfolgen — keine Anfrage und keine weiteren Daten, wie aus dem obigen Beispiel ersichtlich — vorhanden. Nur der berüchtigte Status 0, aber ich weiß, dass ich die Anfrage nicht abgebrochen habe! Ich begann zu stöbern, was falsch laufen könnte. Und alles stellte sich als sehr einfach heraus:

listen 443 ssl http2 backlog=8192;

Also — wenn man http2 für ssl-Verbindungen verwendet, reicht es nicht aus, nur die Anfrage-Puffer zu konfigurieren, man muss sie auch im ngx_http_v2_module konfigurieren, nämlich:

Syntax:	http2_max_field_size Größe;
Vorgabe:	http2_max_field_size 4k;
Kontext:	http, server

Begrenzt die maximale Größe des Anforderungsheaders, der mit HPACK komprimiert wurde. Die Begrenzung gilt sowohl für den Namen als auch für den Wert. Wenn Huffman-Codierung verwendet wird, kann die tatsächliche Größe der entpackten Namens- und Wert-Strings größer sein. Die Standardgrenze eignet sich für die meisten Anfragen.

Im Grunde ist das alles. Und warum? Weil die Länge des Links groß war — größer als die besagten 4k.

Wenn man ihn beispielsweise auf 8kb (oder so viel, wie sicher ausreicht) festlegt, löst man das Problem.
So ist das.

Quelle: habr.com

60GB SSD 8Gb DDR4