uWSGI: добавление обработки CGI-сценариев

Автор: | 11/15/2014
 

uwsgiКраткая заметка.

Предполагается, что uWSGI и NGINX уже установлены и настроены, например — как описано тут>>>.

Если uWSGI уже установлен — бекапим его:

# mv /usr/bin/uwsgi /home/setevoy/backups/

Запускаем сборку:

# cd /tmp
# curl http://uwsgi.it/install | bash -s cgi /usr/bin/uwsgi
...
*** uWSGI compiling embedded plugins ***
[gcc -pthread] plugins/cgi/cgi_plugin.o
...
############## end of uWSGI configuration #############
total build time: 78 seconds
*** uWSGI is ready, launch it with /usr/bin/uwsgi ***

Проверяем:

# which uwsgi
/usr/bin/uwsgi

Поверяем наличие модуля cgi:

# uwsgi --plugins-list
...
*** uWSGI loaded request plugins ***
9: cgi
...

В каталоге /etc/uwsgi/ создаём файл /etc/uwsgi/testing.domain.org.ua.ini:

[uwsgi]
plugins = cgi
socket = 127.0.0.1:9090
http-modifier1 = 9
cgi = /=/var/www/vhosts/setevoy/testing.domain.org.ua/
cgi-allowed-ext = .py
cgi-helper = .py=python

Для NGINX создаём файл конфигурации /etc/nginx/conf.d/testing.domain.kiev.ua.conf:

server {
    server_name testing.domain.org.ua;
    access_log /var/log/nginx/testing.domain.org.ua-access.log;
    error_log /var/log/nginx/testing.domain.org.ua-error.log;
    root /var/www/vhosts/setevoy/testing.domain.org.ua;

    location /
    {
        uwsgi_pass 127.0.0.1:9090;
        uwsgi_modifier1 9;
        include uwsgi_params;
   }
}

Проверяем:

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Перезапускаем:

# service nginx restart
Stopping nginx: [ OK ]
Starting nginx: [ OK ]

В каталоге /var/www/vhosts/setevoy/testing.domain.org.ua создаём скрипт index.py:

#!/usr/bin/python
print "Content-type: text/htmlnn"
print "<html><body><h1>It works!</h1></body></html>"

Запускаем uWSGI:

# uwsgi /etc/uwsgi/testing.domain.org.ua.ini
[uWSGI] getting INI configuration from /etc/uwsgi/testing.domain.org.ua.ini
open("./cgi_plugin.so"): No such file or directory [core/utils.c line 3675]
!!! UNABLE to load uWSGI plugin: ./cgi_plugin.so: cannot open shared object file: No such file or directory !!!
*** Starting uWSGI 2.0.8 (64bit) on [Mon Nov 10 17:39:27 2014] ***
compiled with version: 4.4.7 20120313 (Red Hat 4.4.7-11) on 10 November 2014 17:31:07
os: Linux-2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014
nodename: venti.domain.org.ua
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /var/www/vhosts/setevoy/testing.domain.org.ua
detected binary path: /usr/bin/uwsgi
uWSGI running as root, you can use --uid/--gid/--chroot options
*** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 7803
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 TCP address 127.0.0.1:9090 fd 3
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72768 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
initialized CGI mountpoint: / = /var/www/vhosts/setevoy/testing.domain.org.ua/
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 697, cores: 1)

Проверяем:

# curl http://testing.domain.org.ua/index.py
<html><body><h1>It works!</h1></body></html>

В логе uWSGI видим запись:

[pid: 697|app: -1|req: -1/1] 77.***.***.20 () {30 vars in 491 bytes} [Mon Nov 10 17:39:28 2014] GET /index.py => generated 46 bytes in 11 msecs (HTTP/1.1 200) 1 headers in 44 bytes (0 switches on core 0)

Либо — возьмём более сложный пример, с запросами типа <form></form> и использованием метода cgi.FieldStorage():

#!/usr/bin/python

import cgi, MySQLdb
import cgitb; cgitb.enable()

data = None
form = cgi.FieldStorage()

def myver(host, user, pwd, cmd):
        db = MySQLdb.connect(host, user, pwd)
        cursor = db.cursor()
        cursor.execute(cmd)
        global data
        data = cursor.fetchone()
        db.close()

getvers = form.getvalue('getvers')
exit = form.getvalue('exit')

print "Content-type:text/htmlrnrn"
print "<title>Test to get MySQL version</title>"
print "<h2>MySQL version</h2>"
print '''Get version: <form action="mysql.py" method="get">
<input type="submit" name="getvers" value="Get version" />
<input type="submit" name="exit" value="Exit" />
</form>
'''

if getvers:
        myver('localhost', 'root', 'мегапассворд', 'SELECT VERSION()')
        print('Current MySQL version: %s ' % data)
elif exit:
        print('Exit')

Результат:

# curl http://testing.domain.org.ua/mysql.py?getvers=Get+version

<title>Test to get MySQL version</title>
<h2>MySQL version</h2>
Get version: <form action="mysql.py" method="get">
<input type="submit" name="getvers" value="Get version" />
<input type="submit" name="exit" value="Exit" />
</form>

Current MySQL version: 5.5.40-MariaDB-log