سؤال

I wrote a simple bottle application in /www/app.py.

import bottle

app = bottle.Bottle()
@app.route('/')
def index():
    return 'hello from bottle'

application=app

I have configured my nginx virtual host in a file called /etc/nginx/sites-enabled/foo:

server {
    listen 8080;
    root /www;
    index index.html index.htm;
    server_name foo;
    location / {
        uwsgi_pass 127.0.0.1:9090;
    }
}

I start nginx and uwsgi in this manner:

service nginx restart
uwsgi --socket 127.0.0.1:9090 --wsgi-file app.py

But when I try to visit http://foo/ I get this error in the web page:

Critical error while processing request: /

And I get this error in the uwsgi output:

Traceback (most recent call last):
  File "/usr/local/lib/python3.3/dist-packages/bottle.py", line 954, in wsgi
    out = self._cast(self._handle(environ))
  File "/usr/local/lib/python3.3/dist-packages/bottle.py", line 845, in _handle
    path = environ['bottle.raw_path'] = environ['PATH_INFO']
KeyError: 'PATH_INFO'

I suspected that it could be that the nginx + uwsgi environment is not providing environ['PATH_INFO'] value to my application, so I write a bare WSGI application to confirm it. I replaced the code in app.py with this:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    print('----- begun environ -----')
    for k, v in environ.items():
        print('environ[{}] = {}'.format(k, v))
    print('----- ended environ -----')
    return [b'<p>Hello World</p>']

And sure enough I don't see PATH_INFO in the uwsgi output:

----- begun environ -----
environ[uwsgi.version] = b'2.0.2'
environ[HTTP_ACCEPT_ENCODING] = gzip, deflate
environ[HTTP_CACHE_CONTROL] = max-age=0
environ[wsgi.multithread] = False
environ[HTTP_HOST] = foo:8080
environ[wsgi.input] = <uwsgi._Input object at 0x7f990a7019d8>
environ[wsgi.url_scheme] = http
environ[HTTP_USER_AGENT] = Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
environ[HTTP_ACCEPT_LANGUAGE] = en-US,en;q=0.5
environ[uwsgi.node] = b'nifty'
environ[wsgi.errors] = <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>
environ[wsgi.multiprocess] = False
environ[wsgi.run_once] = False
environ[wsgi.version] = (1, 0)
environ[HTTP_CONNECTION] = keep-alive
environ[HTTP_ACCEPT] = text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
environ[wsgi.file_wrapper] = <built-in function uwsgi_sendfile>
----- ended environ -----

What should I do so that my app or bottle app can get environ['PATH_INFO']?

هل كانت مفيدة؟

المحلول

Depending on what server platform you're using, there should be uwsgi_params config file which sets these parameters in your /etc/nginx directory. You can include it in your nginx config like so:

server {
    listen 8080;
    root /www;
    index index.html index.htm;
    server_name foo;
    location / {
        include uwsgi_params;
        uwsgi_pass 127.0.0.1:9090;
    }
}

If you don't have this file, this is the content of my local nginx server, which would probably also work for you:

menno@mimic:/etc/nginx$ nginx -v
nginx version: nginx/1.1.19

menno@mimic:/etc/nginx$ cat uwsgi_params
uwsgi_param     QUERY_STRING            $query_string;
uwsgi_param     REQUEST_METHOD          $request_method;
uwsgi_param     CONTENT_TYPE            $content_type;
uwsgi_param     CONTENT_LENGTH          $content_length;

uwsgi_param     REQUEST_URI             $request_uri;
uwsgi_param     PATH_INFO               $document_uri;
uwsgi_param     DOCUMENT_ROOT           $document_root;
uwsgi_param     SERVER_PROTOCOL         $server_protocol;

uwsgi_param     REMOTE_ADDR             $remote_addr;
uwsgi_param     REMOTE_PORT             $remote_port;
uwsgi_param     SERVER_PORT             $server_port;
uwsgi_param     SERVER_NAME             $server_name;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top