As a result, the following two requests are matched by the same rule:
http://foo.com/bar/baz
http://foo.com/bar%2Fbaz
Hi @houqp, the web server actually decodes the path before it makes its way into the WSGI callable (this is not unique to Falcon). The value is passed via the PATH_INFO variable in the WSGI environ.
Gunicorn includes a non-standard variable, RAW_URI with the original, percent-encoded string. uWSGI does something similar, but calls it REQUEST_URI. wsgiref only includes PATH_INFO.
I suppose the environ could be examined for one of the above non-standard variables. If found, and it contains %2F, the raw path could be decoded with the exception of any %2F triplet. Then that could be used in lieu of PATH_INFO. Alternatively, the routing engine would need to be aware of all this and use the raw form if available, then decode each path segment only after splitting on non-encoded / chars. Either way, there's a performance cost to consider.
If you'd like to try something like this in your app, you can wrap an instance of falcon.API with another WSGI callable that does the manipulation and overwrites PATH_INFO in the environ before passing it on to the falcon callable.
Depending on demand from the community, we can consider working this functionality into the framework itself, but I'm hesitant since this would rely on non-standard WSGI variables (not to mention the performance overhead, as well as potentially breaking backwards-compat in the case that some app happens to rely on the current decoding behavior).
Thanks @kgriffs for the detailed response ;)
I agree this is not a falcon issue. For now, I will work around with the custom WSGI wrapper.
That said, it might be handy to ship with a builtin wrapper(disabled by default) that handles all the non-standard WSGI variables.
Another approach that flasks took is using URL converter 1, specifically, the path converter. However, this approach has its own limitation and performance tradeoffs.
Duplicates #1895
Most helpful comment
Hi @houqp, the web server actually decodes the path before it makes its way into the WSGI callable (this is not unique to Falcon). The value is passed via the
PATH_INFOvariable in the WSGI environ.Gunicorn includes a non-standard variable,
RAW_URIwith the original, percent-encoded string. uWSGI does something similar, but calls itREQUEST_URI. wsgiref only includesPATH_INFO.I suppose the environ could be examined for one of the above non-standard variables. If found, and it contains
%2F, the raw path could be decoded with the exception of any%2Ftriplet. Then that could be used in lieu ofPATH_INFO. Alternatively, the routing engine would need to be aware of all this and use the raw form if available, then decode each path segment only after splitting on non-encoded/chars. Either way, there's a performance cost to consider.If you'd like to try something like this in your app, you can wrap an instance of
falcon.APIwith another WSGI callable that does the manipulation and overwritesPATH_INFOin the environ before passing it on to the falcon callable.Depending on demand from the community, we can consider working this functionality into the framework itself, but I'm hesitant since this would rely on non-standard WSGI variables (not to mention the performance overhead, as well as potentially breaking backwards-compat in the case that some app happens to rely on the current decoding behavior).