Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The `uwsgi_modifier1 30` directive is not removing the SCRIPT_NAME from PATH_INFO as documented

This is my nginx virtual host configuration.

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;
    }
}

This is the source code of my WSGI application.

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()]

I serve my WSGI application with these two commands:

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

This is the output I see when I try to visit my web application.

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

Since I have mentioned uwsgi_modifier1 30; in my nginx virtual host configuration, I was expecting the PATH_INFO to be only '/bar' as explained in the following two URLs:

  • 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/

Quoting the relevant part from the first article:

The uwsgi_modifier1 30 option sets the uWSGI modifier UWSGI_MODIFIER_MANAGE_PATH_INFO. This per-request modifier instructs the uWSGI server to rewrite the PATH_INFO value removing the SCRIPT_NAME from it.

Quoting the relevant part from the second article:

Standard WSGI request followed by the HTTP request body. The PATH_INFO is automatically modified, removing the SCRIPT_NAME from it.

But I see that my PATH_INFO remains intact as '/foo/bar'. The SCRIPT_NAME part, i.e. '/foo' has not been removed from it. Why?

like image 296
Lone Learner Avatar asked Mar 25 '14 17:03

Lone Learner


1 Answers

After reading https://github.com/unbit/uwsgi/pull/19 I understood that using uwsgi_modifier1 30; is deprecated.

So this is how I solved the problem.

First of all I removed SCRIPT_NAME handling in nginx by removing these two lines:

    uwsgi_param SCRIPT_NAME /foo;
    uwsgi_modifier1 30;

The resulting nginx configuration looked like this:

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;
    }
}

Then I restarted nginx and did SCRIPT_NAME handling in uwsgi using the --mount and --manage-script-name options like this.

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

Now, I get the expected output.

debian:~# curl http://mybox:8080/foo/bar
PATH_INFO: '/bar'
SCRIPT_NAME: '/foo'
REQUEST_URL: '/foo/bar'
like image 128
Lone Learner Avatar answered Sep 30 '22 04:09

Lone Learner