CentOS下Nginx支持CGI

来源:互联网 发布:数据安全保密规定 编辑:程序博客网 时间:2024/05/18 15:23

 

  1. [root@mail src]# wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.73.tar.gz  
  2.  
  3. [root@mail src]# wget  [root@mail src]# wget http://search.cpan.org/CPAN/authors/id/G/GB/GBJK/FCGI-ProcManager-0.19.tar.gz  
  4.  
  5. [root@mail src]# tar –zxvf FCGI-0.73.tar.gz  
  6.  
  7. [root@mail src]# cd FCGI-0.73  
  8.  
  9. [root@mail FCGI-0.73]# perl Makefile.PL  
  10.  
  11. [root@mail FCGI-0.73]# make && make install  
  12.  
  13. [root@mail FCGI-0.73]# cd ..  
  14.  
  15. [root@mail src]# tar –zxvf FCGI-ProcManager-0.19.tar.gz  
  16.  
  17. [root@mail FCGI-ProcManager-0.19]# perl Makefile.PL  
  18.  
  19. [root@mail FCGI-ProcManager-0.19]# make && make install  
  20.  

接下来需要添加一个脚本,我也是从网上开来的,下面给大家转载来一篇

下面的转载来的,大家看一下

作者: Bluedata | 可以转载,转载时务必以超链接形式标明文章原始出处和作者信息及版权声明
网址: http://bluedata.org/2009/08/21/nginx-cgi/

