Skip to content

Commit 9ac495a

Browse files
committed
[soc2009/http-wsgi-improvements] Changes for HttpResponseSendFile support in FastCGI. Refs django#2131.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/http-wsgi-improvements@11319 bcc190cf-cafb-0310-a4f2-bffc1f526a37
1 parent c6322f0 commit 9ac495a

File tree

6 files changed

+26
-12
lines changed

6 files changed

+26
-12
lines changed

django/conf/global_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@
240240
# file with efficient handler-specific routines. None causes HttpResponseSendFile
241241
# to fall back to, first, mechanisms in the handler (wsgi.filewrapper and
242242
# req.sendfile.
243-
# Examples: 'X-Sendfile' (FastCGI, lighttpd, Apache with mod_xsendfile),
243+
# Examples: 'X-Sendfile' (lighttpd & Cherokee with FastCGI/SCGI, Apache with mod_xsendfile),
244244
# 'X-Accel-Redirect' (nginx)
245-
HTTPRESPONSE_SENDFILE_METHOD = None
245+
HTTPRESPONSE_SENDFILE_HEADER = None
246246

247247
# List of upload handler classes to be applied in order.
248248
FILE_UPLOAD_HANDLERS = (

django/core/handlers/modpython.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ def __call__(self, req):
204204
req.sendfile(response.sendfile_filename)
205205
else:
206206
# If we are using a header to do sendfile, set the header and send empty content
207-
if settings.RESPONSE_SENDFILE_METHOD:
207+
if settings.RESPONSE_SENDFILE_HEADER:
208208
response.set_empty_content()
209-
response[settings.HTTPRESPONSE_SENDFILE_METHOD] = response.sendfile_filename
209+
response[settings.HTTPRESPONSE_SENDFILE_HEADER] = response.sendfile_filename
210210
for chunk in response:
211211
req.write(chunk)
212212
return 0 # mod_python.apache.OK

django/core/handlers/wsgi.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,14 +242,21 @@ def __call__(self, environ, start_response):
242242
response_headers.append(('Set-Cookie', str(c.output(header=''))))
243243

244244
if isinstance(response, http.HttpResponseSendFile):
245-
if settings.HTTPRESPONSE_SENDFILE_METHOD:
246-
response_headers.append((settings.HTTPRESPONSE_SENDFILE_METHOD,
247-
response.sendfile_filename))
245+
filename = response.sendfile_filename
246+
if settings.HTTPRESPONSE_SENDFILE_HEADER:
247+
response.set_empty_content()
248+
response_headers.append((settings.HTTPRESPONSE_SENDFILE_HEADER,
249+
filename))
248250
elif 'wsgi.file_wrapper' in environ:
249-
filelike = open(response.sendfile_filename, 'rb')
251+
filelike = open(filename, 'rb')
250252
return environ['wsgi.file_wrapper'](filelike,
251253
response.block_size)
252-
254+
else:
255+
import os.path
256+
if not os.path.exists(filename):
257+
raise Exception("Filename provided to HttpResponseSendFile does not exist.")
258+
response_headers.append(('Content-Length',
259+
str(os.path.getsize(filename))))
253260
start_response(status, response_headers)
254261
return response
255262

django/http/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,6 @@ def __init__(self, path_to_file, content_type=None, block_size=8192):
444444
super(HttpResponseSendFile, self).__init__('', content_type=content_type)
445445
self.sendfile_filename = path_to_file
446446
self.block_size = block_size
447-
self['Content-Length'] = os.path.getsize(path_to_file)
448447
self['Content-Disposition'] = ('attachment; filename=%s' %
449448
os.path.basename(path_to_file))
450449
self._empty_content = False

docs/ref/request-response.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,16 @@ live in :mod:`django.http`.
585585
optionally, the file's content type and block size hint for handlers that
586586
need it.
587587

588+
If the setting ``HTTPRESPONSE_SENDFILE_HEADER`` is overridden (default None),
589+
HttpResponseSendFile will return that response header set as the file name given.
590+
If the file is unavailable, no content will be returned. Since certain servers
591+
do not allow direct access to the file system, it is not feasible to verify
592+
the file's existence beforehand.
593+
594+
Be very careful with this method. It provides access to the filesystem that
595+
must be controlled, and performs no verification of a file's existence in most
596+
cases.
597+
588598
Note that response middleware will be bypassed if you use
589599
:class:`HttpResponseSendFile`.
590600

tests/regressiontests/sendfile/tests.py

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

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

0 commit comments

Comments
 (0)