#29800: Django hangs when Content-Length has incorrect value
------------------------------------+------------------------------------
     Reporter:  Alexander Charykov  |                    Owner:  (none)
         Type:  Bug                 |                   Status:  new
    Component:  HTTP handling       |                  Version:  2.1
     Severity:  Normal              |               Resolution:
     Keywords:                      |             Triage Stage:  Accepted
    Has patch:  0                   |      Needs documentation:  0
  Needs tests:  0                   |  Patch needs improvement:  0
Easy pickings:  0                   |                    UI/UX:  0
------------------------------------+------------------------------------

Comment (by thenomadlad):

 Hi folks, I encountered a similar bug and since this thread was the only
 place I could see information on this bug I thought I'll share what I
 found after working around this issue

 TL;DR I think this is because of the way gunicorn uses the content-length
 header
 
[here](https://github.com/benoitc/gunicorn/blob/ab9c8301cb9ae573ba597154ddeea16f0326fc15/gunicorn/http/body.py#L128-L129)

 My service is a flask+gunicorn service in a kubernetes cluster. we have
 distributed tracing enabled at the flask layer and when I include a
 content-length header, I saw traces start and end at the load-balancer
 layer with a 400 status code after a 1s timeout, but no traces start for
 the flask application. Between the load-balancer and my flask app, I had a
 few places to look - the k8s-networking, docker-runtime, python 3.10 and
 gunicorn. Naturally my biggest suspect was gunicorn

 Gunicorn chooses different "readers" based on whether a `content-length`
 header is set, the `transfer-encoding` header has value `chunked`, or
 neither:
 
https://github.com/benoitc/gunicorn/blob/ab9c8301cb9ae573ba597154ddeea16f0326fc15/gunicorn/http/message.py#L125-L154

 if content-length is set, it uses a `LengthReader` is used, which loops
 infinitely until a certain length is reached:
 
https://github.com/benoitc/gunicorn/blob/ab9c8301cb9ae573ba597154ddeea16f0326fc15/gunicorn/http/body.py#L126-L130

 This is a feature of gunicorn, I think it relies on timing out when the
 reader doesn't have enough bytes

 > I cannot reproduce when Django is behind a reverse proxy such as NGINX
 with proxy_request_buffering on which is the default.
 I believe this might be happening because proxy_request_buffering adds a
 correct content-length header after buffering the request on the nginx
 side? not sure I have the tools to verify this tbh so I would appreciate
 it if someone can confirm this

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29800#comment:15>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018a7586c3c8-8b10df21-4042-4f16-8441-c63a47766b37-000000%40eu-central-1.amazonses.com.

Reply via email to