mod_perl并在子进程中继承STDIN

时间:2009-11-18 00:15:30

标签: perl apache ubuntu cgi mod-perl

我有这个旧的Perl脚本,它应该充当基于HTTP的客户端和非HTTP Java服务器之间的代理:客户端将一些数据POST到此Perl脚本,然后脚本将调用Java服务器,获得响应并将其返回给客户。

Perl部分像这样调用服务器:

$servervars = "-DREMOTE_HOST=$ENV{'REMOTE_HOST'}"; 
#(a few other server variables passed this way)

system "java $servervars -cp /var/www javaserver";

然后Java服务器将会:

InputStream serverData = System.in;
serverData.read(); //and read, and read it on
//....
//print response:
System.out.print("Content-type: application/octet-stream\n\n");
System.out.write(...);

问题是,当通过CGI调用Perl脚本时这很好用,但如果Perl脚本由mod_perl(实际上是mod_perl2)处理则根本不起作用。显然Java部分没有从Perl获取STDIN(serverData.available()返回0)并且Perl没有得到STDOUT。后者可以通过打印`java ...`(即反引号)而不是系统“java ...”来解决,但我不知道如何处理STDIN。

Perl脚本本身能够读取STDIN中的POSTed数据。我也试图生成一个测试Perl脚本而不是Java应用程序,但这也没有得到父脚本的STDIN。

根据描述判断,来自Apache2 :: SubProcess的spawn_proc_prog可以做到这一点(即将POST数据作为STDIN传递给子进程并返回子进程'输出),但是如果我不能工作运行除了另一个Perl脚本以外的任何东西。

有没有办法让子进程继承父脚本的STDIN?我可以在Perl脚本中读取流并将其内容作为命令行参数传递,但我认为这将受命令行长度限制,有时可能会有很多数据(如图片),所以我真的想弄清楚如何继承流。

1 个答案:

答案 0 :(得分:1)

哇,我希望这是来自客户端的低容量负载。在mod_perl中,stdin与客户端的套接字句柄绑定,与stdout相同。因此,要将STDOUT设置为java进程,需要将* STDOUT设置为Java服务器的套接字句柄,或者在您打开进程的情况下执行select STDOUT,并可能通过设置$ |来使其无缓冲。此外,当您想要将数据流回客户端时,您需要直接写入客户端的套接字句柄或将STDOUT重置为其原始值。