Fix /redirect to return absolute URL

This commit is contained in:
Eduardo Gurgel
2014-09-21 00:12:42 +12:00
parent 8f61f1f9ea
commit 54fc281ef7
3 changed files with 73 additions and 8 deletions
+28 -8
View File
@@ -14,7 +14,7 @@ import random
import time
import uuid
from flask import Flask, Response, request, render_template, redirect, jsonify as flask_jsonify, make_response
from flask import Flask, Response, request, render_template, redirect, jsonify as flask_jsonify, make_response, url_for
from werkzeug.datastructures import WWWAuthenticate, MultiDict
from werkzeug.http import http_date
from werkzeug.wrappers import BaseResponse
@@ -188,14 +188,22 @@ def view_deflate_encoded_content():
@app.route('/redirect/<int:n>')
def redirect_n_times(n):
"""301 Redirects n times."""
"""302 Redirects n times."""
assert n > 0
if (n == 1):
return redirect('/get')
absolute = request.args.get('absolute', 'false').lower() == 'true'
return redirect('/redirect/{0}'.format(n - 1))
if n == 1:
return redirect(url_for('view_get', _external=absolute))
if absolute:
return _redirect('absolute', n, True)
else:
return _redirect('relative', n, False)
def _redirect(kind, n, external):
return redirect(url_for('{0}_redirect_n_times'.format(kind), n=n - 1, _external=external))
@app.route('/redirect-to')
@@ -216,14 +224,14 @@ def redirect_to():
@app.route('/relative-redirect/<int:n>')
def relative_redirect_n_times(n):
"""301 Redirects n times."""
"""302 Redirects n times."""
assert n > 0
response = app.make_response('')
response.status_code = 302
if (n == 1):
if n == 1:
response.headers['Location'] = '/get'
return response
@@ -231,6 +239,18 @@ def relative_redirect_n_times(n):
return response
@app.route('/absolute-redirect/<int:n>')
def absolute_redirect_n_times(n):
"""302 Redirects n times."""
assert n > 0
if n == 1:
return redirect(url_for('view_get', _external=True))
return _redirect('absolute', n, True)
@app.route('/stream/<int:n>')
def stream_n_messages(n):
"""Stream n JSON messages"""
+1
View File
@@ -23,6 +23,7 @@
<li><a href="/redirect/6"><code>/redirect/:n</code></a> 302 Redirects <em>n</em> times.</li>
<li><a href="/redirect-to?url=http://example.com/"><code>/redirect-to?url=foo</code></a> 302 Redirects to the <em>foo</em> URL.</li>
<li><a href="/relative-redirect/6"><code>/relative-redirect/:n</code></a> 302 Relative redirects <em>n</em> times.</li>
<li><a href="/absolute-redirect/6"><code>/absolute-redirect/:n</code></a> 302 Absolute redirects <em>n</em> times.</li>
<li><a href="/cookies" data-bare-link="true"><code>/cookies</code></a> Returns cookie data.</li>
<li><a href="/cookies/set?k1=v1&amp;k2=v2"><code>/cookies/set?name=value</code></a> Sets one or more simple cookies.</li>
<li><a href="/cookies/delete?k1&amp;k2"><code>/cookies/delete?name</code></a> Deletes one or more simple cookies.</li>
+44
View File
@@ -290,6 +290,50 @@ class HttpbinTestCase(unittest.TestCase):
})
assert json.loads(response.data.decode('utf-8'))['url'].startswith('https://')
def test_redirect_n_higher_than_1(self):
response = self.app.get('/redirect/5')
self.assertEqual(
response.headers.get('Location'), '/relative-redirect/4'
)
def test_redirect_absolute_param_n_higher_than_1(self):
response = self.app.get('/redirect/5?absolute=true')
self.assertEqual(
response.headers.get('Location'), 'http://localhost/absolute-redirect/4'
)
def test_redirect_n_equals_to_1(self):
response = self.app.get('/redirect/1')
self.assertEqual(response.status_code, 302)
self.assertEqual(
response.headers.get('Location'), '/get'
)
def test_relative_redirect_n_equals_to_1(self):
response = self.app.get('/relative-redirect/1')
self.assertEqual(
response.headers.get('Location'), '/get'
)
def test_relative_redirect_n_higher_than_1(self):
response = self.app.get('/relative-redirect/7')
self.assertEqual(response.status_code, 302)
self.assertEqual(
response.headers.get('Location'), '/relative-redirect/6'
)
def test_absolute_redirect_n_higher_than_1(self):
response = self.app.get('/absolute-redirect/5')
self.assertEqual(
response.headers.get('Location'), 'http://localhost/absolute-redirect/4'
)
def test_absolute_redirect_n_equals_to_1(self):
response = self.app.get('/absolute-redirect/1')
self.assertEqual(response.status_code, 302)
self.assertEqual(
response.headers.get('Location'), 'http://localhost/get'
)
if __name__ == '__main__':
unittest.main()