【问题标题】:Passenger+flask and URL escaping乘客+烧瓶和 URL 转义
【发布时间】:2015-08-01 09:02:21
【问题描述】:

我正在 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)

对于带有简单键的页面,这在Passenger 和本地运行都可以正常工作。但是,如果我去,例如,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 实现中的一个错误)。

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

【问题讨论】:

    标签: python flask passenger dreamhost


    【解决方案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;但是,正确处理它需要对 Flask 进行大量更改,这在绝大多数 WSGI 堆栈上是不兼容的。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    相关资源
    最近更新 更多