Fixed #18678 -- HttpResponse init arguments allowed for subclasses
Thanks hp1337@gmail.com for the report.
This commit is contained in:
parent
03671ad7e3
commit
44c09de555
|
@ -728,11 +728,11 @@ class HttpResponse(object):
|
||||||
class HttpResponseRedirectBase(HttpResponse):
|
class HttpResponseRedirectBase(HttpResponse):
|
||||||
allowed_schemes = ['http', 'https', 'ftp']
|
allowed_schemes = ['http', 'https', 'ftp']
|
||||||
|
|
||||||
def __init__(self, redirect_to):
|
def __init__(self, redirect_to, *args, **kwargs):
|
||||||
parsed = urlparse(redirect_to)
|
parsed = urlparse(redirect_to)
|
||||||
if parsed.scheme and parsed.scheme not in self.allowed_schemes:
|
if parsed.scheme and parsed.scheme not in self.allowed_schemes:
|
||||||
raise SuspiciousOperation("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
|
raise SuspiciousOperation("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
|
||||||
super(HttpResponseRedirectBase, self).__init__()
|
super(HttpResponseRedirectBase, self).__init__(*args, **kwargs)
|
||||||
self['Location'] = iri_to_uri(redirect_to)
|
self['Location'] = iri_to_uri(redirect_to)
|
||||||
|
|
||||||
class HttpResponseRedirect(HttpResponseRedirectBase):
|
class HttpResponseRedirect(HttpResponseRedirectBase):
|
||||||
|
@ -766,8 +766,8 @@ class HttpResponseForbidden(HttpResponse):
|
||||||
class HttpResponseNotAllowed(HttpResponse):
|
class HttpResponseNotAllowed(HttpResponse):
|
||||||
status_code = 405
|
status_code = 405
|
||||||
|
|
||||||
def __init__(self, permitted_methods):
|
def __init__(self, permitted_methods, *args, **kwargs):
|
||||||
super(HttpResponseNotAllowed, self).__init__()
|
super(HttpResponseNotAllowed, self).__init__(*args, **kwargs)
|
||||||
self['Allow'] = ', '.join(permitted_methods)
|
self['Allow'] = ', '.join(permitted_methods)
|
||||||
|
|
||||||
class HttpResponseGone(HttpResponse):
|
class HttpResponseGone(HttpResponse):
|
||||||
|
|
|
@ -731,10 +731,11 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
|
||||||
|
|
||||||
.. class:: HttpResponseRedirect
|
.. class:: HttpResponseRedirect
|
||||||
|
|
||||||
The constructor takes a single argument -- the path to redirect to. This
|
The first argument to the constructor is required -- the path to redirect
|
||||||
can be a fully qualified URL (e.g. ``'http://www.yahoo.com/search/'``) or
|
to. This can be a fully qualified URL
|
||||||
an absolute path with no domain (e.g. ``'/search/'``). Note that this
|
(e.g. ``'http://www.yahoo.com/search/'``) or an absolute path with no
|
||||||
returns an HTTP status code 302.
|
domain (e.g. ``'/search/'``). See :class:`HttpResponse` for other optional
|
||||||
|
constructor arguments. Note that this returns an HTTP status code 302.
|
||||||
|
|
||||||
.. class:: HttpResponsePermanentRedirect
|
.. class:: HttpResponsePermanentRedirect
|
||||||
|
|
||||||
|
@ -761,8 +762,9 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
|
||||||
|
|
||||||
.. class:: HttpResponseNotAllowed
|
.. class:: HttpResponseNotAllowed
|
||||||
|
|
||||||
Like :class:`HttpResponse`, but uses a 405 status code. Takes a single,
|
Like :class:`HttpResponse`, but uses a 405 status code. The first argument
|
||||||
required argument: a list of permitted methods (e.g. ``['GET', 'POST']``).
|
to the constructor is required: a list of permitted methods (e.g.
|
||||||
|
``['GET', 'POST']``).
|
||||||
|
|
||||||
.. class:: HttpResponseGone
|
.. class:: HttpResponseGone
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,11 @@ import pickle
|
||||||
|
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
|
from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
|
||||||
HttpResponsePermanentRedirect, HttpResponseNotModified,
|
HttpResponsePermanentRedirect, HttpResponseNotAllowed,
|
||||||
|
HttpResponseNotModified,
|
||||||
SimpleCookie, BadHeaderError,
|
SimpleCookie, BadHeaderError,
|
||||||
parse_cookie)
|
parse_cookie)
|
||||||
|
from django.test import TestCase
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils import unittest
|
from django.utils import unittest
|
||||||
|
|
||||||
|
@ -330,7 +332,16 @@ class HttpResponseTests(unittest.TestCase):
|
||||||
HttpResponsePermanentRedirect, url)
|
HttpResponsePermanentRedirect, url)
|
||||||
|
|
||||||
|
|
||||||
class HttpResponseSubclassesTests(unittest.TestCase):
|
class HttpResponseSubclassesTests(TestCase):
|
||||||
|
def test_redirect(self):
|
||||||
|
response = HttpResponseRedirect('/redirected/')
|
||||||
|
self.assertEqual(response.status_code, 302)
|
||||||
|
# Test that standard HttpResponse init args can be used
|
||||||
|
response = HttpResponseRedirect('/redirected/',
|
||||||
|
content='The resource has temporarily moved',
|
||||||
|
content_type='text/html')
|
||||||
|
self.assertContains(response, 'The resource has temporarily moved', status_code=302)
|
||||||
|
|
||||||
def test_not_modified(self):
|
def test_not_modified(self):
|
||||||
response = HttpResponseNotModified()
|
response = HttpResponseNotModified()
|
||||||
self.assertEqual(response.status_code, 304)
|
self.assertEqual(response.status_code, 304)
|
||||||
|
@ -339,6 +350,14 @@ class HttpResponseSubclassesTests(unittest.TestCase):
|
||||||
response.content = "Hello dear"
|
response.content = "Hello dear"
|
||||||
self.assertNotIn('content-type', response)
|
self.assertNotIn('content-type', response)
|
||||||
|
|
||||||
|
def test_not_allowed(self):
|
||||||
|
response = HttpResponseNotAllowed(['GET'])
|
||||||
|
self.assertEqual(response.status_code, 405)
|
||||||
|
# Test that standard HttpResponse init args can be used
|
||||||
|
response = HttpResponseNotAllowed(['GET'],
|
||||||
|
content='Only the GET method is allowed',
|
||||||
|
content_type='text/html')
|
||||||
|
self.assertContains(response, 'Only the GET method is allowed', status_code=405)
|
||||||
|
|
||||||
class CookieTests(unittest.TestCase):
|
class CookieTests(unittest.TestCase):
|
||||||
def test_encode(self):
|
def test_encode(self):
|
||||||
|
|
Loading…
Reference in New Issue