如何使用wsgiref CGIHandler摆脱运行Flask App的额外cgi-bin url组件?

时间:2017-08-06 11:19:20

标签: python url flask wsgiref

我正在使用不直接支持wsgi应用的共享cpanel托管计划。所以我必须使用wsgiref CGIHandler解决方法,如下所述:http://flask.pocoo.org/docs/0.12/deploying/cgi/

这一切都有效并产生了预期的结果,但是网址中总有这些额外的内容:“/ 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()

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

我找到了它的黑客......但它只是一个黑客:-( 如果我在wsgiref CGIHandler脚本中覆盖SCRIPT_NAME环境变量的值,那么它可以很好地工作。

这是更新后的代码:

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'] 值是什么,每次请求页面时,它都会以烧录应用程序网址为前缀。

我仍在寻找更优雅的#pythonic"虽然解决方案..