Django

Code

Ticket #5596 (closed: fixed)

Opened 8 months ago

Last modified 5 months ago

"No buffer space available" error when downloading file

Reported by: anonymous Assigned to: nobody
Component: HTTP handling Version: SVN
Keywords: Cc:
Triage Stage: Ready for checkin Has patch: 1
Needs documentation: 0 Needs tests: 0
Patch needs improvement: 1

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

static.diff (2.8 kB) - added by eibaan on 10/01/07 02:33:07.
chunk large files, make application/octet-stream the default

Change History

09/25/07 09:48:02 changed by calvin@debian.org

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

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.

10/01/07 02:32:05 changed by anonymous

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.

10/01/07 02:33:07 changed by eibaan

  • attachment static.diff added.

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

11/15/07 03:29:26 changed by mtredinnick

Why have you decided 2**25 is the right chunk size here?

11/15/07 04:42:09 changed by eibaan

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...

12/01/07 19:37:21 changed by Simon G <dev@simon.net.nz>

  • needs_better_patch set to 1.
  • has_patch set to 1.
  • stage changed from Unreviewed to Ready for checkin.

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

12/17/07 05:46:49 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(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.


Add/Change #5596 ("No buffer space available" error when downloading file)




Change Properties
Action