misc: avoid URLs starting with double slash (#29373)

This commit is contained in:
Frédéric Péters 2018-12-28 12:54:26 +01:00
parent 1a0d0a91b7
commit 0333c9494e
2 changed files with 17 additions and 8 deletions

View File

@ -164,6 +164,8 @@ def test_url_server(pub):
{'url': url}) == 'http://www.example.net/foobar'
assert get_variadic_url('[url]/foobar/',
{'url': url}) == 'http://www.example.net/foobar/'
assert get_variadic_url('{{url}}/foobar/',
{'url': url}) == 'http://www.example.net/foobar/'
assert get_variadic_url('[url]foo/bar/',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foo/bar/'
assert get_variadic_url('[url]foobar/',
@ -174,7 +176,7 @@ def test_url_server(pub):
assert get_variadic_url('{{ url }}/foobar',
{'url': 'http://www.example.net'}) == 'http://www.example.net/foobar'
assert get_variadic_url('{{ url }}/foobar', # Django is more conservative here:
{'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar'
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar'
# to be "smart", use Django templates language:
for url in ('http://www.example.net', 'http://www.example.net/'):
assert get_variadic_url('{{ url }}{% if url|last != "/" %}/{% endif %}foobar',
@ -207,7 +209,7 @@ def test_url_server_qs(pub):
assert get_variadic_url('{{ url }}/?foo=bar',
{'url': 'http://www.example.net'}) == 'http://www.example.net/?foo=bar'
assert get_variadic_url('{{ url }}/?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net//?foo=bar'
{'url': 'http://www.example.net/'}) == 'http://www.example.net/?foo=bar'
def test_url_server_more(pub):
@ -222,7 +224,7 @@ def test_url_server_more(pub):
assert get_variadic_url('{{ url }}/foobar/json?toto',
{'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/json?toto'
assert get_variadic_url('{{ url }}/foobar/json?toto',
{'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/json?toto'
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?toto'
assert get_variadic_url('{{ url }}foobar/json?toto',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?toto'
@ -239,7 +241,7 @@ def test_url_server_even_more(pub):
assert get_variadic_url('{{ url }}/foobar/json?foo=bar',
{'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/json?foo=bar'
assert get_variadic_url('{{ url }}/foobar/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/json?foo=bar'
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?foo=bar'
assert get_variadic_url('{{ url }}foobar/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/json?foo=bar'
@ -249,14 +251,12 @@ def test_url_server_even_more_more(pub):
{'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/baz/json?foo=bar'
assert get_variadic_url('[url]/foobar/baz/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar'
assert get_variadic_url('[url]foobar/baz/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar'
# Django is more conservative
assert get_variadic_url('{{ url }}/foobar/baz/json?foo=bar',
{'url': 'http://www.example.net'}) == 'http://www.example.net/foobar/baz/json?foo=bar'
assert get_variadic_url('{{ url }}/foobar/baz/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net//foobar/baz/json?foo=bar'
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar'
assert get_variadic_url('{{ url }}foobar/baz/json?foo=bar',
{'url': 'http://www.example.net/'}) == 'http://www.example.net/foobar/baz/json?foo=bar'

View File

@ -346,7 +346,16 @@ def get_variadic_url(url, variables, encode_query=True):
# django template
if '{{' in url or '{%' in url:
try:
return Template(url).render(variables)
url = Template(url).render(variables)
p = urlparse.urlsplit(url)
scheme, netloc, path, query, fragment = (
p.scheme, p.netloc, p.path, p.query, p.fragment)
if path.startswith('//'):
# don't let double slash happen at the root of the URL, this
# happens when a template such as {{url}}/path is used (with
# {{url}} already ending with a slash).
path = path[1:]
return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
except (TemplateSyntaxError, VariableDoesNotExist):
return url