Perl CGI получает параметры из другого запроса на текущий URL - PullRequest
3 голосов
/ 23 ноября 2011

Это странно.:)

У меня есть скрипт, работающий под Apache 1.3, с опцией Apache :: PerlRun mod_perl.Он использует стандартный модуль CGI.pm.Это регулярно используемый сценарий на занятом сервере, доступ к которому осуществляется через https.

URL-адрес обычно выглядит примерно так: *

/ script.pl? Action = edit & id = 47049

Который затем вводится в Perl обычным способом ...

my $action = $cgi->param("action");
my $id = $cgi->param("id");

Это успешно работает в течение нескольких лет.Однако на этой неделе мы начали получать запросы поддержки от наших клиентов, которые обращались к этому сценарию и получали пустые страницы.У нас уже была строка, подобная следующей, которая помещала текущий URL в форму, которую мы используем для того, чтобы клиенты сообщали о проблеме со страницей ...

$cgi->url(-query => 1);

И когда мы просматриваем источник страницы, результатэтой команды является тот же URL, но с совершенно другой строкой запроса.

/ script.pl? action = login & user = foo & password = bar

Строка запроса, котораямы распознаем его как совершенно другой скрипт в другом месте нашей системы.

Как бы странно это ни звучало, кажется, что когда пользователи обращаются к URL-адресу со строкой запроса, строка запроса, которую видит скрипт, является одной из следующих:предыдущий запрос на другой скрипт.Конечно, скрипт не может обработать это действие и ничего не выводит.

У нас есть несколько автоматических тестовых скриптов, работающих, чтобы увидеть, как часто это происходит, и это не каждый раз.Чтобы добавить некоторую путаницу в смесь, после перезапуска Apache, проблема, кажется, изначально исчезает полностью, чтобы вернуться позже.Поэтому, что бы ни вызывало его, оно каким-то образом облегчается при перезапуске, но мы не видим, как Apache может принять запрос от одного пользователя и смешать его с другим.

1 Ответ

2 голосов
/ 24 ноября 2011

Это, похоже, интересная комбинация Apache 1.3, mod_perl 1.31, CGI.pm и Apache :: GTopLimit.

В мае прошлого года была зарегистрирована ошибка против CGI.pm: RT # 57184

Что также указывает на то, что CGI.pm params не очищается?

CGI.pm регистрирует обработчик очистки для очистки всего его кэша.... (строка 360)

$r->register_cleanup(\&CGI::_reset_globals);

Apache::GTopLimit (например, Apache::SizeLimit, упомянутый в отчете об ошибке) также имеет такой обработчик:

$r->post_connection(\&exit_if_too_big) if $r->is_main;

В pre mod_perl1.31, post_connection и register_cleanup, кажется, выталкивают в стек, в то время как в 1.31 это выглядит так, как будто GTopLimit one перекрывает запись CGI.pm.Так что если ваша функция GTopLimit сработает из-за того, что процесс Apache стал слишком большим, то CGI.pm не будет очищен, и он останется открытым для возврата тех же параметров в следующий раз, когда вы его используете.

похоже, решение состоит в том, чтобы изменить строку 360 файла CGI.pm на;

$r->push_handlers( 'PerlCleanupHandler', \&CGI::_reset_globals);

, что явно помещает обработчик в список.

Наш перезапуск Apache временно решил проблему, потому что это уменьшилоразмер всех процессов и не дал GTopLimit никаких оснований для запуска.

И мы предполагаем, что он появился за последние несколько недель, потому что мы увеличили размер процесса Apache либо за счет новых разработок, которые включали нечто, что не былот. до.

Все тесты до сих пор указывают на эту проблему, поэтому пальцы скрещены!

...