【问题标题】:mod_perl and inheriting STDIN in child processmod_perl 并在子进程中继承 STDIN
【发布时间】:2010-12-17 16:34:22
【问题描述】:

我有这个旧的 Perl 脚本,它应该充当基于 HTTP 的客户端和非 HTTP Java 服务器之间的某种代理:客户端将一些数据发布到这个 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(...);

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

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

从描述来看,来自 Apache2::SubProcess 的 spawn_proc_prog 可以解决问题(即将 POST 数据作为 STDIN 传递给子进程并取回子进程的输出),但如果我这样做似乎不起作用运行除另一个 Perl 脚本之外的任何东西。

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

【问题讨论】:

    标签: perl apache ubuntu cgi mod-perl


    【解决方案1】:

    哇,我希望这是来自客户端的低容量负载。在 mod_perl 中,您的标准输入与客户端的套接字句柄相关联,并且与标准输出相同。因此,要将您的 STDOUT 设置为 java 进程,您需要将 *STDOUT 设置为 Java 服务器的套接字句柄,或者在您的情况下,因为您正在打开一个进程,所以选择 STDOUT 并可能还通过设置 $| 使其无缓冲。此外,当您想将数据流式传输回客户端时,您需要直接写入客户端的套接字句柄或将 STDOUT 重置为其原始值。

    【讨论】:

    • 是的,我认为这适用于相当低容量的负载。您能否更具体地说明应该做什么? Perl 方面的选择将如何帮助 - 子进程在 Java 中,它不会关心 Perl 的默认流。此外,Java 服务器没有任何打开的套接字——至少没有明确地——它从 STDIN 读取它需要的所有内容(可能在下面实现为套接字,我不知道)。
    • 所以你的Java进程不监听任何网络通信,那么它就不是一个“服务器”。它所做的只是从 STDIN 读取。在您的 perl 脚本中执行此操作,我的 $sh = STDOUT; open(JFH, "|java $servervars -cp /var/www javaserver"); *标准输出 = JFH;然后从 perl 执行所有写入操作,因为您的 java 进程从 STDIN 读取,它会读取您从 perl 写入的所有内容,因为您以这种方式打开 java 进程(开头的 |)。完成编写后,您已将 perl 的 STDOUT 重置为原始输出文件句柄,这是您保存在 $sh 中的客户端套接字句柄
    • 或者我想我可以只打印 JFH "whatever" 而不是将 STDOUT 复制到变量中。谢谢,这似乎可行 - 虽然现在我不知道如何恢复 Java 的输出?我可以将它重定向到一个文件中,例如 open(JFH, "|java $servervars -cp /var/www javaserver > /tmp/somefile.txt");这可能就足够了,但我想知道是否有办法以某种方式将其作为流获取。
    猜你喜欢
    • 2010-09-08
    • 2012-09-29
    • 2011-11-21
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多