Nginx fastcgi perl (pl、cgi)支持


Nginx fastcgi perl (pl、cgi)支持

1. 安装FCGI模块

# wget http://search.cpan.org/CPAN/authors/id/B/BO/BOBTFISH/FCGI-0.70.tar.gz
# tar zxvf FCGI-0.70.tar.gz
# cd FCGI-0.70
# perl Makefile.PL
# make
# make install

 

2. 安装 IO 和 IO::ALL模块

# wget http://search.cpan.org/CPAN/authors/id/G/GB/GBARR/IO-1.25.tar.gz
# tar zxvf IO-1.25.tar.gz
# cd IO-1.25
# perl Makefile.PL
# make
# make install

升级MakeMaker版
#wget http://search.cpan.org/CPAN/authors/id/M/MS/MSCHWERN/ExtUtils-MakeMaker-6.54.tar.gz
#tar zxvf  ExtUtils-MakeMaker-6.54.tar.gz
# perl Makefile.PL
Checking if your kit is complete...
Looks good
Using included version of ExtUtils::Manifest (1.56) as it is newer than the installed version (1.46).
Using included version of ExtUtils::Command (1.16) as it is newer than the installed version (1.09).
Using included version of ExtUtils::Installed (1.43) as it is newer than the installed version (0.08).
Using included version of ExtUtils::Packlist (1.43) as it is newer than the installed version (0.04).
Using included version of ExtUtils::Install (1.52) as it is newer than the installed version (1.33).
Writing Makefile for ExtUtils::MakeMaker
make
make install

# wget http://search.cpan.org/CPAN/authors/id/I/IN/INGY/IO-All-0.41.tar.gz
# tar zxvf IO-All-0.41.tar.gz
# cd IO-All
# perl Makefile.PL
# make
# make install

3. Perl脚本

点击下载Perl脚本perl-fcgi

#!/usr/bin/perl
#
#	author		Daniel Dominik Rudnicki
#	thanks to:	Piotr Romanczuk
#	email		daniel@sardzent.org
#	version		0.4.3
#	webpage		http://www.nginx.eu/
#
#	BASED @ http://wiki.codemongers.com/NginxSimpleCGI
#
#
# use strict;
use FCGI;
use Getopt::Long;
use IO::All;
use Socket;

sub init {
	GetOptions(	"h"	=> \$help,
			"verbose!"=>\$verbose,
			"pid=s"	=> \$filepid,
			"l=s" => \$logfile,
			"S:s"   => \$unixsocket,
			"P:i"   => \$unixport) or usage();
		usage() if $help;

	print "	Starting Nginx-fcgi\n" if $verbose;
	print "	Running with $> UID" if $verbose;
	print "	Perl $]" if $verbose;

	if ( $> == "0" ) {
		print "\n\tERROR\tRunning as a root!\n";
		print "\tSuggested not to do so !!!\n\n";
		exit 1;
	}

        if ( ! $logfile ) {
		print "\n\tERROR\t log file must declared\n"
			. "\tuse $0 with option -l filename\n\n";
		exit 1;
	}
	print "	Using log file $logfile\n" if $verbose;
	"\n\n" >> io($logfile);
	addlog($logfile, "Starting Nginx-cfgi");
	addlog($logfile, "Running with $> UID");
	addlog($logfile, "Perl $]");
	addlog($logfile, "Testing socket options");

	if ( ($unixsocket && $unixport) || (!($unixsocket) && !($unixport)) ) {
		print "\n\tERROR\tOnly one option can be used!\n";
		print "\tSuggested (beacuse of speed) is usage UNIX socket -S \n\n";
		exit 1;
	}

	if ($unixsocket) {
		print "	Daemon listening at UNIX socket $unixsocket\n" if $versbose;
		addlog($logfile, "Deamon listening at UNIX socket $unixsocket");
	} else {
		print "	Daemon listening at TCP/IP socket *:$unixport\n" if $verbose;
		#
		addlog($logfile, "Daemon listening at TCP/IP socket *:$unixport");
	}

	if ( -e $filepid ) {
		print "\n\tERROR\t PID file $filepid already exists\n\n";
		addlog($logfile, "Can not use PID file $filepid, already exists.");
		exit 1;
	}

	if ( $unixsocket ) {
		print "	Creating UNIX socket\n" if $verbose;
		$socket = FCGI::OpenSocket( $unixsocket, 10 );
		if ( !$socket) {
			print "	Couldn't create socket\n";
			addlog($logfile, "Couldn't create socket");
			exit 1;
		}
		print "	Using UNIX socket $unixsocket\n" if $verbose;
	} else {
		print "	Creating TCP/IP socket\n" if $verbose;
		$portnumber = ":".$unixport;
		$socket = FCGI::OpenSocket( $unixport, 10 );
		if ( !$socket ) {
			print "	Couldn't create socket\n";
			addlog($logfile, "Couldn't create socket");
			exit 1;
		}
		print " Using port $unixport\n" if $verbose;
	}
	addlog($logfile, "Socket created");

	if ( ! $filepid ) {
		print "\n\tERROR\t PID file must declared\n"
			. "\tuse $0 with option -pid filename\n\n";
		exit 1;
	}
	print "	Using PID file $filepid\n" if $verbose;
	addlog($logfile, "Using PID file $filepid");

	my $pidnumber = $$;
	$pidnumber > io($filepid);
	print " PID number $$\n" if $verbose;
	addlog($logfile, "PID number $pidnumber");
	
}

