atomAltera
atomAltera

Reputation: 1781

Django resets connection on some requests

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: enter image description here

But when I send some binary data, ~15MB in size, Postmen displays connection error: enter image description here

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

Answers (2)

AKX
AKX

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: enter image description here

Upvotes: 1

dentemm
dentemm

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

Related Questions