1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

[soc2009/http-wsgi-improvements] HttpResponseSendFile now uses django.core.servers.basehttp.FileWrapper inside __iter__ to provide fallback.

regressiontests.sendfile uses this now, and passes. The fallback was tested
using guppy and apache2 with mod_wsgi for heap issues, and it appears to be
fine. We can go back and look at this again if it becomes an issue.

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/http-wsgi-improvements@11212 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Chris Cahoon 2009-07-10 19:02:34 +00:00
parent 9eab31193a
commit ab67a69ec6
2 changed files with 13 additions and 6 deletions

View File

@ -430,6 +430,8 @@ class HttpResponse(object):
return sum([len(chunk) for chunk in self._container]) return sum([len(chunk) for chunk in self._container])
class HttpResponseSendFile(HttpResponse): class HttpResponseSendFile(HttpResponse):
sendfile_fh = None
def __init__(self, path_to_file, content_type=None, block_size=8192): def __init__(self, path_to_file, content_type=None, block_size=8192):
if not content_type: if not content_type:
from mimetypes import guess_type from mimetypes import guess_type
@ -445,10 +447,14 @@ class HttpResponseSendFile(HttpResponse):
os.path.basename(path_to_file)) os.path.basename(path_to_file))
self[settings.HTTPRESPONSE_SENDFILE_HEADER] = path_to_file self[settings.HTTPRESPONSE_SENDFILE_HEADER] = path_to_file
def _get_content(self): def __iter__(self):
return open(self.sendfile_filename).read() from django.core.servers.basehttp import FileWrapper
return FileWrapper(self.get_file_handler(), self.block_size)
content = property(_get_content) def get_file_handler(self):
if not self.sendfile_fh:
self.sendfile_fh = open(self.sendfile_filename, 'rb')
return self.sendfile_fh
class HttpResponseRedirect(HttpResponse): class HttpResponseRedirect(HttpResponse):
_status_code = 302 _status_code = 302

View File

@ -25,10 +25,11 @@ class SendFileTests(TestCase):
self.assertEqual(response['Content-Length'], str(FILE_SIZE)) self.assertEqual(response['Content-Length'], str(FILE_SIZE))
self.assertEqual(response['Content-Type'], 'application/pdf') self.assertEqual(response['Content-Type'], 'application/pdf')
# *if* the degraded case is to be supported, add this instead: # Test the fallback file transfer -- we use FileWrapper to iterate through
self.assertEqual(response.content, CONTENT) # the file, this also wraps close(). This appears to mitigate performance
# issues.
self.assertEqual("".join(iter(response)), CONTENT)
get_content = lambda: response.content.read() get_content = lambda: response.content.read()
#self.assertRaises(TypeError, get_content)
file1.close() file1.close()
# TODO: test middleware bypass etc # TODO: test middleware bypass etc