Reputation: 1781
I stub with problem that when sending some requests to Django sever, it closes connection before time.
Here is simple project on Github
Here is how it works on simple POST request with no body:
But when I send some binary data, ~15MB in size, Postmen displays connection error:
But curl works fine
curl -X POST -d "@bin/ngrok" localhost:3000/test/
I thought this is some bug in Postman, but on mobile devices it does not work too;
I tried to compare request headers. I tried to toss middeware. I tryed to debug Djnago code. But I can find solution. Can you help me with this?
UPDATE 1
setting in settings.py file
FILE_UPLOAD_MAX_MEMORY_SIZE = 1000 * 1000 * 1000
DATA_UPLOAD_MAX_MEMORY_SIZE = 1000 * 1000 * 1000
does not fix issue
UPDATE 2
I added line print(len(request.body))
to index method:
@csrf_exempt
def index(request):
print(len(request.body))
return HttpResponse("Hello")
And now it works. But why should I refer body to complete request? In my real project I check authentication token and if it is wrong, I did not read something from body.
Upvotes: 4
Views: 1095
Reputation: 169032
Yup, I can reproduce this with your repo.
I took a look with Wireshark, and it looks like the Django devserver is actually responding before the entire payload has been sent. I'm not sure what the HTTP spec says about whether this is okay or not, but it's obvious some client libraries (that used by Postman and your mobile device) deem this an error, while others like libcurl are okay with it.
When you add print(len(request.body))
, it forces Django (and the underlying stack) to consume the entire body in order to figure out its length before outputting the response.
This behavior also occurs when running the app under uwsgi, for what it's worth.
The TCP stream looks like this in Wireshark:
Upvotes: 1
Reputation: 6379
I had the exact same issue several weeks ago for one of my projects on Heroku. The Heroku logs showed a not so helpful 'Server Request Interrupted' error. After days of debugging and looking into the django source code I found out it was related to django's Upload Handlers.
There is a setting called FILE_UPLOAD_MAX_MEMORY_SIZE which defaults to 2.5Mb. Any upload smaller than this setting will be handled by the MemoryFileUploadHandler (in memory), otherwise the TemporaryFileUploadHandler is responsible for file handling. I never found out why, but on Heroku the TemporaryFileUploadHandler always made my application crash. I created a workaround by increasing the setting to the max file size my client was going to upload.
Upvotes: 0