`uwsgi_modifier1 30`指令未如文档所述移除PATH_INFO中的SCRIPT_NAME

11 投票
1 回答
4051 浏览
提问于 2025-04-17 23:51

这是我设置的nginx虚拟主机配置。

debian:~# cat /etc/nginx/sites-enabled/mybox
server {
    listen 8080;
    root /www;
    index index.html index.htm;
    server_name mybox;
    location /foo {
        uwsgi_pass unix:/tmp/uwsgi.sock;
        include uwsgi_params;
        uwsgi_param SCRIPT_NAME /foo;
        uwsgi_modifier1 30;
    }
}

这是我的WSGI应用的源代码。

debian:~# cat /www/app.py
def application(environ, start_response):
    path_info = script_name = request_uri = None

    if 'PATH_INFO' in environ:
        path_info = environ['PATH_INFO']

    if 'SCRIPT_NAME' in environ:
        script_name = environ['SCRIPT_NAME']

    if 'REQUEST_URI' in environ:
        request_uri = environ['REQUEST_URI']

    output = 'PATH_INFO: ' + repr(path_info) + '\n' + \
             'SCRIPT_NAME: ' + repr(script_name) + '\n' + \
             'REQUEST_URL: ' + repr(request_uri) + '\n'

    start_response('200 OK', [('Content-Type','text/plain')])
    return [output.encode()]

我用这两个命令来运行我的WSGI应用:

service nginx restart
uwsgi -s /tmp/uwsgi.sock -w app --chown-socket=www-data:www-data

当我尝试访问我的网页应用时,看到的输出是这样的。

debian:~# curl http://mybox:8080/foo/bar
PATH_INFO: '/foo/bar'
SCRIPT_NAME: '/foo'
REQUEST_URL: '/foo/bar'

因为我在nginx虚拟主机配置中提到了 uwsgi_modifier1 30;,所以我原本期待PATH_INFO只会是 '/bar',就像下面这两个网址中解释的那样:

引用第一篇文章中的相关部分:

uwsgi_modifier1 30 这个选项设置了uWSGI的修改器 UWSGI_MODIFIER_MANAGE_PATH_INFO。这个每次请求的修改器指示uWSGI服务器重写PATH_INFO的值,去掉SCRIPT_NAME部分。

引用第二篇文章中的相关部分:

标准的WSGI请求后面跟着HTTP请求体。PATH_INFO会自动被修改,去掉SCRIPT_NAME部分。

但是我发现我的PATH_INFO保持不变,仍然是 '/foo/bar'。SCRIPT_NAME部分,也就是 '/foo' 并没有被去掉。为什么会这样呢?

1 个回答

13

在阅读了这个链接之后,我明白了使用uwsgi_modifier1 30;这个设置已经不推荐用了。

所以我找到了这样解决问题的方法。

首先,我在nginx中去掉了对SCRIPT_NAME的处理,具体是删掉了这两行:

    uwsgi_param SCRIPT_NAME /foo;
    uwsgi_modifier1 30;

这样修改后,nginx的配置看起来是这样的:

debian:~# cat /etc/nginx/sites-enabled/mybox
server {
    listen 8080;
    root /www;
    index index.html index.htm;
    server_name mybox;
    location /foo {
        uwsgi_pass unix:/tmp/uwsgi.sock;
        include uwsgi_params;
    }
}

接着,我重启了nginx,并在uwsgi中使用--mount--manage-script-name这两个选项来处理SCRIPT_NAME,像这样:

service nginx restart
uwsgi -s /tmp/uwsgi.sock -w app --chown-socket=www-data:www-data --manage-script-name --mount=/foo=/www/app.py

现在,我得到了预期的输出结果。

debian:~# curl http://mybox:8080/foo/bar
PATH_INFO: '/bar'
SCRIPT_NAME: '/foo'
REQUEST_URL: '/foo/bar'

撰写回答