[4.0.x] Fixed #33132 -- Fixed test client handling of querystring only redirects.
Regression in1e5aa8e1c7
. Backport ofb1bf8c8a4b
from main
This commit is contained in:
parent
715aa2db67
commit
5d36af6f6f
|
@ -835,8 +835,11 @@ class Client(ClientMixin, RequestFactory):
|
||||||
if url.port:
|
if url.port:
|
||||||
extra['SERVER_PORT'] = str(url.port)
|
extra['SERVER_PORT'] = str(url.port)
|
||||||
|
|
||||||
|
path = url.path
|
||||||
|
# RFC 2616: bare domains without path are treated as the root.
|
||||||
|
if not path and url.netloc:
|
||||||
|
path = '/'
|
||||||
# Prepend the request path to handle relative path redirects
|
# Prepend the request path to handle relative path redirects
|
||||||
path = url.path or '/'
|
|
||||||
if not path.startswith('/'):
|
if not path.startswith('/'):
|
||||||
path = urljoin(response.request['PATH_INFO'], path)
|
path = urljoin(response.request['PATH_INFO'], path)
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,13 @@ class ClientTest(TestCase):
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.request['PATH_INFO'], '/accounts/login/')
|
self.assertEqual(response.request['PATH_INFO'], '/accounts/login/')
|
||||||
|
|
||||||
|
def test_redirect_to_querystring_only(self):
|
||||||
|
"""A URL that consists of a querystring only can be followed"""
|
||||||
|
response = self.client.post('/post_then_get_view/', follow=True)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(response.request['PATH_INFO'], '/post_then_get_view/')
|
||||||
|
self.assertEqual(response.content, b'The value of success is true.')
|
||||||
|
|
||||||
def test_follow_307_and_308_redirect(self):
|
def test_follow_307_and_308_redirect(self):
|
||||||
"""
|
"""
|
||||||
A 307 or 308 redirect preserves the request method after the redirect.
|
A 307 or 308 redirect preserves the request method after the redirect.
|
||||||
|
|
|
@ -8,6 +8,7 @@ urlpatterns = [
|
||||||
path('upload_view/', views.upload_view, name='upload_view'),
|
path('upload_view/', views.upload_view, name='upload_view'),
|
||||||
path('get_view/', views.get_view, name='get_view'),
|
path('get_view/', views.get_view, name='get_view'),
|
||||||
path('post_view/', views.post_view),
|
path('post_view/', views.post_view),
|
||||||
|
path('post_then_get_view/', views.post_then_get_view),
|
||||||
path('put_view/', views.put_view),
|
path('put_view/', views.put_view),
|
||||||
path('trace_view/', views.trace_view),
|
path('trace_view/', views.trace_view),
|
||||||
path('header_view/', views.view_with_header),
|
path('header_view/', views.view_with_header),
|
||||||
|
|
|
@ -85,6 +85,21 @@ def post_view(request):
|
||||||
return HttpResponse(t.render(c))
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
|
|
||||||
|
def post_then_get_view(request):
|
||||||
|
"""
|
||||||
|
A view that expects a POST request, returns a redirect response
|
||||||
|
to itself providing only a ?success=true querystring,
|
||||||
|
the value of this querystring is then rendered upon GET.
|
||||||
|
"""
|
||||||
|
if request.method == 'POST':
|
||||||
|
return HttpResponseRedirect('?success=true')
|
||||||
|
|
||||||
|
t = Template('The value of success is {{ value }}.', name='GET Template')
|
||||||
|
c = Context({'value': request.GET.get('success', 'false')})
|
||||||
|
|
||||||
|
return HttpResponse(t.render(c))
|
||||||
|
|
||||||
|
|
||||||
def json_view(request):
|
def json_view(request):
|
||||||
"""
|
"""
|
||||||
A view that expects a request with the header 'application/json' and JSON
|
A view that expects a request with the header 'application/json' and JSON
|
||||||
|
|
Loading…
Reference in New Issue