English 中文(简体)
mod_perl and inheriting STDIN in child process
原标题:

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

");
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.

问题回答

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.





相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签