Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 handlersubroutine. 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 handlersubroutine. It works, but still feels like a dirty hack. I really hope there's a nicer way.

like image 531
Francisco Zarabozo Avatar asked Aug 29 '16 21:08

Francisco Zarabozo


1 Answers

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

like image 126
Daniel Wisehart Avatar answered Sep 21 '22 20:09

Daniel Wisehart