mirror of
				https://github.com/django/django.git
				synced 2025-11-03 21:25:09 +00:00 
			
		
		
		
	Fixed #30196 -- Made FileResponse set Content-Disposition inline if filename is available.
This commit is contained in:
		
							parent
							
								
									5c19274643
								
							
						
					
					
						commit
						de4832c49b
					
				
					 3 changed files with 27 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -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:
 | 
			
		||||
            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'] = 'attachment; {}'.format(file_expr)
 | 
			
		||||
            self['Content-Disposition'] = '{}; {}'.format(disposition, file_expr)
 | 
			
		||||
        elif self.as_attachment:
 | 
			
		||||
            self['Content-Disposition'] = 'attachment'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HttpResponseRedirectBase(HttpResponse):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue