Fixed #16040 -- Preserved scheme, host and port in the test client when following a redirect.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17157 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Aymeric Augustin 2011-11-27 20:04:13 +00:00
parent c11f9c3193
commit 33a52cde08
3 changed files with 21 additions and 9 deletions

View File

@ -546,19 +546,18 @@ class Client(RequestFactory):
response.redirect_chain = [] response.redirect_chain = []
while response.status_code in (301, 302, 303, 307): while response.status_code in (301, 302, 303, 307):
url = response['Location'] url = response['Location']
scheme, netloc, path, query, fragment = urlsplit(url)
redirect_chain = response.redirect_chain redirect_chain = response.redirect_chain
redirect_chain.append((url, response.status_code)) redirect_chain.append((url, response.status_code))
if scheme: url = urlsplit(url)
extra['wsgi.url_scheme'] = scheme if url.scheme:
extra['wsgi.url_scheme'] = url.scheme
if url.hostname:
extra['SERVER_NAME'] = url.hostname
if url.port:
extra['SERVER_PORT'] = str(url.port)
# The test client doesn't handle external links, response = self.get(url.path, QueryDict(url.query), follow=False, **extra)
# but since the situation is simulated in test_client,
# we fake things here by ignoring the netloc portion of the
# redirected URL.
response = self.get(path, QueryDict(query), follow=False, **extra)
response.redirect_chain = redirect_chain response.redirect_chain = redirect_chain
# Prevent loops # Prevent loops

View File

@ -368,6 +368,18 @@ class AssertRedirectsTests(TestCase):
'/test_client_regress/no_template_view/', 301, 200) '/test_client_regress/no_template_view/', 301, 200)
self.assertEqual(len(response.redirect_chain), 3) self.assertEqual(len(response.redirect_chain), 3)
def test_redirect_to_different_host(self):
"The test client will preserve scheme, host and port changes"
response = self.client.get('/test_client_regress/redirect_other_host/', follow=True)
self.assertRedirects(response,
'https://otherserver:8443/test_client_regress/no_template_view/',
status_code=301, target_status_code=200)
# We can't use is_secure() or get_host()
# because response.request is a dictionary, not an HttpRequest
self.assertEqual(response.request.get('wsgi.url_scheme'), 'https')
self.assertEqual(response.request.get('SERVER_NAME'), 'otherserver')
self.assertEqual(response.request.get('SERVER_PORT'), '8443')
def test_redirect_chain_on_non_redirect_page(self): def test_redirect_chain_on_non_redirect_page(self):
"An assertion is raised if the original page couldn't be retrieved as expected" "An assertion is raised if the original page couldn't be retrieved as expected"
# This page will redirect with code 301, not 302 # This page will redirect with code 301, not 302

View File

@ -23,6 +23,7 @@ urlpatterns = patterns('',
(r'^circular_redirect_1/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_2/')), (r'^circular_redirect_1/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_2/')),
(r'^circular_redirect_2/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_3/')), (r'^circular_redirect_2/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_3/')),
(r'^circular_redirect_3/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_1/')), (r'^circular_redirect_3/$', RedirectView.as_view(url='/test_client_regress/circular_redirect_1/')),
(r'^redirect_other_host/$', RedirectView.as_view(url='https://otherserver:8443/test_client_regress/no_template_view/')),
(r'^set_session/$', views.set_session_view), (r'^set_session/$', views.set_session_view),
(r'^check_session/$', views.check_session_view), (r'^check_session/$', views.check_session_view),
(r'^request_methods/$', views.request_methods_view), (r'^request_methods/$', views.request_methods_view),