网上关于nginx支持perl cgi的文章不少。
不过多半是方法1
即基于
的修改实现
它的特点是用到了ProcManager模块
use FCGI;
use Socket;
use FCGI::ProcManager;
还有
require 'syscall.ph';
网上还有另外一种实现方式
http://blog.haohtml.com/archives/10909
这两种方式其实大同小异,代码也可能有互相借鉴。
感觉方式2虽然长点,但是更好理解。
但是部署后发现,这种方式只支持get方式,post方式无法获得参数
排查源码发现,问题出在这里
#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 !");
根据cgi post方式的定义,参数是通过stdin传递给cgi程序的,而作者这么写,实际是把参数放到了cgi程序的命令行参数,
修改为
open $cgi_app, '-|', "echo '$stdin_passthrough' | '$req_params{SCRIPT_FILENAME}'" 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 !");
测试通过。也可以支持中文参数
注意,'$stdin_passthrough'要加'',防止htnl参数中&的歧义.
顺便吐下槽
这些开源作者注释也不规范(方法1的转载很多人都把注释头去掉了,很不好)
#!/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
#
#
缺少修改日期,http://www.nginx.eu/也连不上
所以也不知道那个版本更新更好。
只是这个方法用到的模块更少,也没用到ph,感觉安装起来更简单些。