sub addzero {
	my ($date) = shift;
	if ($date < 10) {
		return "0$date";
	}
       return $date;
}

sub logformat {
	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$iddst) = localtime(time);
	my $datestring;
	$year += 1900;
	$mon++;
	$mon  = addzero($mon);
	$mday = addzero($mday);
	$min  = addzero($min);
	$datestring = "$year-$mon-$mday $hour:$min";
	return($datestring);
}

sub addlog {
	my ($log_file, $log_message) = @_;
	my $curr_time = logformat();
	my $write_message = "[$curr_time]   $log_message";
	$write_message >> io($log_file);
	"\n" >> io($log_file);
}

sub printerror {
	my $message = @_;
	print "\n	Nginx FastCGI\tERROR\n"
		. "\t $message\n\n";
	exit 1;
}

sub usage {
	print "\n	Nginx FastCGI \n"
		. "\n\tusage: $0 [-h] -S string -P int\n"
		. "\n\t-h\t\t: this (help) message"
		. "\n\t-S path\t\t: path for UNIX socket"
		. "\n\t-P port\t\t: port number"
		. "\n\t-p file\t\t: path for pid file"
		. "\n\t-l file\t\t: path for logfile"
		. "\n\n\texample: $0 -S /var/run/nginx-perl_cgi.sock -l /var/log/nginx/nginx-cfgi.log -pid /var/run/nginx-fcgi.pid\n\n";
	exit 1;
}


init;
#
END() { } BEGIN() { }
*CORE::GLOBAL::exit = sub { die "fakeexit\nrc=".shift()."\n"; }; eval q{exit}; 
if ($@) { 
	exit unless $@ =~ /^fakeexit/; 
} ;

# fork part
my $pid = fork();

if( $pid == 0 ) {
	&main;
	exit 0;
}

print " Forking worker process with PID $pid\n" if $verbose;
addlog($logfile, "Forking worker process with PID $pid");
print " Update PID file $filepid\n" if $verbose;
addlog($logfile, "Update PID file $filepid");
$pid > io($filepid);
print "	Worker process running.\n" if $verbose;
addlog ($logfile, "Parent process $$ is exiting");
exit 0;

sub main {
	$request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%req_params, $socket );
	if ($request) { request_loop()};
		FCGI::CloseSocket( $socket );
}

