(تم التحديث ، لأنني أدركت أنني كنت أحاول إصلاح هذا ، لذا فقد ارتبكت بسبب المشكلة الأصلية والمشكلة التي جعلتني أستسلم)
أقوم بتقديم طلب مقسم إلى تطبيق يستخدم Werkzeug (git master الحالي). ينتهي get_input_stream باستدعاء LimitedStream(wsgi.input, min(content_length, max_content_length))
. min(content_length, max_content_length)
دائمًا في حالة استخدام الترميز المقسم.
في محاولة لإحراز تقدم ، حاولت استخدام LimitedStream(stream, content_length or max_content_length)
، ولكن انتهى بي الأمر بالحصول على استثناء ClientDisconnected
، لأننا لا نستطيع معرفة الفرق بين قطع اتصال العميل والطلب المقسم الذي يتم تنفيذه ببساطة ، حيث إن wsgi.input.read()
فقط بإرجاع سلسلة ذات طول 0 في كلتا الحالتين.
هذا أكثر من مجرد خطأ بسيط مع min
. بعد إصلاح ذلك ، تكمن المشكلة في أن عمل wsgi.input.read(max_content_length)
مع كتل Werkzeug إلى الأبد إذا كان هناك أقل من max_content_length
للقراءة. أو باستخدام Gunicorn ، الذي يدعم الأجزاء عن طريق التحليل والتخزين المؤقت للرسالة بأكملها ، يخرج الطول إلى أقل من max_content_length
، لذلك يعتقد LimitedStream
أن العميل غير متصل.
لقد اختبرت ذلك على Django فقط لأتأكد من أننا لا نفعل شيئًا غريبًا ، إنه يرى تيارًا فارغًا أيضًا.
إن أبسط طريقة للتقدم هي توفير برمجية وسيطة تعين environ['wsgi.input_terminated']
وتطلب من الناس استخدامها عند استخدام خادم يدعم النقل المقسم.
أي WSGI يدعم حاليًا input_terminated
؟ بعد النسخ طوال اليوم عند تصحيح أخطاء البيانات ، لماذا يكون الدفق فارغًا ثم إدراك أنه بسبب ترميز الدفق المتقطع ، لا يمكنني الآن العثور على أي شيء يدعم هذا: /
بالإضافة إلى التحقق من environ.get('wsgi.input_terminated')
يجب علينا أيضًا التحقق من environ.get('HTTP_TRANSFER_ENCODING') == 'chunked'
وفي هذه الحالة أيضًا إعادة التدفق غير المغلف مباشرةً؟ يعمل ذلك على إصلاح مشكلات مثل إرجاع curl -H 'Transfer-Encoding: chunked' ...
لتدفق فارغ.
لكل RFC2616
4.4.2
في حالة وجود حقل عنوان ترميز النقل (القسم 14.41) و
له أي قيمة بخلاف "الهوية" ، فإن طول التحويل هو
المعرفة من خلال استخدام ترميز النقل "المقسم" (القسم 3.6) ،
ما لم يتم إنهاء الرسالة عن طريق إغلاق الاتصال.
4.4.3
إذا كان حقل رأس طول المحتوى (القسم 14.13) موجودًا ، فسيكون
تمثل القيمة العشرية في OCTETs كلاً من طول الكيان و
طول النقل. يجب عدم إرسال حقل عنوان طول المحتوى
إذا كان هذان الطولان مختلفان (على سبيل المثال ، إذا كان ترميز النقل
حقل الرأس موجود). إذا تم استلام رسالة مع كل من ملف
حقل رأس ترميز النقل وحقل رأس طول المحتوى ،
يجب تجاهل الأخير.
... مع ملاحظة أن Transfer-Encoding
من chunked
يتطلب تجاهل أي رأس Content-Length
، وبالتالي لا يجب إجراء معالجة دفق بناءً عليه. هذا هو الحال حاليًا ما لم يتم تعيين wsgi.input_terminated
.
هل من الضروري حقًا تعيين wsgi.input_terminated
حتى يعمل الترميز المقسم العادي ، على سبيل المثال ، حمولة JSON ذات 10 بايت؟
التعليق الأكثر فائدة
أي WSGI يدعم حاليًا
input_terminated
؟ بعد النسخ طوال اليوم عند تصحيح أخطاء البيانات ، لماذا يكون الدفق فارغًا ثم إدراك أنه بسبب ترميز الدفق المتقطع ، لا يمكنني الآن العثور على أي شيء يدعم هذا: /