Skip to content

Commit

Permalink
Fix building of non-absolute urls
Browse files Browse the repository at this point in the history
  • Loading branch information
bwhmather committed Dec 23, 2015
1 parent 236821c commit c4d1823
Showing 1 changed file with 51 additions and 35 deletions.
86 changes: 51 additions & 35 deletions verktyg/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,15 @@
import re
import uuid
import posixpath
from urllib.parse import (
urlencode, quote as urlquote, urljoin,
urlunparse, ParseResult
)

from pprint import pformat

from werkzeug.urls import url_encode, url_quote, url_join
from werkzeug._internal import _get_environ
from werkzeug._compat import to_bytes, wsgi_decoding_dance
from werkzeug._compat import wsgi_decoding_dance

from verktyg.utils import format_string
from verktyg.datastructures import ImmutableDict, MultiDict
Expand Down Expand Up @@ -688,9 +691,7 @@ def build(self, values, append_unknown=True):
return
processed.add(data)
else:
add(url_quote(
to_bytes(data, self.router.charset), safe='/:|+'
))
add(urlquote(data, encoding=self.router.charset, safe='/:|+'))
domain_part, url = (u''.join(tmp)).split(u'|', 1)

if append_unknown:
Expand All @@ -700,10 +701,10 @@ def build(self, values, append_unknown=True):
del query_vars[key]

if query_vars:
url += u'?' + url_encode(query_vars,
charset=self.router.charset,
sort=self.router.sort_parameters,
key=self.router.sort_key)
url += u'?' + urlencode(
sorted(query_vars.items(), key=self.router.sort_key),
encoding=self.router.charset,
)

return domain_part, url

Expand Down Expand Up @@ -802,7 +803,9 @@ def to_python(self, value):
return value

def to_url(self, value):
return url_quote(value, charset=self.router.charset)
if not isinstance(value, (str, bytes)):
value = str(value)
return urlquote(value, encoding=self.router.charset, safe='/:')


class UnicodeConverter(BaseConverter):
Expand Down Expand Up @@ -982,8 +985,8 @@ class URLMap(object):
to the list of converters. If you redefine one
converter this will override the original one.
:param sort_parameters: If set to `True` the url parameters are sorted.
See `url_encode` for more details.
:param sort_key: The sort key function for `url_encode`.
See `urlencode` for more details.
:param sort_key: The sort key function for `urlencode`.
:param encoding_errors: the error method to use for decoding
:param host_matching: if set to `True` it enables the host matching
feature and disables the subdomain one. If
Expand Down Expand Up @@ -1089,11 +1092,21 @@ def bind(self, server_name, script_name=None, subdomain=None,
'subdomain was provided')
elif subdomain is None:
subdomain = self.default_subdomain
if script_name is None:
script_name = '/'
if server_name:

if subdomain is not None:
subdomain = subdomain.lower()
subdomain = subdomain.encode('idna').decode('ascii')

if server_name is not None:
server_name = server_name.lower()
server_name = server_name.encode('idna').decode('ascii')

if subdomain and not server_name:
raise TypeError('subdomain specified without server name')

if script_name is None:
script_name = '/'

return MapAdapter(self, server_name, script_name, subdomain,
url_scheme, path_info, query_args)

Expand Down Expand Up @@ -1275,11 +1288,14 @@ def match(self, path_info=None, return_route=False, query_args=None):
rv = route.match(path)
except RequestSlash:
raise RequestRedirect(self.make_redirect_url(
url_quote(path_info, self.router.charset,
safe='/:|+') + '/', query_args))
urlquote(
path_info, encoding=self.router.charset, safe='/:|+'
) + '/', query_args
))
except RequestAliasRedirect as e:
raise RequestRedirect(self.make_alias_redirect_url(
path, route.endpoint, e.matched_values, query_args))
path, route.endpoint, e.matched_values, query_args
))
if rv is None:
continue

Expand All @@ -1297,7 +1313,7 @@ def _handle_match(match):
route.redirect_to)
else:
redirect_url = route.redirect_to(self, **rv)
raise RequestRedirect(str(url_join('%s://%s%s%s' % (
raise RequestRedirect(str(urljoin('%s://%s%s%s' % (
self.url_scheme,
self.subdomain and self.subdomain + '.' or '',
self.server_name,
Expand Down Expand Up @@ -1366,23 +1382,22 @@ def get_default_redirect(self, route, values, query_args):

def encode_query_args(self, query_args):
if not isinstance(query_args, str):
query_args = url_encode(query_args, self.router.charset)
query_args = urlencode(query_args, self.router.charset)
return query_args

def make_redirect_url(self, path_info, query_args=None, domain_part=None):
"""Creates a redirect URL.
:internal:
"""
suffix = ''
if query_args:
suffix = '?' + self.encode_query_args(query_args)
return str('%s://%s/%s%s' % (
self.url_scheme,
self.get_host(domain_part),
posixpath.join(self.script_name[:-1].lstrip('/'),
path_info.lstrip('/')),
suffix
return urlunparse(ParseResult(
scheme=self.url_scheme or '',
netloc=self.get_host(domain_part),
path=posixpath.join(
self.script_name.strip('/'), path_info.lstrip('/')
),
query=self.encode_query_args(query_args) if query_args else '',
params=None, fragment=None
))

def make_alias_redirect_url(self, path, endpoint, values, query_args):
Expand Down Expand Up @@ -1467,10 +1482,11 @@ def build(self, endpoint, values=None, force_external=False,
host_matching = self.router.host_matching
if (host_matching and host == self.server_name) or \
(not host_matching and domain_part == self.subdomain):
return str(url_join(self.script_name, './' + path.lstrip('/')))
return str('%s://%s%s/%s' % (
self.url_scheme,
host,
self.script_name[:-1],
path.lstrip('/')
return str(urljoin(self.script_name, './' + path.lstrip('/')))

return urlunparse(ParseResult(
scheme=self.url_scheme or '',
netloc=host,
path=posixpath.join(self.script_name, path.lstrip('/')),
params=None, query=None, fragment=None
))

0 comments on commit c4d1823

Please sign in to comment.