cgi 지원
10746 단어 nginx cgi
● perl fcgi 설치
[root@localhost ~]# cd /usr/local/
[root@localhost /usr/local]# wget http://www.cpan.org/modules/by-module/FCGI/FCGI-0.67.tar.gz
[root@localhost /usr/local]# tar -xzxf FCGI-0.67.tar.gz
[root@localhost /usr/local]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-0.67]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-0.67]# perl Makefile.PL
[root@localhost /usr/local/FCGI-0.67]# make && make install
● FCGI - ProcManager 설치
[root@localhost ~]# cd /usr/local/
[root@localhost /usr/local]# wget http://search.cpan.org/CPAN/authors/id/B/BO/BOBTFISH/FCGI-ProcManager-0.24.tar.gz
[root@localhost /usr/local]# tar -xzxf FCGI-ProcManager-0.24.tar.gz
[root@localhost /usr/local]# cd FCGI-ProcManager-0.24
[root@localhost /usr/local/FCGI-ProcManager-0.24]# cd FCGI-0.67
[root@localhost /usr/local/FCGI-ProcManager-0.24]# perl Makefile.PL
[root@localhost /usr/local/FCGI-ProcManager-0.24]# make && make install
준비 작업 이 끝나 면 nginx 가 cgi 여행 을 지원 할 수 있 습 니 다.
1. perl 로 daemon 프로그램 을 써 서 cgi 파일 을 처리 합 니 다.
다음은 perl 로 쓴 daemon 프로그램 입 니 다. cgiwrap - fcgi. pl 이 라 고 명명 되 어 / usr / local / bin 에 넣 습 니 다.이 perl 코드 의 36 번 째 줄 과 37 번 째 줄 은 모두 perl CGI 의 요청 을 감청 하 는 것 을 표시 합 니 다.그 중:
127.0.0.1: 8999 는 TCP / IP 프로 토 콜 응답 요청 을 표시 합 니 다.
/var / run / nginx / giwrap - dispatch. sock 은 유 닉 스 소켓 을 사용 하여 CGI 요청 에 응답 하 는 것 을 표시 합 니 다.
우리 의 예제 에 서 는 유 닉 스 socket 방식 으로 CGI 요청 에 응답 할 것 입 니 다.
#!/usr/bin/perl -w
use 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);
#&daemonize; we don't daemonize when running under runsv
#this keeps the program alive or something after exec'ing perl scripts
END() { }
BEGIN() { }
{
no warnings;
*CORE::GLOBAL::exit = sub { die "fakeexit
rc=" . shift() . "
"; };
};
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 {
#$socket = FCGI::OpenSocket( "127.0.0.1:8999", 10 ); #use IP sockets
#$socket = FCGI::OpenSocket( "/var/run/nginx/cgiwrap-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx'
folder!!
#foreach $item (keys %ENV) { delete $ENV{$item}; }
$proc_manager = FCGI::ProcManager->new( {n_processes => 5} );
$socket = FCGI::OpenSocket( "/var/run/nginx/cgiwrap-dispatch.sock", 10 ); #use UNIX sockets - user running this script must have w access to the 'nginx'
folder!!
$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();
"cgiwrap-fcgi.pl" [dos] 164L, 6275C
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
\r
");
print "Error: No such CGI app - $req_params{SCRIPT_FILENAME} may not exist or is not executable by this process.
";
}
}
}
2. / var / run / nginx / giwrap - dispatch. sock 관련
cgiwrap - dispatch. sock 파일 은 CGI 요청 에 응답 하 는 데 사 용 됩 니 다.실제로 파일 이름 은 / var / run / ngin 에 없 을 수도 있 습 니 다.CGI 가 요청 한 파일 을 처리 하 는 것 은 완전히 자유롭다.물론, 우 리 는 / var / run / nginx / cgwrap - dispatch. sock [을 예 로 들 어 설명 합 니 다.
우리 기계 에는 / var / run / nginx 와 같은 디 렉 터 리 가 존재 하지 않 습 니 다. mkdir 명령 을 통 해 이러한 계층 구조의 디 렉 터 리 를 만 들 수 있 습 니 다. / cgiwrap - dispatch. sock 파일 은 touch / cgiwrap - dispatch. sock 을 통 해 빈 파일 을 만 들 면 됩 니 다.
nginx. cong 에서 설명 한 user 의 사용자 와 그룹 이 다음 과 같은 권한 을 가지 고 있 는 지 확인 하 십시오.
/ var / run / nginx 에 W 권한 이 있 습 니 다.
cgiwrap - dispatch. sock 에 W 권한 이 있 습 니 다.
3. 배경 에서 cgiwrap - fcgi. pl 실행
# cgiwrap-fcgi.pl
[root@localhost ~]# /usr/local/bin/cgiwrap-fcgi.pl
Useless use of a constant in void context at ./cgiwrap-fcgi.pl line 20.
FastCGI: manager (pid 2452): initialized
FastCGI: server (pid 2453): initialized
FastCGI: manager (pid 2452): server (pid 2453) started
FastCGI: manager (pid 2452): server (pid 2454) started
FastCGI: server (pid 2454): initialized
FastCGI: server (pid 2455): initialized
FastCGI: manager (pid 2452): server (pid 2455) started
FastCGI: server (pid 2456): initialized
FastCGI: manager (pid 2452): server (pid 2456) started
FastCGI: server (pid 2457): initialized
FastCGI: manager (pid 2452): server (pid 2457) started
FastCGI: manager (pid 2452): server (pid 2453) exited with status 2304
FastCGI: server (pid 5456): initialized
FastCGI: manager (pid 2452): server (pid 5456) started
FastCGI: manager (pid 2452): server (pid 2454) exited with status 2304
FastCGI: manager (pid 2452): server (pid 9471) started
FastCGI: server (pid 9471): initialized
cgiwrap - fcgi. pl 을 실행 하면 콘 솔 에서 로 그 를 출력 합 니 다. 이 스 크 립 트 가 정상적으로 실행 되 고 있 는 지 확인 합 니 다. 나중에 로 그 를 출력 하지 않 으 려 면 cgiwrap - fcgi. pl 을 실행 할 수 있 습 니 다.
# cgiwrap-fcgi.pl
[root@localhost ~]# /usr/local/bin/cgiwrap-fcgi.pl > /dev/null 2>&1 &
# cgiwrap-fcgi.pl
# /etc/rc.local , :
/usr/local/bin/cgiwrap-fcgi.pl > /dev/null 2>&1 &
4. 웹 루트 디 렉 터 리 에 test. cgi 를 만들어 테스트 합 니 다.
웹 디 렉 터 리 와 디 렉 터 리 를 / home / git 로 설정 하고 test. cgi 파일 을 만 들 며 ngix. cong 에서 설명 한 user 의 사용자 와 그룹 이 test. cgi 에 대한 실행 가능 한 권한 을 갖 도록 합 니 다.
[root@localhost ~]# vi /home/git/test.cgi
#!/usr/bin/perl
print "Content-type: text/html
";
print "Hello, world.";
5. nginx. conf 에서 다음 설정 을 합 니 다.
location ~ .*\.cgi$ {
fastcgi_pass unix:/var/run/nginx/cgiwrap-dispatch.sock;
fastcgi_index index.cgi;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
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 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 param 이 설정 을 하나의 파일 로 독립 시 킬 수 있 습 니 다. 예 를 들 어 fastcgi params. conf 와 같은 다음 include 명령 을 통 해 포함 시 킬 수 있 습 니 다.
여기까지 nginx 가 cgi 를 지원 하도록 했 습 니 다. 접근 할 수 있 습 니 다.http://localhost/test.cgi 설정 이 성 공 했 는 지 시험 해 보 세 요.