Закрыть ответ в mod_perl 2
Я пытаюсь выяснить, есть ли способ завершить ответ в mod_perl 2, не возвращаясь к основному обработчику. Пока не удалось найти способ для этого в документах. Ниже приведен пример того, чего я пытаюсь достичь:
#!/usr/bin/perl
# This is some mod_perl handler
use strict;
use warnings;
use Apache2::Const ':common';
sub handler {
my $r = shift;
if ($r->method eq 'POST') {
# just to do something as example
do_post_response($r);
}
$r->content_type('text/plain');
print "Thank you, goodbye.";
return Apache2::Const::OK;
}
sub do_post_response {
my $r = shift;
unless (check_somthing()) {
# Suppose I find a situation that requires
# a different response than normal...
$r->content_type('text/plain');
print "We have a situation...";
$r->something_to_finish_the_request_immediatly(Apache2::Const::OK);
}
}
В регулярном Perl script, работающем как автономно, так и в mod_cgi, я мог бы просто exit()
с новым ответом, но в mod_perl
мне нужно вернуть что-то в исходной подпрограмме handler
. Это заставляет меня отслеживать целую цепочку вызовов, где все они должны что-то возвращать, пока я не вернусь к основному handler
.
Например, вместо:
unless (check_something()) { ...
Мне нужно делать такие вещи, как:
my $check = check_something();
return $check if $check;
и я также должен сделать что-то подобное в основном обработчике, что довольно неудобно для некоторых обработок ситуации.
Есть ли способ закрыть запрос, когда внутри вложенного вызова, как и то, что я попытался проиллюстрировать с помощью моего примера?
EDIT: Я обнаружил, что могу вызвать goto LABEL
и поместить этот ярлык непосредственно перед последним возвратом в основной подпрограмме handler
. Он работает, но все еще чувствует себя грязным хаком. Я действительно надеюсь, что там будет лучше.
Ответы
Ответ 1
Я думаю, что вы все равно можете вызвать exit(), потому что mod_perl переопределяет, что делает выход:
Выход
В нормальном выходе кода Perl() используется для остановки потока программы и выхода из интерпретатора Perl. Однако в mod_perl мы хотим только остановить поток программы, не убивая интерпретатора Perl.
Вы не должны предпринимать никаких действий, если ваш код включает вызовы exit(), и он ОК, чтобы продолжить их использование. mod_perl беспокоится о переопределении функции exit() со своей собственной версией, которая останавливает поток программы и выполняет все необходимые очистки, но не убивает сервер. Это делается путем переопределения:
* CORE:: GLOBAL:: exit =\& ModPerl:: Util:: exit;
https://perl.apache.org/docs/2.0/user/coding/coding.html