免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3959 | 回复: 4
打印 上一主题 下一主题

[FreeBSD] nginx perl fastcgi daemon 脚本 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-10-15 22:50 |只看该作者 |倒序浏览
rc.conf:

perl_fcgi_enable="YES"
perl_fcgi_pidfile="/var/run/perl-fcgi.pid"
perl_fcgi_user="www"
perl_fcgi_group="www"
perl_fcgi_chdir="/"
perl_fcgi_chroot=""
perl_fcgi_socket="/tmp/perl-fcgi.sock"
perl_fcgi_socketbacklog="100"
perl_fcgi_socketmode="0777"
perl_fcgi_children="2"
perl_fcgi_childrentimeout="10"
perl_fcgi_max_requests="10000"
perl_fcgi_path_env="/bin:/usr/bin"



/usr/local/etc/rc.d/perl-fcgi
  1. #!/bin/sh
  2. ### Rozhuk Ivan 2009.05
  3. ### startup script file for perl-fcgi
  4. ###


  5. # PROVIDE: perl_fcgi
  6. # REQUIRE: DAEMON
  7. # BEFORE:  LOGIN
  8. # KEYWORD: shutdown

  9. . /etc/rc.subr

  10. name="perl_fcgi"
  11. rcvar=`set_rcvar`

  12. load_rc_config $name

  13. : ${perl_fcgi_enable="NO"}
  14. : ${perl_fcgi_pidfile="/var/run/perl-fcgi.pid"}
  15. : ${perl_fcgi_user="www"}
  16. : ${perl_fcgi_group="www"}
  17. : ${perl_fcgi_chdir=""}
  18. : ${perl_fcgi_chroot=""}
  19. : ${perl_fcgi_socket="127.0.0.1:9001"}
  20. : ${perl_fcgi_socketbacklog="10"}
  21. : ${perl_fcgi_socketmode="0777"}
  22. : ${perl_fcgi_children="5"}
  23. : ${perl_fcgi_childrentimeout="30"}
  24. : ${perl_fcgi_max_requests="1000"}
  25. : ${perl_fcgi_path_env="/bin:/usr/bin"}


  26. command="/usr/local/etc/perl-fcgi.pl"
  27. command_args="-d ${perl_fcgi_chdir} -s ${perl_fcgi_socket} -sb ${perl_fcgi_socket} -M ${perl_fcgi_socketmode} -F ${perl_fcgi_children} -Ft ${perl_fcgi_childrentimeout} -Fm ${perl_fcgi_max_requests} -P ${perl_fcgi_pidfile} -e ${perl_fcgi_path_env}"
  28. procname="perl-fcgi-pm"
  29. pidfile="${perl_fcgi_chroot}${perl_fcgi_pidfile}"
  30. required_dirs=${perl_fcgi_chroot}

  31. start_precmd="${name}_start_precmd"
  32. stop_postcmd="${name}_stop_postcmd"


  33. perl_fcgi_start_precmd()
  34. {
  35.         touch ${perl_fcgi_chroot}${pidfile}
  36.         chown ${perl_fcgi_user}:${perl_fcgi_group} ${perl_fcgi_chroot}${pidfile}
  37. }

  38. perl_fcgi_stop_postcmd()
  39. {
  40.         rm -f ${pidfile}
  41. }
  42. run_rc_command "$1"

