Werkzeug: Aufgeteilte Anfragen funktionieren immer noch nicht wirklich

Erstellt am 16. Juli 2017  ·  4Kommentare  ·  Quelle: pallets/werkzeug

(Aktualisiert, weil mir klar wurde, dass ich versucht hatte, dies zu beheben, also war ich verwirrt über das ursprüngliche Problem und das Problem, das mich aufgeben ließ)

Ich stelle eine unterteilte Anfrage an eine App, die Werkzeug (aktueller Git-Master) verwendet. get_input_stream ruft schließlich LimitedStream(wsgi.input, min(content_length, max_content_length)) . min(content_length, max_content_length) wird immer None sein, wenn Chunked Codierung verwendet wird.

Um Fortschritte zu machen, habe ich versucht, LimitedStream(stream, content_length or max_content_length) , aber dann erhalte ich eine ClientDisconnected Ausnahme, weil wir den Unterschied zwischen einem Client, der die Verbindung trennt, und der einfach ausgeführten Anfrage nicht erkennen können , da wsgi.input.read() in beiden Fällen nur einen String der Länge 0 zurückgibt.

bug

Hilfreichster Kommentar

Welche wsgi unterstützt derzeit input_terminated ? Nachdem ich den ganzen Tag beim Debuggen gebrannt habe, warum die Daten leer sind, warum dann der Stream leer ist, und dann erkannt habe, dass es an der Chunked-Stream-Codierung liegt, kann ich jetzt nichts finden, was dies unterstützt :/

Alle 4 Kommentare

Dies ist mehr als nur der einfache Fehler mit min . Nachdem das behoben wurde, besteht das Problem darin, dass wsgi.input.read(max_content_length) mit Werkzeugblöcken ausgeführt wird, wenn weniger als max_content_length zu lesen sind. Oder wenn Gunicorn verwendet wird, das Chunks durch das Parsen und Puffern der gesamten Nachricht unterstützt, beträgt die Länge weniger als max_content_length , also denkt LimitedStream dass der Client die Verbindung getrennt hat.

Ich habe dies auf Django getestet, nur um sicherzustellen, dass wir nicht etwas Seltsames tun, es sieht auch einen leeren Stream.

Der einfachste Weg besteht darin, eine Middleware bereitzustellen, die environ['wsgi.input_terminated'] festlegt und die Benutzer anweist, sie zu verwenden, wenn ein Server verwendet wird, der Chunked Transfer unterstützt.

Welche wsgi unterstützt derzeit input_terminated ? Nachdem ich den ganzen Tag beim Debuggen gebrannt habe, warum die Daten leer sind, warum dann der Stream leer ist, und dann erkannt habe, dass es an der Chunked-Stream-Codierung liegt, kann ich jetzt nichts finden, was dies unterstützt :/

Sollten wir zusätzlich zur Überprüfung von environ.get('wsgi.input_terminated') auch environ.get('HTTP_TRANSFER_ENCODING') == 'chunked' überprüfen und in diesem Fall auch den unverpackten Stream direkt zurückgeben? Das behebt Probleme wie ein einfaches curl -H 'Transfer-Encoding: chunked' ... , das einen leeren Stream zurückgibt.

Gemäß RFC2616

4.4.2
Wenn ein Transfer-Encoding-Header-Feld (Abschnitt 14.41) vorhanden ist und
einen anderen Wert als "identity" hat, dann ist die Übertragungslänge
definiert durch die Verwendung der "chunked" Transfer-Codierung (Abschnitt 3.6),
es sei denn, die Nachricht wird durch Schließen der Verbindung beendet.

4.4.3
Wenn ein Kopfzeilenfeld mit Inhaltslänge (Abschnitt 14.13) vorhanden ist, ist es
Dezimalwert in OCTETs repräsentiert sowohl die Entitätslänge als auch die and
Übertragungslänge. Das Header-Feld Content-Length DARF NICHT gesendet werden
wenn diese beiden Längen unterschiedlich sind (dh wenn ein Transfer-Encoding
Header-Feld ist vorhanden). Wenn eine Nachricht sowohl mit a
Kopfzeilenfeld Transfer-Encoding und ein Kopfzeilenfeld Content-Length,
letzteres MUSS ignoriert werden.

... Beachten Sie, dass Transfer-Encoding von chunked erfordert, dass jeder Content-Length Header ignoriert wird, und daher sollte keine Stream-Verarbeitung basierend darauf erfolgen. Dies ist derzeit der Fall, es sei denn, wsgi.input_terminated ist festgelegt.

Sollte es wirklich notwendig sein, wsgi.input_terminated zu setzen, damit normales chunked Encoding zB von 10 Byte JSON Payload funktioniert?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen