讓Nginx支援CGI

來源:互聯網
上載者:User

原理:

    Nginx預設不支援CGI,但是支援FastCGI,所以可以用FastCGI替代CGI。

準備條件:

    1、安裝perl:略

    2、 安裝FCGI-ProcManage

        simba@simba-laptop:~/tmp$ wget http://search.cpan.org/CPAN/authors/id/G/GB/GBJK/FCGI-ProcManager-0.19.tar.gz         simba@simba-laptop:~/tmp$ tar -zxvf ./FCGI-ProcManager-0.19.tar.gz         simba@simba-laptop:~/tmp$ cd FCGI-ProcManager-0.19/        simba@simba-laptop:~/tmp/FCGI-ProcManager-0.19$ perl Makefile.PL         simba@simba-laptop:~/tmp/FCGI-ProcManager-0.19$ make;sudo make install;

   3、安裝Perl FastCGI 模組(Can't locate FCGI.pm in @INC)

             simba@simba-laptop:~/tmp/FCGI-ProcManager-0.19$ sudo cpan FCGI


編寫Nginx cig精靈:

1、儲存以下指令碼為:/usr/local/bin/cgiwrap-fcgi.pl, 設定可執行許可權。

#!perluse FCGI;use Socket;use FCGI::ProcManager;sub shutdown { FCGI::CloseSocket($socket); exit; }sub restart  { FCGI::CloseSocket($socket); &main; }use sigtrap 'handler', \&shutdown, 'normal-signals';use sigtrap 'handler', \&restart,  'HUP';require 'syscall.ph';use POSIX qw(setsid); END()   { }BEGIN() { }{  no warnings;  *CORE::GLOBAL::exit = sub { die "fakeexit\nrc=" . shift() . "\n"; };}; eval q{exit};if ($@) {  exit unless $@ =~ /^fakeexit/;}&main; sub daemonize() {  chdir '/' or die "Can't chdir to /: $!";  defined( my $pid = fork ) or die "Can't fork: $!";  exit if $pid;  setsid() or die "Can't start a new session: $!";  umask 0;} sub main {  $proc_manager = FCGI::ProcManager->new( {n_processes => 5} );  $socket = FCGI::OpenSocket( "/tmp/cgiwrap-dispatch.sock", 10 )  ; #use UNIX sockets - user running this script must have w access to the 'nginx' folder!!  chmod 0766, "/tmp/cgiwrap-dispatch.sock";  $request =  FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket,  &FCGI::FAIL_ACCEPT_ON_INTR );  $proc_manager->pm_manage();  if ($request) { request_loop() }  FCGI::CloseSocket($socket);} sub request_loop {  while ( $request->Accept() >= 0 ) {    $proc_manager->pm_pre_dispatch();     #processing any STDIN input from WebServer (for CGI-POST actions)    $stdin_passthrough = '';    { no warnings; $req_len = 0 + $req_params{'CONTENT_LENGTH'}; };    if ( ( $req_params{'REQUEST_METHOD'} eq 'POST' ) && ( $req_len != 0 ) ) {      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{SCRIPT_FILENAME} ) &&    #can I execute this?      ( -s $req_params{SCRIPT_FILENAME} ) &&    #Is this file empty?      ( -r $req_params{SCRIPT_FILENAME} )       #can I read this file?    ) {      pipe( CHILD_RD,   PARENT_WR );      pipe( PARENT_ERR, CHILD_ERR );      my $pid = open( CHILD_O, "-|" );      unless ( defined($pid) ) {        print("Content-type: text/plain\r\n\r\n");        print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n";        next;      }      $oldfh = select(PARENT_ERR);      $|     = 1;      select(CHILD_O);      $| = 1;      select($oldfh);      if ( $pid > 0 ) {        close(CHILD_RD);        close(CHILD_ERR);        print PARENT_WR $stdin_passthrough;        close(PARENT_WR);        $rin = $rout = $ein = $eout = '';        vec( $rin, fileno(CHILD_O),    1 ) = 1;        vec( $rin, fileno(PARENT_ERR), 1 ) = 1;        $ein    = $rin;        $nfound = 0;         while ( $nfound = select( $rout = $rin, undef, $ein = $eout, 10 ) ) {          die "$!" unless $nfound != -1;          $r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;          $r2 = vec( $rout, fileno(CHILD_O),    1 ) == 1;          $e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;          $e2 = vec( $eout, fileno(CHILD_O),    1 ) == 1;           if ($r1) {            while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {              print STDERR $errbytes;            }            if ($!) {              $err = $!;              die $!;              vec( $rin, fileno(PARENT_ERR), 1 ) = 0              unless ( $err == EINTR or $err == EAGAIN );            }          }          if ($r2) {            while ( $bytes = read( CHILD_O, $s, 4096 ) ) {              print $s;            }            if ( !defined($bytes) ) {              $err = $!;              die $!;              vec( $rin, fileno(CHILD_O), 1 ) = 0              unless ( $err == EINTR or $err == EAGAIN );            }          }          last if ( $e1 || $e2 );        }        close CHILD_RD;        close PARENT_ERR;        waitpid( $pid, 0 );      } else {        foreach $key ( keys %req_params ) {          $ENV{$key} = $req_params{$key};        }         # cd to the script's local directory        if ( $req_params{SCRIPT_FILENAME} =~ /^(.*)\/[^\/] +$/ ) {          chdir $1;         }        close(PARENT_WR);        #close(PARENT_ERR);        close(STDIN);        close(STDERR);         #fcntl(CHILD_RD, F_DUPFD, 0);        syscall( &SYS_dup2, fileno(CHILD_RD),  0 );        syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );         #open(STDIN, "<&CHILD_RD");        exec( $req_params{SCRIPT_FILENAME} );        die("exec failed");      }    } else {      print("Content-type: text/plain\r\n\r\n");      print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\n";    }  }}

將nginx cgi守護進程為開機自啟動

root@SNDA-192-168-1-58:~/hd1/bin# echo "/usr/local/bin/cgiwrap-fcgi.pl&" > /etc/init.d/nginx-cgi 

root@simba-laptop:/home/simba/tmp# chmod 755 /etc/init.d/nginx-cgi 

root@SNDA-192-168-1-58:~/hd1/bin# update-rc.d nginx-cgi defaults 23

配置Nginx

set $web_root  /var/www/nginx-default;#設定變數 web_root...location / {root   $web_root;index  index.html index.htm;}location ~ .*\.cgi$ {gzip off; #gzip makes scripts feel slower since they have to complete before getting gzippedfastcgi_pass  unix:/tmp/cgiwrap-dispatch.sock;fastcgi_index index.cgi;fastcgi_param SCRIPT_FILENAME  $web_root$fastcgi_script_name;fastcgi_param QUERY_STRING     $query_string;fastcgi_param REQUEST_METHOD   $request_method;fastcgi_param CONTENT_TYPE     $content_type;fastcgi_param CONTENT_LENGTH   $content_length;fastcgi_param GATEWAY_INTERFACE  CGI/1.1;fastcgi_param SERVER_SOFTWARE    nginx;fastcgi_param SCRIPT_NAME        $fastcgi_script_name;fastcgi_param REQUEST_URI        $request_uri;fastcgi_param DOCUMENT_URI       $document_uri;fastcgi_param DOCUMENT_ROOT      $web_root;fastcgi_param SERVER_PROTOCOL    $server_protocol;fastcgi_param REMOTE_ADDR        $remote_addr;fastcgi_param REMOTE_PORT        $remote_port;fastcgi_param SERVER_ADDR        $server_addr;fastcgi_param SERVER_PORT        $server_port;fastcgi_param SERVER_NAME        $server_name;#include /root/hd1/conf.d/nginx/fcgi-parms}

測試:

將以下指令碼儲存到web根目錄下,用瀏覽器訪問。

cgi-test.cgi

#!/usr/bin/perlprint "Content-type: text/html\n\n";print "<html><body>Hello, world.</body></html>";

http://localhost/cgi-test.cgi

cgi-test-python.cgi

#!/usr/bin/pythonprint "Content-type: text/html\n\n"print "<html><body>Hello, world. Hello, Python.</body></html>"

http://localhost/cgi-test-python.cgi

參考:

http://wiki.nginx.org/NginxSimpleCGI讓 Nginx 支援 cgiNginx + nagios +perl fcgi

實戰Nginx與PHP(FastCGI)的安裝、配置與最佳化

為了AWSTATS給NGINX添加FASTCGI方式的PERL支援

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.