{"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
<\/p>\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}]}}