复制代码
创建perl-fcgi.pl 到/usr/local/etc/ 下
  1. #!/usr/bin/perl -w
  2. ### Rozhuk Ivan, 2009
  3. ### fast cgi for perl scripts
  4. ### mod version 1.2

  5. ### origin: http://wiki.nginx.org//NginxSimpleCGI
  6. ### mod by  Denis S. Filimonov (Guest) on 13.03.2008 18:37 http://www.ruby-forum.com/attachment/1583/fastcgi-wrapper.pl
  7. ### mod by mark: http://www.linux.org.ru/view-message.jsp?msgid=3532327
  8. ### final: http://wiki.nginx.org//NginxSimpleCGI
  9. ### additional: http://www.opennet.ru/base/dev/fastcgi_perl.txt.html


  10. use strict;
  11. use warnings;
  12. use FCGI; # /usr/ports/www/p5-FastCGI
  13. use FCGI::ProcManager qw(pm_manage pm_pre_dispatch pm_post_dispatch); # /usr/ports/www/p5-FCGI-ProcManager
  14. use Socket;
  15. use POSIX qw(setsid setuid);
  16. use Getopt::Long;
  17. require 'sys/syscall.ph';

  18. # settings
  19. my ($CURRENT_DIR,$SOCKET_ADDRESS,$SOCKET_BACKLOG,$SOCKET_MODE,$CHILDRENS_COUNT,$CHILDRENS_TIMEOUT,$CHILDRENS_MAX_REQ,$PIDFILE,$PATHENV);

  20. # global variables



  21. &startpoint();


  22. #this keeps the program alive or something after exec'ing perl scripts
  23. END()                { }
  24. BEGIN()        { }
  25. {no warnings; *CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; };
  26. eval q{exit};
  27. if ($@) { exit unless $@ =~ /^fakeexit/; };



  28. sub startpoint()
  29. {
  30.         if ($#ARGV!=-1)
  31.         {
  32.                 $CURRENT_DIR                ='/';
  33.                 #$SOCKET_ADDRESS        ='';
  34.                 $SOCKET_BACKLOG        =10;
  35.                 $SOCKET_MODE                =0777;
  36.                 $CHILDRENS_COUNT        =2;
  37.                 $CHILDRENS_TIMEOUT        =30;
  38.                 $CHILDRENS_MAX_REQ        =100;
  39.                 #$PIDFILE                ='';
  40.                 #$PATHENV                ='/bin:/usr/bin';

  41.                 GetOptions(        'd:s'        => \$CURRENT_DIR,
  42.                                 's=s'        => \$SOCKET_ADDRESS,
  43.                                 'sb:i'        => \$SOCKET_BACKLOG,
  44.                                 'M:i'        => \$SOCKET_MODE,
  45.                                 'F:i'        => \$CHILDRENS_COUNT,
  46.                                 'Ft:i'        => \$CHILDRENS_TIMEOUT,
  47.                                 'Fm:i'        => \$CHILDRENS_MAX_REQ,
  48.                                 'P:s'        => \$PIDFILE,
  49.                                 'e:s'        => \$PATHENV,
  50.                 );

  51.                 if (!defined($SOCKET_ADDRESS)) {usage();}

  52.                 # untainte input
  53.                 if ($SOCKET_ADDRESS =~ /^(.*)$/) {$SOCKET_ADDRESS = $1;}
  54.                 if (defined($PIDFILE)) {if ($PIDFILE =~ /^(.*)$/) {$PIDFILE = $1;}}
  55.                 if (defined($PATHENV))
  56.                 {
  57.                         if ($PIDFILE =~ /^(.*)$/) {$PIDFILE = $1;}
  58.                 }else{
  59.                         $PATHENV='/bin:/usr/bin';
  60.                 }


  61.                 #print "SOCKET_ADDRESS: $SOCKET_ADDRESS SOCKET_BACKLOG: $SOCKET_BACKLOG CHILDRENS_COUNT: $CHILDRENS_COUNT CHILDRENS_TIMEOUT: $CHILDRENS_TIMEOUT PIDFILE: $PIDFILE\n";
  62.                 daemonize();
  63.         }else{
  64.                 usage();
  65.         }
  66. }


  67. sub usage
  68. {
  69.         print "Usage: perl-fcgi [options]\n\n";
  70.         print " -d <directory>        chdir to directory before spawning (default /)\n";
  71.         print " -s <address/path>        unix socket or tcp address:port\n";
  72.         print " -sb <size>                socket backlog size (default 10)\n";
  73.         print " -M <mode>                change Unix domain socket mode (default 0777)\n";
  74.         print " -F <children>                number of children to fork (default 2)\n";
  75.         print " -Ft <timeout>                children process timeout (default 30)\n";
  76.         print " -Fm <num>                children process max requests (default 100)\n";
  77.         print " -P <path>                name of PID-file for spawned process\n";
  78.         print " -e <path>                set new PATH environment (default /bin:/usr/bin)\n";
  79.         #print "(root only)\n";
  80.         #print " -c <directory>                chroot to directory (default /)\n";
  81.         #print " -S                        create socket before chroot() (default is to create the socket in the chroot)\n";
  82.         #print " -u <user>                change to user-id\n";
  83.         #print " -g <group>                change to group-id (default: primary group of user if -u is given)\n";
  84.         #print " -U <user>                change Unix domain socket owner to user-id\n";
  85.         #print " -G <group>                change Unix domain socket group to group-id\n";

  86.         exit;
  87. }


  88. sub daemonize()
  89. {
  90.         delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer
  91.         $ENV{'PATH'} = $PATHENV; # set new path environment
  92.         chdir $CURRENT_DIR                 or die "Can't chdir to $CURRENT_DIR: $!\n";
  93.         #setuid(65534)                or die "Can't set uid: $!\n"; # nobody

  94.         open(STDIN,  "+>/dev/null")        or die "Can't open STDIN: $!\n";
  95.         open(STDOUT, "+>&STDIN")        or die "Can't open STDOUT: $!\n";
  96.         open(STDERR, "+>&STDIN")        or die "Can't open STDERR: $!\n";
  97.         defined(my $tm = fork)        or die "Can't fork: $!\n";
  98.         exit if $tm;
  99.         setsid                                or die "Can't start a new session: $!\n";
  100.         umask 0;

  101.         main();
  102. }


  103. sub main
  104. {
  105.         my ($ListenSocket);
  106.         my ($proc_manager,$request,%req_params);

  107.         $ListenSocket = FCGI::OpenSocket( $SOCKET_ADDRESS, $SOCKET_BACKLOG );
  108.         if (defined($ListenSocket))
  109.         {
  110.                 if (defined($PIDFILE))
  111.                 {
  112.                         open FILE, "> $PIDFILE" or die $!;
  113.                         print FILE "$$\n";
  114.                         close FILE;
  115.                 }

  116.                 if (substr($SOCKET_ADDRESS,0,1) eq '/')
  117.                 {
  118.                         print "chmod($SOCKET_MODE,$SOCKET_ADDRESS)\n";
  119.                         chmod(oct($SOCKET_MODE),$SOCKET_ADDRESS);
  120.                 }

  121.                 $proc_manager = FCGI::ProcManager->new({ n_processes => $CHILDRENS_COUNT, die_timeout => $CHILDRENS_TIMEOUT });
  122.                 $request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $ListenSocket, &FCGI::FAIL_ACCEPT_ON_INTR );
  123.                 $proc_manager->pm_manage();

  124.                 if ($request) { request_loop(\$proc_manager,\$request,\%req_params) };

  125.                 FCGI::CloseSocket( $ListenSocket );
  126.                 if (substr($SOCKET_ADDRESS,0,1) eq '/')        {unlink($SOCKET_ADDRESS);}
  127.                 if (defined($PIDFILE))                        {unlink($PIDFILE);}
  128.         }
  129. }


  130. sub request_loop()
  131. {
  132.         my ($proc_manager_ref)=$_[0];
  133.         my ($request_ref)=$_[1];
  134.         my ($req_params_ref)=$_[2];
  135.         my ($stdin_passthrough,$req_len,$key,$pid_child,$req_count);

  136.         $req_count=1;
  137.         while( $$request_ref->Accept() >= 0 )
  138.         {
  139.                 $$proc_manager_ref->pm_pre_dispatch();
  140.                
  141.                 #processing any STDIN input from WebServer (for CGI-POST actions)
  142.                 $stdin_passthrough ='';
  143.                 { no warnings; $req_len = 0 + $$req_params_ref{'CONTENT_LENGTH'}; };
  144.                 if (($$req_params_ref{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) )
  145.                 {
  146.                         my $bytes_read = 0;
  147.                         while ($bytes_read < $req_len)
  148.                         {
  149.                                 my $data = '';
  150.                                 my $bytes = read(STDIN, $data, ($req_len - $bytes_read));
  151.                                 last if ($bytes == 0 || !defined($bytes));
  152.                                 $stdin_passthrough .= $data;
  153.                                 $bytes_read += $bytes;
  154.                         }
  155.                 }

  156.                 #running the cgi app
  157.                 if ( (-x $$req_params_ref{SCRIPT_FILENAME}) &&  #can I execute this?
  158.                         (-s $$req_params_ref{SCRIPT_FILENAME}) &&  #Is this file empty?
  159.                         (-r $$req_params_ref{SCRIPT_FILENAME})     #can I read this file?
  160.                 ){

  161.                         pipe(CHILD_RD, PARENT_WR);
  162.                         $pid_child = open(KID_TO_READ, "-|");
  163.                         unless(defined($pid_child))
  164.                         {
  165.                                 print("Content-type: text/plain\r\n\r\n");
  166.                             print "Error: CGI app returned no output - Executing $$req_params_ref{SCRIPT_FILENAME} failed !\n";
  167.                                 next;
  168.                         }

  169.                         if ($pid_child > 0)
  170.                         {
  171.                                 close(CHILD_RD);
  172.                                 print PARENT_WR $stdin_passthrough;
  173.                                 close(PARENT_WR);

  174.                                 while(my $s = <KID_TO_READ>) { print $s; }
  175.                                 close KID_TO_READ;
  176.                                 waitpid($pid_child, 0);
  177.                         }else{
  178.                                 foreach $key ( keys %{$req_params_ref}){ $ENV{$key} = $$req_params_ref{$key}; }
  179.                                 # cd to the script's local directory
  180.                                 if ($$req_params_ref{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/) { chdir $1;}

  181.                                 close(PARENT_WR);
  182.                                 close(STDIN);
  183.                                 #fcntl(CHILD_RD, F_DUPFD, 0);
  184.                                 syscall(&SYS_dup2, fileno(CHILD_RD), 0);
  185.                                 #open(STDIN, "<&CHILD_RD");
  186.                                 exec($$req_params_ref{SCRIPT_FILENAME});
  187.                                 die("exec failed");
  188.                         }
  189.                 }else{
  190.                         print("Content-type: text/plain\r\n\r\n");
  191.                         print "Error: No such CGI app - $$req_params_ref{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";
  192.                 }

  193.                 $req_count++;
  194.                 exit if $req_count > $CHILDRENS_MAX_REQ;

  195.                 $$proc_manager_ref->pm_post_dispatch();
  196.         }
  197. }


复制代码

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
2 [报告]
发表于 2010-10-15 22:58 |只看该作者
看不懂
原创的吗?

论坛徽章:
2
狮子座
日期:2013-08-26 15:25:32金牛座
日期:2013-09-05 15:45:36
3 [报告]
发表于 2010-10-15 23:47 |只看该作者
里面有版权申明嗒

用来让nginx支持cgi的,跟php-fpm作用差不多
嘿嘿
收藏先

论坛徽章:
0
4 [报告]
发表于 2010-10-18 01:11 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
20
CU大牛徽章
日期:2013-04-17 11:48:26羊年新春福章
日期:2015-03-10 22:39:202015年中国系统架构师大会
日期:2015-06-29 16:11:282015亚冠之平阳省
日期:2015-07-31 09:19:042015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-09-30 06:20:002015亚冠之柏太阳神
日期:2015-10-19 20:29:5915-16赛季CBA联赛之天津
日期:2016-11-29 14:03:4315-16赛季CBA联赛之北控
日期:2016-12-24 20:51:492015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-12 20:58:532014年中国系统架构师大会
日期:2014-10-14 15:59:00
5 [报告]
发表于 2010-10-18 19:24 |只看该作者
支持
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP