I'm doing a HTTP POST request against a nginx->gunicorn->Django app. Response body comes back quickly, but the request doesn't finish completely for about 60 more seconds.
By "finish completely" I mean that various clients I've tried (Chrome, wget, Android app I'm building) indicate that request is still in progress, as if waiting for more data. Listening in from Wireshark I see that all data arrives quickly, then after 60 seconds ACK FIN finally comes.
The same POST request on local development server (./manage.py runserver
) executes quickly. Also, it executes quickly against gunicorn directly, bypassing nginx. Also works quickly in Apache/mod_wsgi setup.
GET requests have no issues. Even other POST requests are fine. One difference I'm aware of is that this specific request returns 201 not 200.
I figure it has someting to do with Content-Length
headers, closed vs keepalive connections, but don't yet know how things are supposed to work correctly.
- Backend server (gunicorn) is currently closing connections, this makes sense.
- Should backend server include
Content-Length header
, orTransfer-encoding: chunked
? Or should nginx be able to cope without these, and add them as needed? - I assume connection keep-alive is good to have, and should not be disabled in nginx.
Update: Setting keepalive_timeout
to 0 in nginx.conf
fixes my problem. But, of course, keep-alive is gone. I'm still not sure what's the issue. Probably something in the stack (my Django app or gunicorn) doesn't implement chunked transfer correctly, and confuses clients.