How to make TurboGears treat '%2F' differently from '/' when routing?

64 views Asked by At

I have a simple TurboGears 2 script, named app.py:

#!/usr/bin/env python3

from wsgiref.simple_server import make_server
from tg import expose, TGController, AppConfig

class RootController(TGController):
    @expose()
    def lookup(self, name):
        return name

config = AppConfig(minimal=True, root_controller=RootController())

print("Serving on port 5000...")
httpd = make_server('', 5000, config.make_wsgi_app())
httpd.serve_forever()

When I run app.py and visit http://localhost:5000/lookup/dave, I see "dave" as expected. But when I visit http://localhost:5000/lookup/dave%2Fdavid, I get a 404 error instead of "dave/david". It seems that TurboGears is splitting 'dave%2Fdavid' into two separate arguments.

How can I get TurboGears to respect that an escaped slash is different from an unescaped slash?

2

There are 2 answers

1
Alex Henrie On BEST ANSWER

It's not possible to distinguish / from %2F in standard WSGI applications. There was a long argument about this in 2008, but the WSGI spec authors decided that compatibility with CGI--which does not distinguish between the two either--was more important than letting the programmer decide how to interpret a %2F.

In the end I decided to convert / to %252F when building paths, and then run replace('%2F', '/') on every variable I get from the path. This is not a very elegant solution, but unless the WSGI authors have a change of heart I don't see a better option.

0
amol On

For your specific example you can probably work-around that by adding *args to your lookup and join name based on them:

class RootController(TGController):
    @expose()
    def lookup(self, *args):
        name = '/'.join(args)
        return name