【问题标题】:bottle + CGI always matches / route瓶子 + CGI 总是匹配 / 路由
【发布时间】:2020-04-06 12:20:29
【问题描述】:

在 CGI 环境中部署时,我无法让 Bottle 匹配除“/”之外的任何其他路由。 (不幸的是,我被托管服务提供商所困扰,不提供 FastCGI 或 WSGI)。

Bottle 位于子目录 lib 中 - 我已经从那里的 bottle-0.12.18.tar.gz 中删除了 bottle.py。

Python 是 3.5.3(提供者)或 3.8.2(本地主机)

我在.htaccess 中有以下内容

Options +ExecCGI
AddHandler cgi-script .py

Options -Indexes

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^static\/ - [L]  
  RewriteRule .* application.py [L]
</IfModule>

还有以下application.py

#!/usr/bin/python3

#setup lib path
import os
import os.path
import sys
if 'SCRIPT_NAME' in os.environ:
    MY_DIR = os.path.dirname(os.path.realpath(os.environ['SCRIPT_FILENAME']))
else:
    MY_DIR = os.environ['PWD']    
sys.path.append(os.path.join(MY_DIR,'lib'))


from bottle import Bottle

app = Bottle()

@app.route('/test')
def test():
    return '<b>matched @app.route("/test") - Testing: One, Two</b>!'

@app.route('/')
def index():
    r = ""
    for p in os.environ.keys():
        r += "{0} : {1}\n".format(p,os.environ[p])
    return '<b>matched @app.route("/")</b>\n<pre>'+r+'</pre>'

app.run(server='cgi')

无论我请求什么 URL,这总是返回来自 index() 的输出。

从输出

matched @app.route("/")

APP_ENGINE : phpcgi
APP_ENGINE_VERSION : 7.3
AUTH_TYPE : Basic
CFG_CLUSTER : cluster003
DOCUMENT_ROOT : /home/somethinguxiz/www-dev
ENVIRONMENT : production
GATEWAY_INTERFACE : CGI/1.1
HOME : /homez.907/somethinguxiz
HTTP_ACCEPT_ENCODING : gzip, deflate, br
HTTP_ACCEPT_LANGUAGE : en,de-DE;q=0.7,de;q=0.3
HTTP_ACCEPT : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
HTTP_DNT : 1
HTTP_FORWARDED : for=51.xxx.xxx.xxx; proto=https; host=dev.something.else
HTTP_HOST : dev.something.else
HTTP_REMOTE_IP : 90.xxx.xxx.xxx
HTTPS : on
HTTP_UPGRADE_INSECURE_REQUESTS : 1
HTTP_USER_AGENT : Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
HTTP_X_FORWARDED_FOR : 90.xxx.xxx.xxx
HTTP_X_FORWARDED_PORT : 443
HTTP_X_FORWARDED_PROTO : https
HTTP_X_PREDICTOR : 1
HTTP_X_REMOTE_IP : 51.xxx.xxx.xxx
HTTP_X_REMOTE_PORT : 64440
HTTP_X_REMOTE_PROTO : https
PATH : /usr/local/bin:/usr/bin:/bin
PHP_VER : 5_TEST
PWD : /homez.907/somethinguxiz/www-dev
QUERY_STRING : 
REDIRECT_STATUS : 200
REDIRECT_URL : /test
REGISTER_GLOBALS : 0
REMOTE_ADDR : 90.xxx.xxx.xxx
REMOTE_PORT : 17926
REMOTE_USER : csomething
REQUEST_METHOD : GET
REQUEST_URI : /test
SCRIPT_FILENAME : /home/somethinguxiz/www-dev/application.py
SCRIPT_NAME : /application.py
SCRIPT_URI : https://dev.something.else:443/test
SCRIPT_URL : /test
SERVER_ADDR : 51.xxx.xxx.xxx
SERVER_ADMIN : postmaster@dev.something.else
SERVER_NAME : dev.something.else
SERVER_PORT : 443
SERVER_PROTOCOL : HTTP/1.1
SERVER_SIGNATURE : 
SERVER_SOFTWARE : Apache
UID : somethinguxiz

即脚本确实看到了REQUEST_URI,但它不会触发test(),而是index()!?

任何想法,指针?

编辑: 除非它在某处被删除,否则上面的列表中缺少PATH_INFO,但如果我正确理解 CGI 规范,它应该在那里。这也是瓶子在其 match() 方法中使用的内容。如果不存在,它会退回到/(这说明总是调用index()

编辑:移动解决方案文本以回答

【问题讨论】:

    标签: python apache routes cgi bottle


    【解决方案1】:

    PATH_INFO 仅在路径超出 cgi 脚本时设置。虽然我最初的意图是让那个隐形,但我已经同意在这里有一个应用程序名称。另外,与[END] 相比,在重写规则中使用[L] 是有区别的。

    因此我解决了以下.htaccess

    
    Options +ExecCGI                                                                                                                     
    AddHandler cgi-script .py                                                                                                            
    AcceptPathInfo on                                                                                                                    
    
    Options -Indexes                                                                                                                     
    
    <IfModule mod_rewrite.c>                                                                                                             
        RewriteEngine On                                                                                                                 
        RewriteOptions IgnoreInherit                                                                                                     
        RewriteBase /                                                                                                              
        RewriteRule ^demo\/(static\/.*)$ $1 [END]                                                                                        
        RewriteRule ^demo(/.*)$ application.py$1 [END]                                                                                   
        RewriteRule ^demo$ application.py [END]                                                                                           
        RewriteRule !^demo$ demo [R,END]                                                                                                  
    </IfModule>                                                                                                                          
    
    

    它允许在应用程序逻辑位于 application.py 时从 httpd 提供静态内容 - 隐藏为 demo。其他任何东西都会重定向到前门。

    申请地址为.../demo, 应用程序中的页面位于.../demo/path/to/page,并且 httpd 提供的资源位于.../demo/static/path/to/ressource

    【讨论】:

      猜你喜欢
      • 2018-06-17
      • 2016-04-28
      • 2019-07-20
      • 2018-03-31
      • 1970-01-01
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 2020-04-05
      相关资源
      最近更新 更多