URL() args encoding

1,255 views
Skip to first unread message

(m)

unread,
Jul 13, 2011, 5:55:49 PM7/13/11
to web2py-users
My Web-programming and Python noobs continues to show. Thanks for
bearing with me.

I have a view with a fragment along the lines of the following to
generates a list of links. foos has been generated in the controller.

{{for foo in foos:}}
<li><a href="{{=URL('show', args=foo.name)}}">{{=foo.name}}</a></li>
{{pass}}

This works fine until foo.name has spaces and/or other URL-unfriendly
chars in it. So the questions are:

* Does web2py have its own mechanism for encoding/decoding URLs that
is useful here?
* If not, what is the preferred Python lib for doing URL encoding/
decoding?

(P.S. I am aware that there are other ways of addressing this issue:
e.g., use vars (which web2py seems to automatically encode) instead of
args, or use args=foo.id instead or args=foo.name. In any event, it'd
be good to know the web2py way to encode/decode URLs.)

pbreit

unread,
Jul 13, 2011, 6:19:10 PM7/13/11
to web...@googlegroups.com

Anthony

unread,
Jul 13, 2011, 7:31:44 PM7/13/11
to web...@googlegroups.com
If you've got keys and values in a dictionary that you want to convert to a query string, you would use urllib.urlencode (which is what the web2py URL function uses for vars). To quote just a plain string (like an arg), you can use urllib.quote() or urllib.quote_plus() (the latter converts each space to a '+' instead of a '%20'). If you want to convert back, you can use urllib.unquote() or urllib.unquote_plus() (though I think that will be handled automatically anyway).
 
Anthony

(m)

unread,
Jul 14, 2011, 6:27:09 AM7/14/11
to web2py-users
Awesome and thanx. I got that working and am able to generate URLs of
the form I wanted.

But I've now discovered that web2py seems to be doing some additional
URL processing that I can't isolate.

Assume a controller:

def baz():
orb = request.args[0]
return dict(orb=orb)

With a view that just renders orb:

{{extend 'layout.html'}}
<h1>Baz</h1>
<p>{{=orb}}</p>

When I type in a URL of the form:

http://localhost:8000/simple_app/default/baz/laa%20poo

the value of orb that gets passed to the view appears to be

laa_poo

In other words, the encoded space got converted to an underscore
somewhere.

Who is doing this and where are its rules documented? (I'm guessing
it's part of a security measure to prevent arbitrary stuff being
passed as args -- is this right?)

Anthony

unread,
Jul 14, 2011, 8:17:15 AM7/14/11
to web...@googlegroups.com
I cannot reproduce this problem. For me, 'laa%20poo' is converted to 'laa poo' (i.e., the '%20' is properly converted to a space, not an underscore). What version of web2py are you using? Are you using the built-in Rocket server?
 
Anthony

On Thursday, July 14, 2011 6:27:09 AM UTC-4, (m) wrote:
Awesome and thanx. I got that working and am able to generate URLs of
the form I wanted.

But I've now discovered that web2py seems to be doing some additional
URL processing that I can't isolate.

Assume a controller:

def baz():
    orb = request.args[0]
    return dict(orb=orb)

With a view that just renders orb:

{{extend 'layout.html'}}
<h1>Baz</h1>
<p>{{=orb}}</p>

When I type in a URL of the form:

http://localhost:8000/simple_app/default/baz/laa%20poo

the value of orb that gets passed to the view appears to be

laa_poo

In other words, the encoded space got converted to an underscore
somewhere.

Who is doing this and where are its rules documented? (I'm guessing
it's part of a security measure to prevent arbitrary stuff being
passed as args -- is this right?)


Jonathan Lundell

unread,
Jul 14, 2011, 10:32:49 AM7/14/11
to web...@googlegroups.com
On Jul 14, 2011, at 5:17 AM, Anthony wrote:
I cannot reproduce this problem. For me, 'laa%20poo' is converted to 'laa poo' (i.e., the '%20' is properly converted to a space, not an underscore). What version of web2py are you using? Are you using the built-in Rocket server?

Are you (Anthony) using the parametric router? The standard handling of incoming URLs (with no router or the pattern-based router) converts spaces to underscores. The parametric router does not.

If you're not using the parametric router, you'll find the untranslated args in request.raw_args, a single string that you'll need to split. 

If you're not using the parametric router and you want to take complete responsibility for dealing with args (this, importantly, includes validating them, because normal validation is bypassed), you can add your app name to routes_apps_raw.

My recommendation: use the parametric router (see router.example.py), even if you disable rewriting.

Anthony

unread,
Jul 14, 2011, 10:44:21 AM7/14/11
to web...@googlegroups.com
On Thursday, July 14, 2011 10:32:49 AM UTC-4, Jonathan Lundell wrote:
On Jul 14, 2011, at 5:17 AM, Anthony wrote:
I cannot reproduce this problem. For me, 'laa%20poo' is converted to 'laa poo' (i.e., the '%20' is properly converted to a space, not an underscore). What version of web2py are you using? Are you using the built-in Rocket server?

Are you (Anthony) using the parametric router? The standard handling of incoming URLs (with no router or the pattern-based router) converts spaces to underscores. The parametric router does not.
 
Oops, yes, I'm using the parametric router. Thanks for clearing that up.
 
Anthony
Reply all
Reply to author
Forward
0 new messages