8000 [soc2009/http-wsgi-improvements] Establish the priorities and fallbac… · alex-python/django@94a94be · GitHub
[go: up one dir, main page]

Skip to content

Commit 94a94be

Browse files
committed
[soc2009/http-wsgi-improvements] Establish the priorities and fallbacks for HttpResponseSendFile methods.
Change the setting to settings.HTTPRESPONSE_SENDFILE_METHOD. If this is set to None, we use handler methods, but otherwise the header gets set, and we do not send any content. If neither of these are available, use the FileWrapper fallback in HttpResponseSendFile. This passes the test suite, but is untested on mod_python. I am still trying to figure out how to view the headers of a response with the Content-Disposition "attachment." git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/http-wsgi-improvements@11268 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent b0e3819 commit 94a94be

File tree

5 files changed

+28
-22
lines changed

5 files changed

+28
-22
lines changed

django/conf/global_settings.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,13 @@
236236
# Example: "http://media.lawrence.com"
237237
MEDIA_URL = ''
238238

239-
# Header to use in HttpResponseSendFile to inform the handler to serve the
240-
# file with efficient handler-specific routines.
241-
HTTPRESPONSE_SENDFILE_HEADER = 'X-Sendfile'
239+
# Header to use in HttpResponseSendFile to inform the handler to serve the
240+
# file with efficient handler-specific routines. None causes HttpResponseSendFile
241+
# to fall back to, first, mechanisms in the handler (wsgi.filewrapper and
242+
# req.sendfile.
243+
# Examples: 'X-Sendfile' (FastCGI, lighttpd, Apache with mod_xsendfile),
244+
# 'X-Accel-Redirect' (nginx)
245+
HTTPRESPONSE_SENDFILE_METHOD = None
242246

243247
# List of upload handler classes to be applied in order.
244248
FILE_UPLOAD_HANDLERS = (

django/core/handlers/modpython.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,15 @@ def __call__(self, req):
200200
for c in response.cookies.values():
201201
req.headers_out.add('Set-Cookie', c.output(header=''))
202202
req.status = response.status_code
203-
if isinstance(response, http.HttpResponseSendFile):
204-
req.sendfile(response.sendfile_filename)
203+
if isinstance(response, http.HttpResponseSendFile):
204+
req.sendfile(response.sendfile_filename)
205205
else:
206-
try:
207-
for chunk in response:
208-
req.write(chunk)
209-
finally:
210-
response.close()
211-
206+
# If we are using a header to do sendfile, set the header and send empty content
207+
if settings.RESPONSE_SENDFILE_METHOD:
208+
response.set_empty_content()
209+
response[settings.HTTPRESPONSE_SENDFILE_METHOD] = response.sendfile_filename
210+
for chunk in response:
211+
req.write(chunk)
212212
return 0 # mod_python.apache.OK
213213

214214
def handler(req):

django/core/handlers/wsgi.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,11 @@ def __call__(self, environ, start_response):
243243
start_response(status, response_headers)
244244

245245
if isinstance(response, http.HttpResponseSendFile):
246-
filelike = open(response.sendfile_filename, 'rb')
247-
if 'wsgi.file_wrapper' in environ:
246+
if settings.HTTPRESPONSE_SENDFILE_METHOD:
247+
response[settings.HTTPRESPONSE_SENDFILE_METHOD] = response.sendfile_filename
248+
elif 'wsgi.file_wrapper' in environ:
249+
filelike = open(response.sendfile_filename, 'rb')
248250
return environ['wsgi.file_wrapper'](filelike,
249-
response.block_size)
250-
else:
251-
# wraps close() as well
252-
from django.core.servers.basehttp import FileWrapper
253-
return FileWrapper(filelike, response.block_size)
254-
251+
response.block_size)
255252
return response
256253

django/http/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,14 @@ def __init__(self, path_to_file, content_type=None, block_size=8192):
447447
self['Content-Length'] = os.path.getsize(path_to_file)
448448
self['Content-Disposition'] = ('attachment; filename=%s' %
449449
os.path.basename(path_to_file))
450-
self[settings.HTTPRESPONSE_SENDFILE_HEADER] = path_to_file
450+
self._empty_content = False
451+
452+
def set_empty_content(self):
453+
self._empty_content = True
451454

452455
def __iter__(self):
456+
if self._empty_content:
457+
return iter([''])
453458
from django.core.servers.basehttp import FileWrapper
454459
return FileWrapper(self.get_file_handler(), self.block_size)
455460

tests/regressiontests/sendfile/tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ def test_sendfile(self):
1818
urllib.quote(file1.name))
1919

2020
self.assertEqual(response.status_code, 200)
21-
self.assertEqual(response[settings.HTTPRESPONSE_SENDFILE_HEADER],
22-
file1.name)
21+
#self.assertEqual(response[settings.HTTPRESPONSE_SENDFILE_METHOD],
22+
# file1.name)
2323
self.assertEqual(response['Content-Disposition'],
2424
'attachment; filename=%s' % os.path.basename(file1.name))
2525
self.assertEqual(response['Content-Length'], str(FILE_SIZE))

0 commit comments

Comments
 (0)
0