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)
Change History (7)
comment:1 by , 17 years ago
comment:2 by , 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 , 17 years ago
Attachment: | static.diff added |
---|
chunk large files, make application/octet-stream the default
comment:4 by , 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 , 17 years ago
Has patch: | set |
---|---|
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Ready for checkin |
Marked as RFC, but might need a few tweaks to sizing etc as per Malcolm's comment
comment:6 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
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.