(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.
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?
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:/