用 perl 写一个 daemon 程序来处理 cgi 文件:
vi /usr/local/bin/cgiwrap-fcgi.pl

  1. #!/usr/bin/perl -w  
  2. use FCGI;  
  3. use Socket;  
  4. use FCGI::ProcManager;  
  5. sub shutdown { FCGI::CloseSocket($socket); exit; }  
  6. sub restart { FCGI::CloseSocket($socket); &main; }  
  7. use sigtrap 'handler', \&shutdown, 'normal-signals';  
  8. use sigtrap 'handler', \&restart,  'HUP';  
  9. require 'syscall.ph';  
  10. use POSIX qw(setsid);  
  11. #&daemonize; we don't daemonize when running under runsv  
  12. #this keeps the program alive or something after exec'ing perl scripts  
  13. END() { }  
  14. BEGIN() { }  
  15. {  
  16. no warnings;  
  17. *CORE::GLOBAL::exit = sub { die "fakeexit\nrc=" . shift() . "\n"; };  
  18. };  
  19. eval q{exit};  
  20. if ($@) {  
  21. exit unless $@ =~ /^fakeexit/;  
  22. }  
  23. &main;  
  24. sub daemonize() {  
  25. chdir '/' or die "Can't chdir to /: $!";  
  26. defined( my $pid = fork ) or die "Can't fork: $!";  
  27. exit if $pid;  
  28. setsid() or die "Can't start a new session: $!";  
  29. umask 0;  
  30. }  
  31. sub main {  
  32. #$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets  
  33. #$socket = FCGI::OpenSocket( "/var/run/nginx/perl_cgi-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!  
  34. #foreach $item (keys %ENV) { delete $ENV{$item}; }  
  35. $proc_manager = FCGI::ProcManager->new( {n_processes => 5} );  
  36. $socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 )  
  37.         ; #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!  
  38. $request =  
  39. FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,  
  40. &FCGI::FAIL_ACCEPT_ON_INTR );  
  41. $proc_manager->pm_manage();  
  42. if ($request) { request_loop() }  
  43. FCGI::CloseSocket($socket);  
  44. }  
  45. sub request_loop {  
  46. while ( $request->Accept() >= 0 ) {  
  47. $proc_manager->pm_pre_dispatch();  
  48. #processing any STDIN input from WebServer (for CGI-POST actions)  
  49. $stdin_passthrough = '';  
  50. no warnings; $req_len = 0 + $req_params{'CONTENT_LENGTH'}; };  
  51. if ( ( $req_params{'REQUEST_METHOD'} eq 'POST' ) && ( $req_len != 0 ) )  
  52. {  
  53. my $bytes_read = 0;  
  54. while ( $bytes_read < $req_len ) {  
  55. my $data = '';  
  56. my $bytes = read( STDIN, $data, ( $req_len - $bytes_read ) );  
  57. last if ( $bytes == 0 || !defined($bytes) );  
  58. $stdin_passthrough .= $data;  
  59. $bytes_read += $bytes;  
  60. }  
  61. }  
  62. #running the cgi app  
  63. if (  
  64. ( -x $req_params{SCRIPT_FILENAME} ) &&    #can I execute this?  
  65. ( -s $req_params{SCRIPT_FILENAME} ) &&    #Is this file empty?  
  66. ( -r $req_params{SCRIPT_FILENAME} ) #can I read this file?  
  67. )  
  68. {  
  69. pipe( CHILD_RD,   PARENT_WR );  
  70. pipe( PARENT_ERR, CHILD_ERR );  
  71. my $pid = open( CHILD_O, "-|" );  
  72. unless ( defined($pid) ) {  
  73. print("Content-type: text/plain\r\n\r\n");  
  74. print  
  75. "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";  
  76. next;  
  77. }  
  78. $oldfh = select(PARENT_ERR);  
  79.             $|     = 1;  
  80. select(CHILD_O);  
  81.             $| = 1;  
  82. select($oldfh);  
  83. if ( $pid > 0 ) {  
  84. close(CHILD_RD);  
  85. close(CHILD_ERR);  
  86. print PARENT_WR $stdin_passthrough;  
  87. close(PARENT_WR);  
  88. $rin = $rout = $ein = $eout = '';  
  89. vec( $rin, fileno(CHILD_O),    1 ) = 1;  
  90. vec( $rin, fileno(PARENT_ERR), 1 ) = 1;  
  91. $ein    = $rin;  
  92. $nfound = 0;  
  93. while ( $nfound =  
  94. select( $rout = $rin, undef, $ein = $eout, 10 ) )  
  95. {  
  96. die "$!" unless $nfound != -1;  
  97. $r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;  
  98. $r2 = vec( $rout, fileno(CHILD_O),    1 ) == 1;  
  99. $e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;  
  100. $e2 = vec( $eout, fileno(CHILD_O),    1 ) == 1;  
  101. if ($r1) {  
  102. while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {  
  103. print STDERR $errbytes;  
  104. }  
  105. if ($!) {  
  106. $err = $!;  
  107. die $!;  
  108. vec( $rin, fileno(PARENT_ERR), 1 ) = 0  
  109. unless ( $err == EINTR or $err == EAGAIN );  
  110. }  
  111. }  
  112. if ($r2) {  
  113. while ( $bytes = read( CHILD_O, $s, 4096 ) ) {  
  114. print $s;  
  115. }  
  116. if ( !defined($bytes) ) {  
  117. $err = $!;  
  118. die $!;  
  119. vec( $rin, fileno(CHILD_O), 1 ) = 0  
  120. unless ( $err == EINTR or $err == EAGAIN );  
  121. }  
  122. }  
  123. last if ( $e1 || $e2 );  
  124. }  
  125. close CHILD_RD;  
  126. close PARENT_ERR;  
  127. waitpid( $pid, 0 );  
  128. else {  
  129. foreach $key ( keys %req_params ) {  
  130. $ENV{$key} = $req_params{$key};  
  131. }  
  132. # cd to the script's local directory  
  133. if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/]+$/ ) {  
  134. chdir $1;  
  135. }  
  136. close(PARENT_WR);  
  137. #close(PARENT_ERR);  
  138. close(STDIN);  
  139. close(STDERR);  
  140. #fcntl(CHILD_RD, F_DUPFD, 0);  
  141. syscall( &SYS_dup2, fileno(CHILD_RD),  0 );  
  142. syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );  
  143. #open(STDIN, "<&CHILD_RD");  
  144. exec( $req_params{SCRIPT_FILENAME} );  
  145. die("exec failed");  
  146. }  
  147. else {  
  148. print("Content-type: text/plain\r\n\r\n");  
  149. print  
  150. "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";  
  151. }  
  152. }  
  153. }   
  154.  

注意文件中的这两行:
#$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 );
#$socket = FCGI::OpenSocket( "/var/run/nginx/perl_cgi-dispatch.sock", 10 );
这两行都表示监听来自 perl CGI 的请求。
其中 perl_cgi-dispatch.sock 表示使用 unix socket 响应 CGI 请求。
127.0.0.1:8999 表示使用 TCP/IP 协议响应请求。
需要使用哪种方式就在下面的 FCGI::OpenSocket 中填入相对应的内容。

启动:
chmod +x /usr/local/bin/cgiwrap-fcgi.pl
/usr/local/bin/cgiwrap-fcgi.pl > /dev/null 2>&1 &

配置 Nginx 的 location 处理 cgi 文件:

location ~ .*\.cgi$ {
    fastcgi_pass  127.0.0.1:8999;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    include  fastcgi_params;
}

测试:
在 web 的根目录下创建一个 cgi 文件:
vi test.cgi
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, world.";

文件需要有可执行权限:
chmod +x test.cgi

访问 http://www.domain.com/test.cgi 看看有没有输出。

本文出自 “cold night” 博客,转载请与作者联系!