Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unquote path before injecting into environment #1263

Closed
bhearsum opened this issue May 24, 2016 · 5 comments
Closed

unquote path before injecting into environment #1263

bhearsum opened this issue May 24, 2016 · 5 comments

Comments

@bhearsum
Copy link
Contributor

While migrating an application from mod_wsgi -> uwsgi I discovered that some of my routes were not working -- specifically those that can contain quoted characters like @ or :

I did some digging on this, and according to this gunicorn thread, PATH_INFO is required to be unquoted: benoitc/gunicorn#1211 (comment).

AFAICT, uwsgi does not unquote paths by default nor is there a way to enable it (short of manually writing some route processing hacks). If that thread is correct, uwsgi should be doing this. It's also possible I've misunderstood the contract between the wsgi server and the app.

@bhearsum
Copy link
Contributor Author

This can be seen pretty clearly in https://www.python.org/dev/peps/pep-3333/#url-reconstruction, which shows the re-quoting of PATH_INFO when trying to construct the original URL.

@unbit
Copy link
Owner

unbit commented May 25, 2016

The PATH_INFO is managed here: https://github.com/unbit/uwsgi/blob/master/proto/http.c#L217
for the http protocol. For the lower-level protocols (uwsgi, scgi, fastcgi) it gets what the webserver passes.

I am pretty sure nginx passes the right PATH_INFO

@bhearsum
Copy link
Contributor Author

I'm pretty sure I'm working in http mode (with uwsgi 2.0.11.2, for what it's worth), and not getting the path decode. Concretely, here's my config:

[uwsgi]
http = :8080
mount = /=/app/uwsgi/admin.wsgi
manage-script-name = 1
check-static = /app/ui/dist
static-index = index.html
route-uri = ^/api/(.*)$ rewrite:/$1
route-uri = ^/api/(.*)$ continue:
route-if = startswith:${REQUEST_URI};/__ continue:
route-if-not = exists:/app/ui/dist${PATH_INFO} static:/app/ui/dist/index.html

And if I make a request such as:
[pid: 105|app: 0|req: 7/7] 172.17.42.1 () {50 vars in 957 bytes} [Wed May 25 17:10:01 2016] PUT /api/users/foo%40blah.com/permissions/admin => generated 23 bytes in 40 msecs (HTTP/1.1 201) 5 headers in 322 bytes (1 switches on core 0)

I end up with a foo%40blah.com permission, instead of [email protected].

(Apologies if this is turning into a support request...)

@unbit
Copy link
Owner

unbit commented May 26, 2016

Can you try with a simpler config without the rewrite rule ?

def application(e, sr):
    headers = [ ('Foo', 'Bar')]
    sr('200 OK', headers)
    return [e['PATH_INFO']]

uwsgi --http :8080 --wsgi-file foo.py

Returns the expected output

Maybe the rewrite plugin is broken ?

@bhearsum
Copy link
Contributor Author

Indeed - if I remove all of the routing options, the path is unquoted as expected. If I just add the rewrite back, unquoting fails to happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants