简体   繁体   中英

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: 在此输入图像描述

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.

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: 在此输入图像描述

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM