#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.