summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/http/response.py20
-rw-r--r--docs/ref/request-response.txt12
-rw-r--r--tests/responses/test_fileresponse.py9
3 files changed, 27 insertions, 14 deletions
diff --git a/django/http/response.py b/django/http/response.py
index a9ede09dd9..04efbd6bef 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -436,15 +436,17 @@ class FileResponse(StreamingHttpResponse):
else:
self['Content-Type'] = 'application/octet-stream'
- if self.as_attachment:
- filename = self.filename or os.path.basename(filename)
- if filename:
- try:
- filename.encode('ascii')
- file_expr = 'filename="{}"'.format(filename)
- except UnicodeEncodeError:
- file_expr = "filename*=utf-8''{}".format(quote(filename))
- self['Content-Disposition'] = 'attachment; {}'.format(file_expr)
+ filename = self.filename or os.path.basename(filename)
+ if filename:
+ disposition = 'attachment' if self.as_attachment else 'inline'
+ try:
+ filename.encode('ascii')
+ file_expr = 'filename="{}"'.format(filename)
+ except UnicodeEncodeError:
+ file_expr = "filename*=utf-8''{}".format(quote(filename))
+ self['Content-Disposition'] = '{}; {}'.format(disposition, file_expr)
+ elif self.as_attachment:
+ self['Content-Disposition'] = 'attachment'
class HttpResponseRedirectBase(HttpResponse):
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 58a7c3e7e4..28e5170595 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -1107,15 +1107,17 @@ Attributes
optimized for binary files. It uses `wsgi.file_wrapper`_ if provided by the
wsgi server, otherwise it streams the file out in small chunks.
- If ``as_attachment=True``, the ``Content-Disposition`` header is set, which
- asks the browser to offer the file to the user as a download.
+ If ``as_attachment=True``, the ``Content-Disposition`` header is set to
+ ``attachment``, which asks the browser to offer the file to the user as a
+ download. Otherwise, a ``Content-Disposition`` header with a value of
+ ``inline`` (the browser default) will be set only if a filename is
+ available.
If ``open_file`` doesn't have a name or if the name of ``open_file`` isn't
appropriate, provide a custom file name using the ``filename`` parameter.
- The ``Content-Length``, ``Content-Type``, and ``Content-Disposition``
- headers are automatically set when they can be guessed from contents of
- ``open_file``.
+ The ``Content-Length`` and ``Content-Type`` headers are automatically set
+ when they can be guessed from contents of ``open_file``.
.. _wsgi.file_wrapper: https://www.python.org/dev/peps/pep-3333/#optional-platform-specific-file-handling
diff --git a/tests/responses/test_fileresponse.py b/tests/responses/test_fileresponse.py
index 5896373d4d..e77df4513a 100644
--- a/tests/responses/test_fileresponse.py
+++ b/tests/responses/test_fileresponse.py
@@ -14,12 +14,21 @@ class FileResponseTests(SimpleTestCase):
response = FileResponse(open(__file__, 'rb'))
self.assertEqual(response['Content-Length'], str(os.path.getsize(__file__)))
self.assertIn(response['Content-Type'], ['text/x-python', 'text/plain'])
+ self.assertEqual(response['Content-Disposition'], 'inline; filename="test_fileresponse.py"')
response.close()
def test_file_from_buffer_response(self):
response = FileResponse(io.BytesIO(b'binary content'))
self.assertEqual(response['Content-Length'], '14')
self.assertEqual(response['Content-Type'], 'application/octet-stream')
+ self.assertFalse(response.has_header('Content-Disposition'))
+ self.assertEqual(list(response), [b'binary content'])
+
+ def test_file_from_buffer_unnamed_attachment(self):
+ response = FileResponse(io.BytesIO(b'binary content'), as_attachment=True)
+ self.assertEqual(response['Content-Length'], '14')
+ self.assertEqual(response['Content-Type'], 'application/octet-stream')
+ self.assertEqual(response['Content-Disposition'], 'attachment')
self.assertEqual(list(response), [b'binary content'])
@skipIf(sys.platform == 'win32', "Named pipes are Unix-only.")