Как избавиться от дополнительных компонентов cgi-bin url, запускающих приложение Flask с помощью wsgiref CGIHandler?
У меня общий хостинг cpanel, который не поддерживает приложения wsgi напрямую. Поэтому я должен использовать обходной путь wsgiref CGIHandler, как описано здесь: http://flask.pocoo.org/docs/0.12/deploying/cgi/.
Все это работает и дает ожидаемые результаты, но в URL-адресах всегда есть дополнительные данные: "/cgi-bin/index.cgi/", которые приложение python, кажется, добавляет автоматически (чтобы соответствовать тому, что оно обнаруживает при вызове cgi обработчик).
Например, мне бы хотелось, чтобы это был myhost.com/login/ вместо myhost.com/cgi-bin/index.cgi/login/ или myhost.com/ вместо myhost.com/cgi-bin/index.cgi /.
Все эти более короткие версии ссылок работают хорошо, потому что правила переписывания движка уже существуют. Я проверил это. Это всего лишь вопрос того, как заставить приложение фляги избавиться от "/cgi-bin/index.cgi/".
Некоторые из моего кода:
cat www/.htaccess
# Redirect everything to CGI WSGI handler, but Don't interfere with static files
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /cgi-bin/index.cgi/$1 [L]
,
cat www/cgi-bin/index.cgi
#!/home/myhost/myhost.com/flasky/venv/bin/python
import os
import sys
sys.path.insert(0, '/home/myhost/myhost.com/flasky/venv/lib/python2.7/site-packages')
sys.path.insert(0, '/home/myhost/myhost.com/flasky')
from wsgiref.handlers import CGIHandler
from manage import app
CGIHandler().run(app)
,
cat www/flasky/manage.py
#!/usr/bin/env python
import os
from app import create_app, db
from app.models import User, Role, Permission
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
app = create_app(os.getenv('FLASK_CONFIG') or 'default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db, User=User, Role=Role,
Permission=Permission)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
,
Есть идеи?
Спасибо!
1 ответ
cat www/cgi-bin/index.cgi
#!/home/myhost/myhost.com/flasky/venv/bin/python
import os
import sys
sys.path.insert(0, '/home/myhost/myhost.com/flasky/venv/lib/python2.7/site-packages')
sys.path.insert(0, '/home/myhost/myhost.com/flasky')
from wsgiref.handlers import CGIHandler
from manage import app
class ScriptNameStripper(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
app = ScriptNameStripper(app)
CGIHandler().run(app)
Я нашел хак для него... но это просто хак:-(Если я переопределил значение переменной окружения SCRIPT_NAME в скрипте wsgiref CGIHandler, тогда он отлично работает.
Вот обновленный код:
cat www/cgi-bin/index.cgi
#!/home/myhost/myhost.com/flasky/venv/bin/python
import os
import sys
sys.path.insert(0, '/home/myhost/myhost.com/flasky/venv/lib/python2.7/site-packages')
sys.path.insert(0, '/home/myhost/myhost.com/flasky')
from wsgiref.handlers import CGIHandler
from manage import app
os.environ['SCRIPT_NAME'] = ''
CGIHandler().run(app)
,
В принципе, каким бы ни было значение os.environ['SCRIPT_NAME'], оно будет добавляться к URL-адресу приложения фляги каждый раз, когда запрашивается страница.
Я все еще ищу более изящное "питоническое" решение хотя..