Закрыть ответ в 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