Jan. 24th, 2019

victor_sudakov: (Default)
nginx, в отличие например от Apache httpd, не умеет сам запускать CGI-скрипты, ему нужен внешний сервер приложений, с которым nginx будет общаться по протоколу FastCGI или другому.

Если не нужна высокая производительность или фичи, а просто хочется эмулировать функционал апачевского mod_cgi, то проще всего поставить из портов демон www/fcgiwrap и передавать ему запросы через Unix socket. При запуске демона очень желательно указывать fcgiwrap_flags="-f", иначе ошибки fcgiwrap будут уходить в никуда (а при -f будут видны в nginx/error.log). И при необходимости перезапустить его вручную надо не забывать очистить переменные среды (например "env -i /usr/local/etc/rc.d/fcgiwrap restart"), иначе весь environment рута станет виден в CGI-скриптах).

Если CGI-скрипты планируется держать в /usr/local/www/cgi-bin/, а сокет для обмена между nginx и fcgiwrap в /tmp/fcgiwrap.socket, то секция nginx.conf должна выглядеть так:

        location /cgi-bin/ {
            root   /usr/local/www;
            include /usr/local/etc/nginx/fastcgi_params;
            fastcgi_pass unix:/tmp/fcgiwrap.socket;
        }


Обратите внимание, что в директиве root отсутствует "cgi-bin", хотя это реальный каталог на диске, в котором хранятся скрипты. Почему так?

Дело в том, что путь к скрипту задаётся (передаётся в fcgiwrap) склеиванием двух переменных: DOCUMENT_ROOT и SCRIPT_NAME, в которые мапятся (в fastcgi_params) nginx-овские переменные $document_root и $fastcgi_script_name соответственно. По умолчанию $fastcgi_script_name=$request_uri, то есть при обращении к
http://myserver.example/cgi-bin/myscript
fcgiwrap получит команду найти на диске и выполнить "/usr/local/www"+"/cgi-bin/myscript". Естественно $fastcgi_script_name можно переопределить, например с помощью $fastcgi_split_path_info, но для простейшей эмуляции mod_cgi это не нужно.

Отлаживать скрипты вообще без веб-сервера можно как показано ниже, заодно это помогает лучше понять протокол обмена:

#!/bin/sh -x

DOCUMENT_ROOT=/usr/local/www/ ; export DOCUMENT_ROOT
REQUEST_URI=/cgi-bin/myscript ; export REQUEST_URI
SCRIPT_NAME=$REQUEST_URI; export SCRIPT_NAME
REQUEST_METHOD=GET ; export REQUEST_METHOD
su -m www -c '/usr/local/bin/cgi-fcgi -bind -connect /tmp/fcgiwrap.socket'

Profile

victor_sudakov: (Default)
Виктор Судаков

December 2024

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Aug. 31st, 2025 04:48 pm
Powered by Dreamwidth Studios