This shows you the differences between two versions of the page.
Next revision | Previous revisionLast revisionBoth sides next revision | ||
software:perl:fastcgi [2015/05/20 18:24] – создано root | software:perl:fastcgi [2022/02/05 03:59] – root | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{tag> | ||
+ | |||
====== Perl fastcgi daemon ====== | ====== Perl fastcgi daemon ====== | ||
- | Поставил nginx вместо lighttpd | + | Nginx, в отличии от lighttpd |
- | Не нашёл ничего чтобы работало демоном для перла по fast-cgi. | + | |
- | Зато было две модификации перлового | + | |
- | Пришлось самому его дописывать и делать обёртку стартового | + | |
- | chroot | + | |
+ | ---- | ||
- | Пример настроек в rc.conf: | + | <note important> |
- | [code]perl_fcgi_enable=" | + | Так же хорошо работает uWSGI, инструкции по настройке: |
+ | |||
+ | ---- | ||
+ | |||
+ | Демон не моя | ||
+ | Работа chroot не проверялась, | ||
+ | Часть не реализованных в демоне опций выполняется стартовым скриптом (chroot, смена пользователя и группы), | ||
+ | |||
+ | **Стартовый скрипт**: | ||
+ | **Демон**: [[http:// | ||
+ | **Лицензия**: | ||
+ | |||
+ | **Более продвинутый вариант**: | ||
+ | **Обсуждение на форуме**: | ||
+ | |||
+ | |||
+ | |||
+ | ===== Пример настроек ===== | ||
+ | В rc.conf для FreeBSD добавляем: | ||
+ | < | ||
perl_fcgi_pidfile="/ | perl_fcgi_pidfile="/ | ||
perl_fcgi_user=" | perl_fcgi_user=" | ||
Line 14: | Line 32: | ||
perl_fcgi_chdir="/" | perl_fcgi_chdir="/" | ||
perl_fcgi_chroot="" | perl_fcgi_chroot="" | ||
- | perl_fcgi_socket="/ | + | # perl_fcgi_socket=" |
+ | perl_fcgi_socket="/ | ||
perl_fcgi_socketbacklog=" | perl_fcgi_socketbacklog=" | ||
- | perl_fcgi_socketmode=" | + | perl_fcgi_socketmode=" |
perl_fcgi_children=" | perl_fcgi_children=" | ||
perl_fcgi_childrentimeout=" | perl_fcgi_childrentimeout=" | ||
- | perl_fcgi_max_requests=" | + | perl_fcgi_max_requests=" |
- | perl_fcgi_path_env="/ | + | perl_fcgi_path_env="/ |
- | + | * **enable** - разрешить запуск при загрузке | |
- | + | * **user** - имя пользователя под которым | |
- | стартовый скрипт | + | * **group** |
- | [code]# | + | * **chdir** |
- | ### Rozhuk Ivan 2009.05 | + | |
- | ### startup script file for perl-fcgi | + | * **socket** |
- | ### | + | * **socketbacklog** |
- | + | * **socketmode** - права доступа к сокету, только для unix сокета | |
- | + | * **children** | |
- | # PROVIDE: perl_fcgi | + | * **childrentimeout** - максимальное время выполнения |
- | # REQUIRE: DAEMON | + | * **max_requests** - максимальное количество запросов обработанных одним дочерним процессом |
- | # BEFORE: | + | * **path_env** - перезаписать переменную окружения PATH |
- | # KEYWORD: shutdown | + | |
- | + | ||
- | . / | + | |
- | + | ||
- | name=" | + | |
- | rcvar=`set_rcvar` | + | |
- | + | ||
- | load_rc_config $name | + | |
- | + | ||
- | : ${perl_fcgi_enable=" | + | |
- | : ${perl_fcgi_pidfile="/ | + | |
- | : ${perl_fcgi_user=" | + | |
- | : ${perl_fcgi_group=" | + | |
- | : ${perl_fcgi_chdir="" | + | |
- | : ${perl_fcgi_chroot="" | + | |
- | : ${perl_fcgi_socket=" | + | |
- | : ${perl_fcgi_socketbacklog=" | + | |
- | : ${perl_fcgi_socketmode=" | + | |
- | : ${perl_fcgi_children=" | + | |
- | : ${perl_fcgi_childrentimeout=" | + | |
- | : ${perl_fcgi_max_requests=" | + | |
- | : ${perl_fcgi_path_env="/ | + | |
- | + | ||
- | + | ||
- | command="/ | + | |
- | command_args=" | + | |
- | procname=" | + | |
- | pidfile=" | + | |
- | required_dirs=${perl_fcgi_chroot} | + | |
- | + | ||
- | start_precmd=" | + | |
- | stop_postcmd=" | + | |
- | + | ||
- | + | ||
- | perl_fcgi_start_precmd() | + | |
- | { | + | |
- | touch ${perl_fcgi_chroot}${pidfile} | + | |
- | chown ${perl_fcgi_user}: | + | |
- | } | + | |
- | + | ||
- | perl_fcgi_stop_postcmd() | + | |
- | { | + | |
- | rm -f ${pidfile} | + | |
- | } | + | |
- | + | ||
- | run_rc_command " | + | |
- | [/code] | + | |
- | + | ||
- | + | ||
- | Демонический скрипт perl-fcgi.pl (ложить в / | + | |
- | [code]# | + | |
- | ### Rozhuk Ivan, 2009 | + | |
- | ### fast cgi for perl scripts | + | |
- | ### mod version 1.2 | + | |
- | + | ||
- | ### origin: http:// | + | |
- | ### mod by Denis S. Filimonov (Guest) on 13.03.2008 18:37 http:// | + | |
- | ### mod by mark: http:// | + | |
- | ### final: http:// | + | |
- | ### additional: http:// | + | |
- | + | ||
- | + | ||
- | use strict; | + | |
- | use warnings; | + | |
- | use FCGI; # / | + | |
- | use FCGI:: | + | |
- | use Socket; | + | |
- | use POSIX qw(setsid setuid); | + | |
- | use Getopt:: | + | |
- | require ' | + | |
- | + | ||
- | # settings | + | |
- | my ($CURRENT_DIR, | + | |
- | + | ||
- | # global variables | + | |
- | + | ||
- | + | ||
- | + | ||
- | & | + | |
- | + | ||
- | + | ||
- | #this keeps the program alive or something after exec' | + | |
- | END() { } | + | |
- | BEGIN() { } | + | |
- | {no warnings; | + | |
- | eval q{exit}; | + | |
- | if ($@) { exit unless $@ =~ / | + | |
- | + | ||
- | + | ||
- | + | ||
- | sub startpoint() | + | |
- | { | + | |
- | if ($# | + | |
- | { | + | |
- | $CURRENT_DIR ='/'; | + | |
- | # | + | |
- | $SOCKET_BACKLOG =10; | + | |
- | $SOCKET_MODE =0777; | + | |
- | $CHILDRENS_COUNT =2; | + | |
- | $CHILDRENS_TIMEOUT =30; | + | |
- | $CHILDRENS_MAX_REQ =100; | + | |
- | # | + | |
- | # | + | |
- | + | ||
- | GetOptions( ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | |
- | ); | + | |
- | + | ||
- | if (!defined($SOCKET_ADDRESS)) {usage(); | + | |
- | + | ||
- | # untainte input | + | |
- | if ($SOCKET_ADDRESS =~ /^(.*)$/) {$SOCKET_ADDRESS = $1;} | + | |
- | if (defined($PIDFILE)) {if ($PIDFILE =~ /^(.*)$/) {$PIDFILE = $1;}} | + | |
- | if (defined($PATHENV)) | + | |
- | { | + | |
- | if ($PIDFILE =~ /^(.*)$/) {$PIDFILE = $1;} | + | |
- | }else{ | + | |
- | $PATHENV='/ | + | |
- | } | + | |
- | + | ||
- | + | ||
- | #print " | + | |
- | daemonize(); | + | |
- | }else{ | + | |
- | usage(); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | sub usage | + | |
- | { | + | |
- | print " | + | |
- | print " -d < | + | |
- | print " -s < | + | |
- | print " -sb < | + | |
- | print " -M < | + | |
- | print " -F < | + | |
- | print " -Ft < | + | |
- | print " -Fm < | + | |
- | print " -P < | + | |
- | print " -e < | + | |
- | #print "(root only)\n"; | + | |
- | #print " -c < | + | |
- | #print " -S create socket before chroot() (default is to create the socket in the chroot)\n"; | + | |
- | #print " -u < | + | |
- | #print " -g < | + | |
- | #print " -U < | + | |
- | #print " -G < | + | |
- | + | ||
- | exit; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | sub daemonize() | + | |
- | { | + | |
- | delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer | + | |
- | $ENV{' | + | |
- | chdir $CURRENT_DIR or die " | + | |
- | # | + | |
- | + | ||
- | open(STDIN, | + | |
- | open(STDOUT, | + | |
- | open(STDERR, | + | |
- | defined(my $tm = fork) or die " | + | |
- | exit if $tm; | + | |
- | setsid or die " | + | |
- | umask 0; | + | |
- | + | ||
- | main(); | + | |
- | } | + | |
- | + | ||
- | + | ||
- | sub main | + | |
- | { | + | |
- | my ($ListenSocket); | + | |
- | my ($proc_manager, | + | |
- | + | ||
- | $ListenSocket = FCGI:: | + | |
- | if (defined($ListenSocket)) | + | |
- | { | + | |
- | if (defined($PIDFILE)) | + | |
- | { | + | |
- | open FILE, "> $PIDFILE" | + | |
- | print FILE " | + | |
- | close FILE; | + | |
- | } | + | |
- | + | ||
- | if (substr($SOCKET_ADDRESS, | + | |
- | { | + | |
- | print " | + | |
- | chmod(oct($SOCKET_MODE), | + | |
- | } | + | |
- | + | ||
- | $proc_manager = FCGI:: | + | |
- | $request = FCGI:: | + | |
- | $proc_manager-> | + | |
- | + | ||
- | if ($request) { request_loop(\$proc_manager, | + | |
- | + | ||
- | FCGI:: | + | |
- | if (substr($SOCKET_ADDRESS, | + | |
- | if (defined($PIDFILE)) {unlink($PIDFILE); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | sub request_loop() | + | |
- | { | + | |
- | my ($proc_manager_ref)=$_[0]; | + | |
- | my ($request_ref)=$_[1]; | + | |
- | my ($req_params_ref)=$_[2]; | + | |
- | my ($stdin_passthrough, | + | |
- | + | ||
- | $req_count=1; | + | |
- | while( $$request_ref-> | + | |
- | { | + | |
- | $$proc_manager_ref-> | + | |
- | + | ||
- | # | + | |
- | $stdin_passthrough =''; | + | |
- | { no warnings; $req_len = 0 + $$req_params_ref{' | + | |
- | if (($$req_params_ref{' | + | |
- | { | + | |
- | my $bytes_read = 0; | + | |
- | while ($bytes_read < $req_len) | + | |
- | { | + | |
- | my $data = ''; | + | |
- | my $bytes = read(STDIN, $data, ($req_len - $bytes_read)); | + | |
- | last if ($bytes == 0 || !defined($bytes)); | + | |
- | $stdin_passthrough .= $data; | + | |
- | $bytes_read += $bytes; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | #running the cgi app | + | |
- | if ( (-x $$req_params_ref{SCRIPT_FILENAME}) && | + | |
- | (-s $$req_params_ref{SCRIPT_FILENAME}) && | + | |
- | (-r $$req_params_ref{SCRIPT_FILENAME}) | + | |
- | ){ | + | |
- | + | ||
- | pipe(CHILD_RD, | + | |
- | $pid_child = open(KID_TO_READ, | + | |
- | unless(defined($pid_child)) | + | |
- | { | + | |
- | print(" | + | |
- | print " | + | |
- | next; | + | |
- | } | + | |
- | + | ||
- | if ($pid_child > 0) | + | |
- | { | + | |
- | close(CHILD_RD); | + | |
- | print PARENT_WR $stdin_passthrough; | + | |
- | close(PARENT_WR); | + | |
- | + | ||
- | while(my $s = < | + | |
- | close KID_TO_READ; | + | |
- | waitpid($pid_child, | + | |
- | }else{ | + | |
- | foreach $key ( keys %{$req_params_ref}){ $ENV{$key} = $$req_params_ref{$key}; | + | |
- | # cd to the script' | + | |
- | if ($$req_params_ref{SCRIPT_FILENAME} =~ /^(.*)\/ | + | |
- | + | ||
- | close(PARENT_WR); | + | |
- | close(STDIN); | + | |
- | # | + | |
- | syscall(& | + | |
- | # | + | |
- | exec($$req_params_ref{SCRIPT_FILENAME}); | + | |
- | die(" | + | |
- | } | + | |
- | }else{ | + | |
- | print(" | + | |
- | print " | + | |
- | } | + | |
- | + | ||
- | $req_count++; | + | |
- | exit if $req_count > $CHILDRENS_MAX_REQ; | + | |
- | $$proc_manager_ref-> | ||
- | } | ||
- | } | ||
- | [/code] | ||
+ | ===== Параметры командной строки демона ===== | ||
+ | * **-d** < | ||
+ | * **-s** < | ||
+ | * **-sb** < | ||
+ | * **-M** < | ||
+ | * **-F** < | ||
+ | * **-Ft** < | ||
+ | * **-Fm** <num> - children process max requests (default 100) | ||
+ | * **-P** < | ||
+ | * **-e** < | ||
- | Постарался проследить историю развития скрипта, | ||
- | Версию с более продвинутой логикой внутри мне не удалось заставить работать, | ||
- | В коде видно часть не реализованных опций - часть из них реализуется стартовым скриптом (chroot, смена пользователя и группы), |