`uwsgi_modifier1 30`指令未如文档所述移除PATH_INFO中的SCRIPT_NAME
这是我设置的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'
,就像下面这两个网址中解释的那样:
- http://uwsgi-docs.readthedocs.org/en/latest/Nginx.html
- http://blog.codepainters.com/2012/08/05/wsgi-deployment-under-a-subpath-using-uwsgi-and-nginx/
引用第一篇文章中的相关部分:
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'