sub request_loop {
	while( $request->Accept() >= 0 ) {
		# processing any STDIN input from WebServer (for CGI-POST actions)
		$stdin_passthrough = '';
		$req_len = 0 + $req_params{'CONTENT_LENGTH'};
		if (($req_params{'REQUEST_METHOD'} eq 'POST') && ($req_len != 0) ){
			while ($req_len) {
				$stdin_passthrough .= getc(STDIN);
				$req_len--;	
			}
		}

		# running the cgi app
		if ( (-x $req_params{SCRIPT_FILENAME}) && 
			(-s $req_params{SCRIPT_FILENAME}) && 
			(-r $req_params{SCRIPT_FILENAME})
		){
			foreach $key ( keys %req_params){
				$ENV{$key} = $req_params{$key};
			}
			if ( $verbose ) {
				addlog($logfile, "running $req_params{SCRIPT_FILENAME}");
			}
			# http://perldoc.perl.org/perlipc.html#Safe-Pipe-Opens
			#
			open $cgi_app, '-|', $req_params{SCRIPT_FILENAME}, $stdin_passthrough or print("Content-type: text/plain\r\n\r\n"); print "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !\n"; # addlog($logfile, "Error: CGI app returned no output - Executing $req_params{SCRIPT_FILENAME} failed !");
			
			if ($cgi_app) { 
				print <$cgi_app>; 
				close $cgi_app; 
			}
		} 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";
			addlog($logfile, "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.");
		}
	}
}


 

脚本放在 /usr/local/nginx/perl-fcgi.pl

chmod 755 /usr/local/nginx/perl-fcgi.pl

chown www-data:www-data  /usr/local/nginx/perl-fcgi.pl

 

4.cgi启动/停止脚本 (www-data为nginx的运行用户)

# vi /usr/local/nginx/start_perl_cgi.sh

 

#!/bin/bash
#set -x
dir=/usr/local/nginx

stop ()
{
#pkill  -f  $dir/perl-fcgi.pl
kill $(cat $dir/logs/perl-fcgi.pid)
rm $dir/logs/perl-fcgi.pid 2>/dev/null
rm $dir/logs/perl-fcgi.sock 2>/dev/null
echo "stop perl-fcgi done"
}

start ()
{
rm $dir/now_start_perl_fcgi.sh 2>/dev/null

chown www-data.root $dir/logs
echo "$dir/perl-fcgi.pl -l $dir/logs/perl-fcgi.log -pid $dir/logs/perl-fcgi.pid -S $dir/logs/perl-fcgi.sock" >>$dir/now_start_perl_fcgi.sh

chown www-data.www-data $dir/now_start_perl_fcgi.sh
chmod u+x $dir/now_start_perl_fcgi.sh

sudo -u www-data $dir/now_start_perl_fcgi.sh
echo "start perl-fcgi done"
}

case $1 in
stop)
stop
;;
start)
start
;;
restart)
stop
start
;;
esac

chmod 755 /usr/local/nginx/start_perl_cgi.sh

chown www-data:www-data /usr/local/nginx/start_perl_cgi.sh

# 启动脚本

# /usr/local/nginx/start_perl_cgi.sh start

正常情况下在/usr/local/nginx/logs 下生成 perl-fcgi.sock 这个文件,如果没有生成,那就要检查下上面的步聚了.

5. 配置nginx

/usr/local/nginx/html 根目录的用户更改成 www-data

 

server {
    listen       80;
    server_name  _;
    location / {
        root   /usr/local/nginx/html;
        index  index.html index.htm index.cgi;
    }
    location ~ .*\.(pl|cgi)?$
    {
      gzip off;
      root   /data/nginx/html;
      fastcgi_pass  unix:/usr/local/nginx/logs/perl-fcgi.sock;
      fastcgi_index index.cgi;
      fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
      fastcgi_param  SERVER_SOFTWARE    nginx;
      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  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
      fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
      fastcgi_param  REQUEST_URI        $request_uri;
      fastcgi_param  DOCUMENT_URI       $document_uri;
      fastcgi_param  DOCUMENT_ROOT      $document_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;
      fastcgi_read_timeout   60;
     }
}


 

6.Perl探针测试

 

# disable filename globbing  
set -f 
echo "Content-type: text/plain; charset=iso-8859-1"  
echo   

echo CGI/1.0 test script report:

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值