Я пишу приложение на Flask, которое будет развернуто на Dreamhost через Passenger. У меня есть такая настройка, что я могу работать локально, используя ./run.py
(env
- это мой виртуальный каталог):
#!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 не декодирует PATH_INFO
URL-адреса, как должен делать WSGI. Например, у меня настроен маршрут (в 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'
.
Похоже, что встроенный HTTP-сервер Flask декодирует URL-адрес PATH_INFO
еще до того, как он попадет в парсер URL-адресов Flask, поэтому в результате %2F
символов также преждевременно декодируются; поскольку Flask ожидает, что URL-адрес уже будет декодирован URL-адресом в этот момент, он не выполняет декодирование URL-адресов отдельных проанализированных компонентов пути. Однако Passenger + WSGI сохраняет PATH_INFO
, и, таким образом, символы в кодировке URL остаются в кодировке URL (что, по-видимому, является ошибкой в реализации WSGI Passenger).
Итак, каков самый простой способ согласовать поведение пассажира и ./run.py
?