{"id":1350,"date":"2012-01-14T17:35:48","date_gmt":"2012-01-14T09:35:48","guid":{"rendered":"http:\/\/doophp.sinaapp.com\/?p=1350"},"modified":"2012-01-15T15:14:15","modified_gmt":"2012-01-15T07:14:15","slug":"nginx-perl-fastcgi","status":"publish","type":"post","link":"https:\/\/blog.vimge.com\/archives\/linux\/nginx-perl-fastcgi.html","title":{"rendered":"Nginx \u914d\u7f6e\u5b89\u88c5 Perl \u652f\u6301"},"content":{"rendered":"

\u672c\u6587\u5b89\u88c5\u73af\u5883\u4e3aCentOS5.4\uff0cNginx1.0.11<\/p>\n

Perl\u4ee5FastCGI\u6a21\u5f0f\u5b89\u88c5\uff0c\u9700\u8981\u9996\u5148\u5b89\u88c5\u4ee5\u4e0b2\u4e2a\u8f6f\u4ef6\uff08CentOS\u81ea\u5e26Perl\u652f\u6301\u4e0d\u505a\u8003\u8651\uff09<\/p>\n

    \n
      \n
    1. FCGI
      \n[code]
      \n#wget\u00a0http:\/\/search.cpan.org\/CPAN\/authors\/id\/F\/FL\/FLORA\/FCGI-0.74.tar.gz
      \n#tar xzvf\u00a0FCGI-0.74.tar.gz
      \n#cd FCGI-0.74
      \n#perl Makefile.PL
      \n#make
      \n#make install
      \n[\/code]<\/li>\n<\/ol>\n<\/ol>\n

      <\/p>\n

        \n
      1. FCGI-ProcManager
        \n[code]
        \n#wget http:\/\/search.cpan.org\/CPAN\/authors\/id\/B\/BO\/BOBTFISH\/FCGI-ProcManager-0.24.tar.gz
        \n#tar xzvf\u00a0FCGI-ProcManager-0.24.tar.gz
        \n#cd\u00a0FCGI-ProcManager-0.24
        \n#perl Makefile.PL
        \n#make
        \n#make install
        \n[\/code]<\/li>\n<\/ol>\n

        \u4fdd\u5b58\u4ee5\u4e0b\u6587\u4ef6\u5230 \/usr\/local\/bin\/cgiwrap-fcgi.pl<\/p>\n

        [code]
        \n#!perl
        \nuse FCGI;
        \nuse Socket;
        \nuse FCGI::ProcManager;
        \nsub shutdown { FCGI::CloseSocket($socket); exit; }
        \nsub restart { FCGI::CloseSocket($socket); &main; }
        \nuse sigtrap ‘handler’, \\&shutdown, ‘normal-signals’;
        \nuse sigtrap ‘handler’, \\&restart, ‘HUP’;
        \nrequire ‘syscall.ph’;
        \nuse POSIX qw(setsid);<\/p>\n

        END() { }
        \nBEGIN() { }
        \n{
        \n no warnings;
        \n *CORE::GLOBAL::exit = sub { die "fakeexit\\nrc=" . shift() . "\\n"; };
        \n};<\/p>\n

        eval q{exit};
        \nif ($@) {
        \n exit unless $@ =~ \/^fakeexit\/;
        \n}
        \n&main;<\/p>\n

        sub daemonize() {
        \n chdir ‘\/’ or die "Can’t chdir to \/: $!";
        \n defined( my $pid = fork ) or die "Can’t fork: $!";
        \n exit if $pid;
        \n setsid() or die "Can’t start a new session: $!";
        \n umask 0;
        \n}<\/p>\n

        sub main {
        \n $proc_manager = FCGI::ProcManager->new( {n_processes => 5} );
        \n $socket = FCGI::OpenSocket( "\/var\/run\/nginx\/cgiwrap-dispatch.sock", 10 )
        \n ; #use UNIX sockets – user running this script must have w access to the ‘nginx’ folder!!
        \n $request =
        \n FCGI::Request( \\*STDIN, \\*STDOUT, \\*STDERR, \\%req_params, $socket,
        \n &FCGI::FAIL_ACCEPT_ON_INTR );
        \n $proc_manager->pm_manage();
        \n if ($request) { request_loop() }
        \n FCGI::CloseSocket($socket);
        \n}<\/p>\n

        sub request_loop {
        \n while ( $request->Accept() >= 0 ) {
        \n $proc_manager->pm_pre_dispatch();<\/p>\n

        #processing any STDIN input from WebServer (for CGI-POST actions)
        \n $stdin_passthrough = ”;
        \n { no warnings; $req_len = 0 + $req_params{‘CONTENT_LENGTH’}; };
        \n if ( ( $req_params{‘REQUEST_METHOD’} eq ‘POST’ ) && ( $req_len != 0 ) ) {
        \n my $bytes_read = 0;
        \n while ( $bytes_read < $req_len ) {
        \n my $data = ”;
        \n my $bytes = read( STDIN, $data, ( $req_len – $bytes_read ) );
        \n last if ( $bytes == 0 || !defined($bytes) );
        \n $stdin_passthrough .= $data;
        \n $bytes_read += $bytes;
        \n }
        \n }<\/p>\n

        #running the cgi app
        \n if (
        \n ( -x $req_params{SCRIPT_FILENAME} ) && #can I execute this?
        \n ( -s $req_params{SCRIPT_FILENAME} ) && #Is this file empty?
        \n ( -r $req_params{SCRIPT_FILENAME} ) #can I read this file?
        \n ) {
        \n pipe( CHILD_RD, PARENT_WR );
        \n pipe( PARENT_ERR, CHILD_ERR );
        \n my $pid = open( CHILD_O, "-|" );
        \n unless ( defined($pid) ) {
        \n print("Content-type: text\/plain\\r\\n\\r\\n");
        \n print "Error: CGI app returned no output – Executing $req_params{SCRIPT_FILENAME} failed !\\n";
        \n next;
        \n }
        \n $oldfh = select(PARENT_ERR);
        \n $| = 1;
        \n select(CHILD_O);
        \n $| = 1;
        \n select($oldfh);
        \n if ( $pid > 0 ) {
        \n close(CHILD_RD);
        \n close(CHILD_ERR);
        \n print PARENT_WR $stdin_passthrough;
        \n close(PARENT_WR);
        \n $rin = $rout = $ein = $eout = ”;
        \n vec( $rin, fileno(CHILD_O), 1 ) = 1;
        \n vec( $rin, fileno(PARENT_ERR), 1 ) = 1;
        \n $ein = $rin;
        \n $nfound = 0;<\/p>\n

        while ( $nfound = select( $rout = $rin, undef, $ein = $eout, 10 ) ) {
        \n die "$!" unless $nfound != -1;
        \n $r1 = vec( $rout, fileno(PARENT_ERR), 1 ) == 1;
        \n $r2 = vec( $rout, fileno(CHILD_O), 1 ) == 1;
        \n $e1 = vec( $eout, fileno(PARENT_ERR), 1 ) == 1;
        \n $e2 = vec( $eout, fileno(CHILD_O), 1 ) == 1;<\/p>\n

        if ($r1) {
        \n while ( $bytes = read( PARENT_ERR, $errbytes, 4096 ) ) {
        \n print STDERR $errbytes;
        \n }
        \n if ($!) {
        \n $err = $!;
        \n die $!;
        \n vec( $rin, fileno(PARENT_ERR), 1 ) = 0
        \n unless ( $err == EINTR or $err == EAGAIN );
        \n }
        \n }
        \n if ($r2) {
        \n while ( $bytes = read( CHILD_O, $s, 4096 ) ) {
        \n print $s;
        \n }
        \n if ( !defined($bytes) ) {
        \n $err = $!;
        \n die $!;
        \n vec( $rin, fileno(CHILD_O), 1 ) = 0
        \n unless ( $err == EINTR or $err == EAGAIN );
        \n }
        \n }
        \n last if ( $e1 || $e2 );
        \n }
        \n close CHILD_RD;
        \n close PARENT_ERR;
        \n waitpid( $pid, 0 );
        \n } else {
        \n foreach $key ( keys %req_params ) {
        \n $ENV{$key} = $req_params{$key};
        \n }<\/p>\n

        # cd to the script’s local directory
        \n if ( $req_params{SCRIPT_FILENAME} =~ \/^(.*)\\\/[^\\\/] +$\/ ) {
        \n chdir $1;
        \n }
        \n close(PARENT_WR);
        \n #close(PARENT_ERR);
        \n close(STDIN);
        \n close(STDERR);<\/p>\n

        #fcntl(CHILD_RD, F_DUPFD, 0);
        \n syscall( &SYS_dup2, fileno(CHILD_RD), 0 );
        \n syscall( &SYS_dup2, fileno(CHILD_ERR), 2 );<\/p>\n

        #open(STDIN, "<&CHILD_RD");
        \n exec( $req_params{SCRIPT_FILENAME} );
        \n die("exec failed");
        \n }
        \n } else {
        \n print("Content-type: text\/plain\\r\\n\\r\\n");
        \n print "Error: No such CGI app – $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.\\n";
        \n }
        \n }
        \n}
        \n[\/code]<\/p>\n

        \u4ee5\u4e0a\u811a\u672c\u5c06\u751f\u6210\/var\/run\/nginx\/cgiwrap-dispatch.sock\u6587\u4ef6\uff0c\u8bf7\u786e\u4fdd\u8def\u5f84\u6709\u6548\uff0c\u4ee5\u53caNginx\u5de5\u4f5c\u8fdb\u7a0b\u6709\u8bfb\u5199\u6743\u9650.
        \n\u8fd0\u884cperl fast-cig
        \n#perl \/usr\/local\/bin\/cgiwrap-fcgi.pl &<\/p>\n

        \u914d\u7f6eNginx<\/p>\n

        [code]
        \n#\u6dfb\u52a0\u4ee5\u4e0b\u4ee3\u7801
        \nlocation ~ \\.(cgi|pl)$ {
        \n gzip off; #gzip makes scripts feel slower since they have to complete before getting gzipped
        \n fastcgi_pass unix:\/var\/run\/nginx\/cgiwrap-dispatch.sock;
        \n fastcgi_index index.cgi;
        \n fastcgi_param SCRIPT_FILENAME \/var\/www\/cgi-bin$fastcgi_script_name;
        \n fastcgi_param QUERY_STRING $query_string;
        \n fastcgi_param REQUEST_METHOD $request_method;
        \n fastcgi_param CONTENT_TYPE $content_type;
        \n fastcgi_param CONTENT_LENGTH $content_length;
        \n fastcgi_param GATEWAY_INTERFACE CGI\/1.1;
        \n fastcgi_param SERVER_SOFTWARE nginx;
        \n fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        \n fastcgi_param REQUEST_URI $request_uri;
        \n fastcgi_param DOCUMENT_URI $document_uri;
        \n fastcgi_param DOCUMENT_ROOT $document_root;
        \n fastcgi_param SERVER_PROTOCOL $server_protocol;
        \n fastcgi_param REMOTE_ADDR $remote_addr;
        \n fastcgi_param REMOTE_PORT $remote_port;
        \n fastcgi_param SERVER_ADDR $server_addr;
        \n fastcgi_param SERVER_PORT $server_port;
        \n fastcgi_param SERVER_NAME $server_name;
        \n}
        \n[\/code]<\/p>\n

        \u53c2\u6570\u8d44\u6599\uff1ahttp:\/\/wiki.nginx.org\/SimpleCGI<\/p>\n","protected":false},"excerpt":{"rendered":"

        \u672c\u6587\u5b89\u88c5\u73af\u5883\u4e3aCentOS5.4\uff0cNginx1.0.11 Perl\u4ee5FastCGI\u6a21\u5f0f\u5b89\u88c5\uff0c\u9700\u8981\u9996\u5148\u5b89\u88c5\u4ee5\u4e0b2 […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[8],"tags":[33,34],"_links":{"self":[{"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/posts\/1350"}],"collection":[{"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/comments?post=1350"}],"version-history":[{"count":11,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/posts\/1350\/revisions"}],"predecessor-version":[{"id":1385,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/posts\/1350\/revisions\/1385"}],"wp:attachment":[{"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/media?parent=1350"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/categories?post=1350"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.vimge.com\/wp-json\/wp\/v2\/tags?post=1350"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}