7macaw
7macaw

Reputation: 51

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\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.

Upvotes: 0

Views: 707

Answers (1)

Murali VP
Murali VP

Reputation: 6417

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.

Upvotes: 1

Related Questions