Opened 17 years ago

Closed 17 years ago

#5596 closed (fixed)

"No buffer space available" error when downloading file

Reported by: anonymous Owned by: nobody
Component: HTTP handling Version: dev
Severity: Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Development server with django.views.static.serve route, file has 235949884 bytes. When trying to access the file, I get the following error:

Traceback (most recent call last):
  File "D:\Python25\lib\site-packages\django\core\servers\basehttp.py", line 279, in run 
    self.finish_response()
  File "D:\Python25\lib\site-packages\django\core\servers\basehttp.py", line 318, in finish_response
    self.write(data)
  File "D:\Python25\lib\site-packages\django\core\servers\basehttp.py", line 402, in write
    self._write(data)
  File "D:\Python25\lib\socket.py", line 263, in write
    self.flush()
  File "D:\Python25\lib\socket.py", line 250, in flush
    self._sock.sendall(buffer)
error: (10055, 'No buffer space available')

Django seems to be able to read and write the file. In flush() in socket.py the final buffer to flush has the correct size. Please tell me that this isn't a general Python error. It should be possible to write a 230MB file into a socket. Still, it might be better if serve() would *not* try to read in everything at once and then write everything but stream the file in smaller chunks.

Attachments (1)

static.diff (2.8 KB ) - added by eibaan 17 years ago.
chunk large files, make application/octet-stream the default

Download all attachments as: .zip

Change History (7)

comment:1 by calvin@…, 17 years ago

Do you mean Django attempts to write ~230MB of data at once via socket.sendall()? That would indeed be a bad idea. You should split the data up in smaller chunks (say 64KB or so) before writing to a network socket. I notice that such a comment is already in basehttp.py:402, so that might be a known problem.

comment:2 by anonymous, 17 years ago

Yes, but it's not me but the django.views.static.serve() function. I created a patch (including test cases) to work around the problem. Hopefully, this problem will not occur on a production server which will not use the above function to serve static files. Still, it should work in development mode, too.

When writing the test, I noticed that files with unknown file extensions are served as text/html. A better default would IMHO be application/octet-stream, so I changed this, too. As both changes are in the same files, I didn't really know how to split the patch.

by eibaan, 17 years ago

Attachment: static.diff added

chunk large files, make application/octet-stream the default

comment:3 by Malcolm Tredinnick, 17 years ago

Why have you decided 225 is the right chunk size here?

comment:4 by eibaan, 17 years ago

It seems to be a nice value :) 32 MB is large enough so that for typical usage the optimization doesn't kick in and we stay backward compatible. Uploading 32 MB is still fast and doesn't seem to stress the Python garbage collector too much. Using 16 MB or even less as threshold would be fine with me...

comment:5 by Simon G <dev@…>, 17 years ago

Has patch: set
Patch needs improvement: set
Triage Stage: UnreviewedReady for checkin

Marked as RFC, but might need a few tweaks to sizing etc as per Malcolm's comment

comment:6 by Malcolm Tredinnick, 17 years ago

Resolution: fixed
Status: newclosed

(In [6939]) Fixed #5596 -- Changed the static view for the development server so that Django doesn't crash if somebody tries to serve a 200MB file. Patch from eibaan.

Note: See TracTickets for help on using tickets.
Back to Top