Werkzeug: Permintaan yang dipotong masih tidak benar-benar berfungsi

Dibuat pada 16 Jul 2017  ·  4Komentar  ·  Sumber: pallets/werkzeug

(Diperbarui, karena saya menyadari bahwa saya telah mencoba untuk memperbaikinya, jadi bingung dengan masalah asli dan masalah yang membuat saya menyerah)

Saya membuat permintaan terpotong ke aplikasi yang menggunakan Werkzeug (master git saat ini). get_input_stream akhirnya memanggil LimitedStream(wsgi.input, min(content_length, max_content_length)) . min(content_length, max_content_length) akan selalu menjadi Tidak Ada jika menggunakan penyandian terpotong.

Dalam upaya untuk membuat kemajuan, saya mencoba menggunakan LimitedStream(stream, content_length or max_content_length) , tetapi kemudian saya akhirnya mendapatkan pengecualian ClientDisconnected , karena kami tidak dapat membedakan antara pemutusan klien dan permintaan yang dipotong hanya dilakukan , karena wsgi.input.read() baru saja mengembalikan string 0-panjang dalam kedua kasus.

bug

Komentar yang paling membantu

wsgi mana yang saat ini mendukung input_terminated ? Setelah membakar sepanjang hari pada debugging mengapa data kosong, lalu mengapa aliran kosong kemudian menyadari itu karena pengkodean aliran yang terpotong Saya sekarang tidak dapat menemukan apa pun yang mendukung ini:/

Semua 4 komentar

Ini lebih dari sekedar bug sederhana dengan min . Setelah memperbaikinya, masalahnya adalah melakukan wsgi.input.read(max_content_length) dengan Werkzeug memblokir selamanya jika ada kurang dari max_content_length untuk dibaca. Atau menggunakan Gunicorn, yang mendukung potongan dengan mem-parsing dan buffering seluruh pesan, panjangnya kurang dari max_content_length , jadi LimitedStream menganggap klien terputus.

Saya menguji ini di Django hanya untuk memastikan kami tidak melakukan sesuatu yang aneh, ia juga melihat aliran kosong.

Cara paling sederhana ke depan adalah menyediakan middleware yang menetapkan environ['wsgi.input_terminated'] dan memberitahu orang-orang untuk menggunakannya saat menggunakan server yang mendukung transfer chunked.

wsgi mana yang saat ini mendukung input_terminated ? Setelah membakar sepanjang hari pada debugging mengapa data kosong, lalu mengapa aliran kosong kemudian menyadari itu karena pengkodean aliran yang terpotong Saya sekarang tidak dapat menemukan apa pun yang mendukung ini:/

Selain memeriksa environ.get('wsgi.input_terminated') haruskah kita juga memeriksa environ.get('HTTP_TRANSFER_ENCODING') == 'chunked' dan dalam hal ini juga mengembalikan aliran yang belum dibuka secara langsung? Itu memperbaiki masalah seperti curl -H 'Transfer-Encoding: chunked' ... mengembalikan aliran kosong.

Per RFC2616

4.4.2
Jika bidang header Transfer-Encoding (bagian 14.41) ada dan
memiliki nilai selain "identitas", maka panjang transfer adalah
didefinisikan dengan menggunakan pengkodean transfer "potong" (bagian 3.6),
kecuali pesan diakhiri dengan menutup koneksi.

4.4.3
Jika bidang header Panjang Konten (bagian 14.13) ada,
nilai desimal dalam OCTET mewakili panjang entitas dan
panjang transfer. Bidang header Panjang Konten TIDAK HARUS dikirim
jika kedua panjang ini berbeda (yaitu, jika Transfer-Encoding
bidang tajuk ada). Jika sebuah pesan diterima dengan kedua a
Bidang header Transfer-Encoding dan bidang header Content-Length,
yang terakhir HARUS diabaikan.

... mencatat bahwa Transfer-Encoding dari chunked menuntut agar header Content-Length diabaikan, sehingga tidak ada pemrosesan streaming yang harus dilakukan berdasarkan header wsgi.input_terminated disetel.

Haruskah benar-benar diperlukan untuk mengatur wsgi.input_terminated agar pengkodean chunked normal misalnya payload JSON 10 byte berfungsi?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat