vicendominguez

cgi mode with perl on Nginx + FreeBSD9

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