Fixed #11340 -- Prevented HttpResponseNotModified to have content/content-type

The HTTP 1.1 spec tells that the 304 response MUST NOT contain a
message body.
Thanks aparajita for the report.
This commit is contained in:
Claude Paroz 2012-08-22 18:06:03 +02:00
parent e2b4eddc11
commit 7cfe8e8fce
4 changed files with 25 additions and 4 deletions

View File

@ -744,6 +744,16 @@ class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
class HttpResponseNotModified(HttpResponse):
status_code = 304
def __init__(self, *args, **kwargs):
super(HttpResponseNotModified, self).__init__(*args, **kwargs)
del self['content-type']
@HttpResponse.content.setter
def content(self, value):
if value:
raise AttributeError("You cannot set content to a 304 (Not Modified) response")
self._container = []
class HttpResponseBadRequest(HttpResponse):
status_code = 400

View File

@ -61,7 +61,7 @@ def serve(request, path, document_root=None, show_indexes=False):
mimetype = mimetype or 'application/octet-stream'
if not was_modified_since(request.META.get('HTTP_IF_MODIFIED_SINCE'),
statobj.st_mtime, statobj.st_size):
return HttpResponseNotModified(content_type=mimetype)
return HttpResponseNotModified()
with open(fullpath, 'rb') as f:
response = HttpResponse(f.read(), content_type=mimetype)
response["Last-Modified"] = http_date(statobj.st_mtime)

View File

@ -743,8 +743,9 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
.. class:: HttpResponseNotModified
The constructor doesn't take any arguments. Use this to designate that a
page hasn't been modified since the user's last request (status code 304).
The constructor doesn't take any arguments and no content should be added
to this response. Use this to designate that a page hasn't been modified
since the user's last request (status code 304).
.. class:: HttpResponseBadRequest

View File

@ -6,7 +6,7 @@ import pickle
from django.core.exceptions import SuspiciousOperation
from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
HttpResponsePermanentRedirect,
HttpResponsePermanentRedirect, HttpResponseNotModified,
SimpleCookie, BadHeaderError,
parse_cookie)
from django.utils import six
@ -330,6 +330,16 @@ class HttpResponseTests(unittest.TestCase):
HttpResponsePermanentRedirect, url)
class HttpResponseSubclassesTests(unittest.TestCase):
def test_not_modified(self):
response = HttpResponseNotModified()
self.assertEqual(response.status_code, 304)
# 304 responses should not have content/content-type
with self.assertRaises(AttributeError):
response.content = "Hello dear"
self.assertNotIn('content-type', response)
class CookieTests(unittest.TestCase):
def test_encode(self):
"""