Skip to content

Commit

Permalink
Fixed django#18678 -- HttpResponse init arguments allowed for subclasses
Browse files Browse the repository at this point in the history
Thanks [email protected] for the report.
  • Loading branch information
claudep committed Aug 23, 2012
1 parent 03671ad commit 44c09de
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
8 changes: 4 additions & 4 deletions django/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,11 +728,11 @@ def tell(self):
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']

def __init__(self, redirect_to):
def __init__(self, redirect_to, *args, **kwargs):
parsed = urlparse(redirect_to)
if parsed.scheme and parsed.scheme not in self.allowed_schemes:
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)

class HttpResponseRedirect(HttpResponseRedirectBase):
Expand Down Expand Up @@ -766,8 +766,8 @@ class HttpResponseForbidden(HttpResponse):
class HttpResponseNotAllowed(HttpResponse):
status_code = 405

def __init__(self, permitted_methods):
super(HttpResponseNotAllowed, self).__init__()
def __init__(self, permitted_methods, *args, **kwargs):
super(HttpResponseNotAllowed, self).__init__(*args, **kwargs)
self['Allow'] = ', '.join(permitted_methods)

class HttpResponseGone(HttpResponse):
Expand Down
14 changes: 8 additions & 6 deletions docs/ref/request-response.txt
Original file line number Diff line number Diff line change
Expand Up @@ -731,10 +731,11 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in

.. class:: HttpResponseRedirect

The constructor takes a single argument -- the path to redirect to. This
can be a fully qualified URL (e.g. ``'http://www.yahoo.com/search/'``) or
an absolute path with no domain (e.g. ``'/search/'``). Note that this
returns an HTTP status code 302.
The first argument to the constructor is required -- the path to redirect
to. This can be a fully qualified URL
(e.g. ``'http://www.yahoo.com/search/'``) or an absolute path with no
domain (e.g. ``'/search/'``). See :class:`HttpResponse` for other optional
constructor arguments. Note that this returns an HTTP status code 302.

.. class:: HttpResponsePermanentRedirect

Expand All @@ -761,8 +762,9 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in

.. class:: HttpResponseNotAllowed

Like :class:`HttpResponse`, but uses a 405 status code. Takes a single,
required argument: a list of permitted methods (e.g. ``['GET', 'POST']``).
Like :class:`HttpResponse`, but uses a 405 status code. The first argument
to the constructor is required: a list of permitted methods (e.g.
``['GET', 'POST']``).

.. class:: HttpResponseGone

Expand Down
23 changes: 21 additions & 2 deletions tests/regressiontests/httpwrappers/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

from django.core.exceptions import SuspiciousOperation
from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
HttpResponsePermanentRedirect, HttpResponseNotModified,
HttpResponsePermanentRedirect, HttpResponseNotAllowed,
HttpResponseNotModified,
SimpleCookie, BadHeaderError,
parse_cookie)
from django.test import TestCase
from django.utils import six
from django.utils import unittest

Expand Down Expand Up @@ -330,7 +332,16 @@ def test_unsafe_redirect(self):
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):
response = HttpResponseNotModified()
self.assertEqual(response.status_code, 304)
Expand All @@ -339,6 +350,14 @@ def test_not_modified(self):
response.content = "Hello dear"
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):
def test_encode(self):
Expand Down

0 comments on commit 44c09de

Please sign in to comment.