mod_perl и наследование STDIN в дочернем процессе - PullRequest
0 голосов
/ 18 ноября 2009

У меня есть старый сценарий 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 не получает STDIN от Perl (serverData.available () возвращает 0), а Perl не возвращает STDOUT обратно. Последнее можно исправить, выполнив print `java ...` (т.е. backticks) вместо системного «java ...», но я не знаю, что делать с STDIN.

Сам скрипт Perl может читать POST-данные в STDIN. Я также пытался порождать тестовый сценарий Perl вместо приложения Java, но он также не получает STDIN родительского сценария.

Судя по описанию, spawn_proc_prog из Apache2 :: SubProcess может сделать свое дело (т.е. передать данные POST как STDIN дочернему процессу и вернуть выходные данные дочернего процесса), но, похоже, он не будет работать, если я запустить что-нибудь, кроме другого сценария Perl.

Есть ли способ заставить дочерний процесс наследовать STDIN родительского скрипта? Я могу прочитать поток в сценарии Perl и передать его содержимое в качестве параметра командной строки, но я предполагаю, что это будет предметом ограничений длины командной строки, и иногда может быть много данных (например, изображения), поэтому мне бы очень хотелось выяснить, как наследовать поток.

1 Ответ

1 голос
/ 18 ноября 2009

Ух ты, я надеюсь, что это небольшая загрузка от клиента. В mod_perl ваш stdin привязан к дескриптору сокета от клиента и то же самое с stdout. Поэтому, чтобы установить свой STDOUT для процесса java, вам нужно установить * STDOUT в качестве дескриптора сокета Java-сервера, или в вашем случае, так как вы открываете процесс, выберите select STDOUT и, возможно, сделаете его небуферизованным, установив $ |. Также, когда вы хотите отправить данные обратно на ваш клиент, вам нужно записать либо непосредственно в дескриптор сокета клиента, либо сбросить STDOUT обратно к его первоначальному значению.

...