mod_perl并在子进程中继承STDIN
我有这个旧的 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 中的 POST 数据。我还尝试生成一个测试 Perl 脚本而不是 Java 应用程序,但这也无法获取父脚本的 STDIN。
从描述来看, Apache2::SubProcess 中的spawn_proc_prog 可以做到这一点(即将 POST 数据作为 STDIN 传递给子进程并返回子进程的输出),但如果我运行以下任何内容,它似乎不起作用另一个 Perl 脚本。
有没有办法让子进程继承父脚本的STDIN?我可以读取 Perl 脚本中的流并将其内容作为命令行参数传递,但我认为这会受到命令行长度限制,有时可能会有大量数据(如图片),所以我真的很想弄清楚如何继承流。
I have this old Perl script that is supposed to act as a proxy of sorts between HTTP-based clients and non-HTTP Java server: the client POSTs some data to this Perl script and the script would in turn call the Java server, get the response and return it to the client.
The Perl part calls the server like this:
$servervars = "-DREMOTE_HOST=$ENV{'REMOTE_HOST'}";
#(a few other server variables passed this way)
system "java $servervars -cp /var/www javaserver";
and then the Java server would go:
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(...);
Problem is, this works just fine when the Perl script is invoked via CGI, but doesn't work at all if the Perl script is handled by mod_perl (mod_perl2 actually). Apparently the Java part doesn't get the STDIN from Perl (serverData.available() returns 0) and Perl doesn't get the STDOUT back. The latter can be remedied by doing print `java...` (i.e. backticks) instead of system "java...", but I don't know what to do about STDIN.
The Perl script itself is able to read the POSTed data in STDIN. I've also tried to spawn a test Perl script instead of the Java application, and that doesn't get the parent script's STDIN either.
Judging by the description, spawn_proc_prog from Apache2::SubProcess could do the trick (i.e. pass the POST data as STDIN to the child process and get back the child process' output), but it doesn't seem to work if I run anything but another Perl script.
Is there any way to make the child process inherit the parent script's STDIN? I can read the stream in the Perl script and pass its contents as a command-line parameter, but I presume that would be the subject to command-line length limitations, and sometimes there can be a lot of data (like an picture), so I would really like to figure out how to inherit the stream.
哇,我希望这是来自客户端的少量负载。在 mod_perl 中,您的标准输入与客户端的套接字句柄相关联,并且与标准输出相同。因此,要将 STDOUT 设置为 java 进程,您需要将 *STDOUT 设置为 Java 服务器的套接字句柄,或者在您的情况下,因为您要打开一个进程,所以要选择 STDOUT,并且还可能通过设置 $| 使其无缓冲。此外,当您想要将数据流式传输回客户端时,您需要直接写入客户端的套接字句柄或将 STDOUT 重置回其原始值。
Wow, I hope this is a low volume load from the client. In mod_perl your stdin is tied to the socket handle from client and same with stdout. So to set your STDOUT to the java process, you need to set the *STDOUT to the Java server's socket handle, or in your case since you are opening a process do a select STDOUT and possibly also make it unbuffered by setting $|. Also when you want to stream data back to your client, you need to write either directly to the client's socket handle or reset STDOUT back to its original value.