简体   繁体   中英

Close response under mod_perl 2

I'm trying to find out if there's a way to complete a response under mod_perl 2 without returning to the main handler. Haven't been able to find a method for that in the docs so far. The following is an example of what I'm trying to achieve:

#!/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);
    }
}

In a regular Perl script, running as stand alone or under mod_cgi, I could just exit() with the new response, but under mod_perl I need to return something in the original handler subroutine. This is leading me to keep track of a whole chain of calls where all of them have to return something until I get back to the main handler .

For example, instead of:

unless (check_something()) { ...

I need to do things like:

my $check = check_something();
return $check if $check;

and I also have to do something similar in the main handler, which is quite ungly for some situation handlings.

Is there a way to close the request when inside a nested call, just like what I tried to illustrate with my example?

EDIT: I've found that I can call a goto LABEL and place that label just before the last return in the main handler subroutine. It works, but still feels like a dirty hack. I really hope there's a nicer way.

I think you are still fine to call exit() because mod_perl overrides what exit does:

exit

In the normal Perl code exit() is used to stop the program flow and exit the Perl interpreter. However under mod_perl we only want the stop the program flow without killing the Perl interpreter.

You should take no action if your code includes exit() calls and it's OK to continue using them. mod_perl worries to override the exit() function with its own version which stops the program flow, and performs all the necessary cleanups, but doesn't kill the server. This is done by overriding:

*CORE::GLOBAL::exit = \\&ModPerl::Util::exit;

https://perl.apache.org/docs/2.0/user/coding/coding.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM