Fixed #5897 -- Added the Content-Length response header in CommonMiddleware
Thanks Tim Graham for the review.
This commit is contained in:
parent
ca77b50905
commit
9588718cd4
|
@ -123,6 +123,10 @@ class CommonMiddleware(MiddlewareMixin):
|
||||||
etag=unquote_etag(response['ETag']),
|
etag=unquote_etag(response['ETag']),
|
||||||
response=response,
|
response=response,
|
||||||
)
|
)
|
||||||
|
# Add the Content-Length header to non-streaming responses if not
|
||||||
|
# already set.
|
||||||
|
if not response.streaming and not response.has_header('Content-Length'):
|
||||||
|
response['Content-Length'] = str(len(response.content))
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,12 @@ Adds a few conveniences for perfectionists:
|
||||||
for each request by MD5-hashing the page content, and it'll take care of
|
for each request by MD5-hashing the page content, and it'll take care of
|
||||||
sending ``Not Modified`` responses, if appropriate.
|
sending ``Not Modified`` responses, if appropriate.
|
||||||
|
|
||||||
|
* Sets the ``Content-Length`` header for non-streaming responses.
|
||||||
|
|
||||||
|
.. versionchanged: 1.11
|
||||||
|
|
||||||
|
Older versions didn't set the ``Content-Length`` header.
|
||||||
|
|
||||||
.. attribute:: CommonMiddleware.response_redirect_class
|
.. attribute:: CommonMiddleware.response_redirect_class
|
||||||
|
|
||||||
Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
|
Defaults to :class:`~django.http.HttpResponsePermanentRedirect`. Subclass
|
||||||
|
|
|
@ -197,6 +197,9 @@ Requests and Responses
|
||||||
|
|
||||||
* Added :meth:`QueryDict.fromkeys() <django.http.QueryDict.fromkeys>`.
|
* Added :meth:`QueryDict.fromkeys() <django.http.QueryDict.fromkeys>`.
|
||||||
|
|
||||||
|
* :class:`~django.middleware.common.CommonMiddleware` now sets the
|
||||||
|
``Content-Length`` response header for non-streaming responses.
|
||||||
|
|
||||||
Serialization
|
Serialization
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -285,6 +285,27 @@ class CommonMiddlewareTest(SimpleTestCase):
|
||||||
second_res = CommonMiddleware().process_response(second_req, HttpResponse('content'))
|
second_res = CommonMiddleware().process_response(second_req, HttpResponse('content'))
|
||||||
self.assertEqual(second_res.status_code, 304)
|
self.assertEqual(second_res.status_code, 304)
|
||||||
|
|
||||||
|
# Tests for the Content-Length header
|
||||||
|
|
||||||
|
def test_content_length_header_added(self):
|
||||||
|
response = HttpResponse('content')
|
||||||
|
self.assertNotIn('Content-Length', response)
|
||||||
|
response = CommonMiddleware().process_response(HttpRequest(), response)
|
||||||
|
self.assertEqual(int(response['Content-Length']), len(response.content))
|
||||||
|
|
||||||
|
def test_content_length_header_not_added_for_streaming_response(self):
|
||||||
|
response = StreamingHttpResponse('content')
|
||||||
|
self.assertNotIn('Content-Length', response)
|
||||||
|
response = CommonMiddleware().process_response(HttpRequest(), response)
|
||||||
|
self.assertNotIn('Content-Length', response)
|
||||||
|
|
||||||
|
def test_content_length_header_not_changed(self):
|
||||||
|
response = HttpResponse()
|
||||||
|
bad_content_length = len(response.content) + 10
|
||||||
|
response['Content-Length'] = bad_content_length
|
||||||
|
response = CommonMiddleware().process_response(HttpRequest(), response)
|
||||||
|
self.assertEqual(int(response['Content-Length']), bad_content_length)
|
||||||
|
|
||||||
# Other tests
|
# Other tests
|
||||||
|
|
||||||
@override_settings(DISALLOWED_USER_AGENTS=[re.compile(r'foo')])
|
@override_settings(DISALLOWED_USER_AGENTS=[re.compile(r'foo')])
|
||||||
|
@ -445,6 +466,9 @@ class ConditionalGetMiddlewareTest(SimpleTestCase):
|
||||||
|
|
||||||
def test_content_length_header_added(self):
|
def test_content_length_header_added(self):
|
||||||
content_length = len(self.resp.content)
|
content_length = len(self.resp.content)
|
||||||
|
# Already set by CommonMiddleware, remove it to check that
|
||||||
|
# ConditionalGetMiddleware readds it.
|
||||||
|
del self.resp['Content-Length']
|
||||||
self.assertNotIn('Content-Length', self.resp)
|
self.assertNotIn('Content-Length', self.resp)
|
||||||
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
|
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
|
||||||
self.assertIn('Content-Length', self.resp)
|
self.assertIn('Content-Length', self.resp)
|
||||||
|
|
|
@ -41,6 +41,7 @@ class TestStartProjectSettings(TestCase):
|
||||||
response = self.client.get('/empty/')
|
response = self.client.get('/empty/')
|
||||||
headers = sorted(response.serialize_headers().split(b'\r\n'))
|
headers = sorted(response.serialize_headers().split(b'\r\n'))
|
||||||
self.assertEqual(headers, [
|
self.assertEqual(headers, [
|
||||||
|
b'Content-Length: 0',
|
||||||
b'Content-Type: text/html; charset=utf-8',
|
b'Content-Type: text/html; charset=utf-8',
|
||||||
b'X-Frame-Options: SAMEORIGIN',
|
b'X-Frame-Options: SAMEORIGIN',
|
||||||
])
|
])
|
||||||
|
|
|
@ -41,11 +41,12 @@ class WSGITest(SimpleTestCase):
|
||||||
|
|
||||||
self.assertEqual(response_data["status"], "200 OK")
|
self.assertEqual(response_data["status"], "200 OK")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
response_data["headers"],
|
set(response_data["headers"]),
|
||||||
[('Content-Type', 'text/html; charset=utf-8')])
|
{('Content-Length', '12'), ('Content-Type', 'text/html; charset=utf-8')})
|
||||||
self.assertEqual(
|
self.assertTrue(bytes(response) in [
|
||||||
bytes(response),
|
b"Content-Length: 12\r\nContent-Type: text/html; charset=utf-8\r\n\r\nHello World!",
|
||||||
b"Content-Type: text/html; charset=utf-8\r\n\r\nHello World!")
|
b"Content-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\n\r\nHello World!"
|
||||||
|
])
|
||||||
|
|
||||||
def test_file_wrapper(self):
|
def test_file_wrapper(self):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue