3

I want to use uWSGI with CGI plugin to process all requests to .py files passed from NGINX.

NGINX server config:

location ~ \.py$ {
    include         uwsgi_params;
    uwsgi_modifier1 9;
    uwsgi_pass      unix:/var/www/html/cgi-bin/wsgi.sock;
}

uWSGI config:

[uwsgi]
plugin-dir = /usr/lib/uwsgi/plugins
plugins = cgi
cgi = /var/www/html/cgi-bin
cgi-allowed-ext = .py
cgi-helper = .py=python
master = true
processes = 5
socket = wsgi.sock
chmod-socket = 664
vacuum = true
die-on-term = true

uWSGI starting output:

$ sudo -u www-data uwsgi --ini uwsgi.ini 
[uWSGI] getting INI configuration from uwsgi.ini
*** Starting uWSGI 2.0.18 (64bit) on [Fri Oct 18 15:27:33 2019] ***
compiled with version: 7.4.0 on 18 October 2019 12:14:16
os: Linux-4.15.0-65-generic #74-Ubuntu SMP Tue Sep 17 17:06:04 UTC 2019
nodename: some-host
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 4
current working directory: /var/www/html/cgi-bin
detected binary path: /usr/bin/uwsgi
your processes number limit is 15501
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address wsgi.sock fd 3
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 437424 bytes (427 KB) for 5 cores
*** Operational MODE: preforking ***
initialized CGI path: /var/www/html/cgi-bin
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 6868)
spawned uWSGI worker 1 (pid: 6869, cores: 1)
spawned uWSGI worker 2 (pid: 6870, cores: 1)
spawned uWSGI worker 3 (pid: 6871, cores: 1)
spawned uWSGI worker 4 (pid: 6872, cores: 1)
spawned uWSGI worker 5 (pid: 6873, cores: 1)

There are 2 files in /var/www/html/cgi-bin/:

  • info.py
  • some.py

If I open an URL with any other file name, I get 404 error from uWSGI - that is good. But if I open an URL with either of actual script names, then I get 500 from uWSGI (hence 502 Bad Gateway from NGINX).

URLs:

  1. http://localhost/another.py
  2. http://localhost/info.py
  3. http://localhost/some.py

Output:

[pid: 9606|app: -1|req: -1/1] 127.0.0.1 () {42 vars in 624 bytes} [Fri Oct 18 15:40:50 2019] GET /another.py => generated 9 bytes in 0 msecs (HTTP/1.1 404) 2 headers in 71 bytes (0 switches on core 0)
[pid: 9604|app: -1|req: -1/2] 127.0.0.1 () {42 vars in 618 bytes} [Fri Oct 18 15:41:01 2019] GET /info.py => generated 0 bytes in 15 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
[pid: 9606|app: -1|req: -1/3] 127.0.0.1 () {42 vars in 618 bytes} [Fri Oct 18 15:41:05 2019] GET /some.py => generated 0 bytes in 15 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)

So obviously it finds the files (info.py and some.py), but what is the reason of the 500 error from uWSGI? Do I have something wrong in either of configurations?

Here's one of the Python scripts:

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [ "Ololo".encode("utf-8") ]

uWSGI with CGI plugin is installed using instructions from documentaion:

curl http://uwsgi.it/install | bash -s cgi /tmp/uwsgi
sudo mv /tmp/uwsgi /usr/bin

I wrote a blog post with more details on the matter.

1 Answer 1

2

You're getting 500's because the uWSGI CGI plugin doesn't use WSGI, it uses CGI (took me a few hours to figure that difference out). The python script you're using implements the WSG Interface (with an "application" method) but isn't actually CGI-compatible.

To make it compatible just output the HTTP response headers, a new line, and then the HTTP body to standard out (https://en.wikipedia.org/wiki/Common_Gateway_Interface#Example).

So for your example this would become:

print("Content-Type: text/html")
print("Status: 200 OK")
print()

print("Ololo")
Sign up to request clarification or add additional context in comments.

1 Comment

Yes! That turned out to be the case. I didn't know about the difference between WSGI and CGI myself. After modifying the scripts accordingly I can now execute them in CGI mode. Thank you for taking the time to answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.