乘客+烧瓶和URL转义

时间:2015-08-01 09:02:22

标签: python flask passenger dreamhost

我正在Flask中编写一个应用程序,通过Passenger部署在Dreamhost上。我有一个设置,以便我可以使用./run.py在本地运行(env是我的virtualenv目录):

#!env/bin/python

from my_website import app
app.run(debug=True)

并部署到Dreamhost使用以下passenger_wsgi.py

#!env/bin/python
import sys, os
INTERP = os.path.join(os.getcwd(), 'env', 'bin', 'python')
if sys.executable != INTERP:
    os.execl(INTERP, INTERP, *sys.argv)
sys.path.append(os.getcwd())
from my_website import app as application

大多数东西都很好用。 然而,我遇到了一个问题,即Passenger没有像WSGI那样解码URL的PATH_INFO。例如,我有一个路线设置(在my_website/__init__.py

app.add_url_rule('/example/<key>', 'examplepage', examplepage.show_page)

对于具有简单键的页面,这对乘客和本地运行都很好。但是,如果我转到example.com/example/test%20key,我的本地开发系统examplepage.show_page会按预期使用key='test key'进行调用,但是通过Passenger将调用key='test%20key'

看起来Flask的内置HTTP服务器在它到达Flask的URL解析器之前对PATH_INFO进行URL解码,因此,%2F个字符也会过早解码;由于Flask希望URL在那时已经被URL解码,因此它不会对单个解析出的路径组件进行URL解码。但是,Passenger + WSGI保留PATH_INFO,因此URL编码的字符仍然是URL编码的(这似乎是Passenger的WSGI实现中的错误)。

那么,让乘客和./run.py之间的行为保持一致的最简单方法是什么?

1 个答案:

答案 0 :(得分:1)

这似乎运作良好(passenger_wsgi.py),虽然可能有些不妥之处:

from my_website import app

# hackish way to apply WSGI's url decoding in Passenger
import urllib2
def application(environ, start_response):
    environ["PATH_INFO"] = urllib2.unquote(environ["PATH_INFO"])
    return app(environ, start_response)

一个值得注意的问题是,这意味着当%2f可能通过Passenger时,#include<stdio.h> int main() { char str[] = "Sasindar\0Baby\0"; printf("%d\n", sizeof(str)); return 0; } 不再被正确处理;但是,正确处理它需要对Flask进行大量更改,这些更改在绝大多数WSGI堆栈上都是不兼容的。