Quote variable values in url_for()

This commit is contained in:
Kovid Goyal 2015-06-14 20:03:11 +05:30
parent 33e47e424c
commit dc7cf2cfdc
2 changed files with 14 additions and 0 deletions

View File

@ -7,6 +7,7 @@ __license__ = 'GPL v3'
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
import httplib, sys, inspect, re, time, numbers, json as jsonlib
from urllib import quote as urlquote
from itertools import izip
from operator import attrgetter
@ -144,6 +145,13 @@ class Route(object):
raise RouteError('The required variable(s) %s were not specified for the route: %s' % (','.join(not_spec), self.endpoint.route))
args = self.defaults.copy()
args.update(kwargs)
def quoted(x):
if not isinstance(x, unicode) and not isinstance(x, bytes):
x = unicode(x)
if isinstance(x, unicode):
x = x.encode('utf-8')
return urlquote(x, '')
args = {k:quoted(v) for k, v in args.iteritems()}
route = self.var_pat.sub(lambda m:'{%s}' % m.group(1).partition('=')[0].lstrip('+'), self.endpoint.route)
return route.format(**args)

View File

@ -64,6 +64,10 @@ class TestRouter(BaseTest):
def soak_opt(ctx, dest, rest):
pass
@endpoint('/needs quoting/{x}')
def quoting(ctx, dest, x):
pass
for x in locals().itervalues():
if getattr(x, 'is_endpoint', False):
router.add(x)
@ -91,3 +95,5 @@ class TestRouter(BaseTest):
self.ae(ep, soak_opt), self.ae(args, ['xxx'])
ep, args = find('/soak_opt/a/b')
self.ae(ep, soak_opt), self.ae(args, ['a/b'])
self.ae(router.url_for('/needs quoting', x='a/b c'), '/needs quoting/a%2Fb%20c')