Fixed #10491 -- Allowed passing lazy objects to HttpResponseRedirect.

Thanks liangent for the report.
This commit is contained in:
Baptiste Mispelon 2013-04-20 05:20:01 +02:00 committed by Tim Graham
parent 75cf5fc7f0
commit 3c45fb8589
2 changed files with 15 additions and 3 deletions

View File

@ -14,7 +14,7 @@ from django.core import signing
from django.core.exceptions import DisallowedRedirect from django.core.exceptions import DisallowedRedirect
from django.http.cookie import SimpleCookie from django.http.cookie import SimpleCookie
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.encoding import force_bytes, iri_to_uri from django.utils.encoding import force_bytes, force_text, iri_to_uri
from django.utils.http import cookie_date from django.utils.http import cookie_date
from django.utils.six.moves import map from django.utils.six.moves import map
@ -393,7 +393,7 @@ class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp'] allowed_schemes = ['http', 'https', 'ftp']
def __init__(self, redirect_to, *args, **kwargs): def __init__(self, redirect_to, *args, **kwargs):
parsed = urlparse(redirect_to) parsed = urlparse(force_text(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 DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)
super(HttpResponseRedirectBase, self).__init__(*args, **kwargs) super(HttpResponseRedirectBase, self).__init__(*args, **kwargs)

View File

@ -16,10 +16,13 @@ from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
SimpleCookie, BadHeaderError, SimpleCookie, BadHeaderError,
parse_cookie) parse_cookie)
from django.test import TestCase from django.test import TestCase
from django.utils.encoding import smart_str from django.utils.encoding import smart_str, force_text
from django.utils.functional import lazy
from django.utils._os import upath from django.utils._os import upath
from django.utils import six from django.utils import six
lazystr = lazy(force_text, six.text_type)
class QueryDictTests(unittest.TestCase): class QueryDictTests(unittest.TestCase):
def test_missing_key(self): def test_missing_key(self):
@ -366,6 +369,10 @@ class HttpResponseTests(unittest.TestCase):
self.assertEqual(list(i), [b'abc']) self.assertEqual(list(i), [b'abc'])
self.assertEqual(list(i), []) self.assertEqual(list(i), [])
def test_lazy_content(self):
r = HttpResponse(lazystr('helloworld'))
self.assertEqual(r.content, b'helloworld')
def test_file_interface(self): def test_file_interface(self):
r = HttpResponse() r = HttpResponse()
r.write(b"hello") r.write(b"hello")
@ -402,6 +409,11 @@ class HttpResponseSubclassesTests(TestCase):
# Test that url attribute is right # Test that url attribute is right
self.assertEqual(response.url, response['Location']) self.assertEqual(response.url, response['Location'])
def test_redirect_lazy(self):
"""Make sure HttpResponseRedirect works with lazy strings."""
r = HttpResponseRedirect(lazystr('/redirected/'))
self.assertEqual(r.url, '/redirected/')
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)