2016-08-29 6 views
14

Ich versuche herauszufinden, ob es eine Möglichkeit gibt, eine Antwort unter mod_perl 2 abzuschließen, ohne zum Haupt-Handler zurückzukehren. Ich habe bisher keine Methode in den Dokumenten gefunden. Das Folgende ist ein Beispiel dafür, was ich versuche zu erreichen:Schließen Antwort unter 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); 
    } 
} 

In einem regulären Perl-Skript, wie allein oder unter mod_cgi laufen stehen, ich konnte nur exit() mit der neuen Antwort, aber unter mod_perl Ich muß etwas in der ursprünglichen handler Unterroutine zurückgeben. Das führt mich dazu, eine ganze Kette von Anrufen im Auge zu behalten, bei denen alle etwas zurückgeben müssen, bis ich zurück zum Hauptnetz komme.

Zum Beispiel statt:

unless (check_something()) { ... 

Ich brauche Dinge wie:

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

und ich muss auch etwas Ähnliches tun in der Haupt Handler, der für einige ziemlich ungly ist Situationshandhabung.

Gibt es eine Möglichkeit, die Anfrage innerhalb eines verschachtelten Anrufs zu schließen, genau wie das, was ich mit meinem Beispiel zu veranschaulichen versuchte?

EDIT: Ich habe festgestellt, dass ich einen goto LABEL und Ort nennen kann, die kurz vor der letzten Rückkehr in dem Haupt handler Unterroutine beschriften. Es funktioniert, fühlt sich aber immer noch wie ein schmutziger Hack an. Ich hoffe wirklich, dass es einen schöneren Weg gibt.

+2

Ich bin kein Experte auf mod_perl2 aber in der Regel das sieht aus wie etwas, das Sie Ausnahmen für verwenden würde. Innerhalb von do_post_response(), benutze 'die 'Wir haben eine Situation ..."; 'und fange diese in handler() mit einem' eval' Block oder besser mit einem Modul wie 'Try :: Tiny'. Fügen Sie "Exception :: Class" hinzu, wenn Sie Ihre benutzerdefinierten Ausnahmen von anderen Ausnahmen unterscheiden müssen, die aufgrund anderer nicht abgefangener Fehler auftreten können. – mbethke

Antwort

2

Ich glaube, Sie immer noch in Ordnung sind Ausfahrt() aufzurufen, da mod_perl Überschreibungen Welche Lösung hat:

Ausfahrt

Im normalen Perl-Code exit() verwendet wird, um den Programmablauf zu stoppen und beenden Sie den Perl-Interpreter. Unter mod_perl möchten wir jedoch nur den Programmfluss stoppen, ohne den Perl-Interpreter zu löschen.

Sie sollten nichts unternehmen, wenn Ihr Code exit() -Aufrufe enthält und es OK ist, sie weiterhin zu verwenden. mod_perl kümmert sich darum, die exit() -Funktion mit einer eigenen Version zu überschreiben, die den Programmfluss stoppt und alle notwendigen Bereinigungen durchführt, aber den Server nicht killt. Dies geschieht durch Überschreiben:

* CORE :: GLOBAL :: Beenden = \ & ModPerl :: Util :: Exit;

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

+0

Ich habe versucht, zu beenden, bevor Sie diese Frage stellen. Es funktioniert nicht, es bringt den Handler nicht dazu, zurückzugeben, was er zurückgeben muss, es ist dasselbe wie ein Würfel zu rufen. –

+0

Dann haben Sie ein anderes Problem in Ihrem Code oder Ihre mod_perl wurde geändert. mod_perl überschreibt exit, wie in den Dokumenten, die ich verlinkt habe, erläutert. –

+0

Ja, es überschreibt exit, weil Sie sich in einem persistenten Interpreter befinden und nicht wollen, dass er wirklich beendet wird.Wenn Sie den echten Exit verwenden, töten Sie tatsächlich den Apache-Thread. Die Tatsache, dass es exit überschreibt, beendet jedoch nur den aktuellen Funktionsaufruf, aber es gibt nichts an Apache zurück, und das ist das Problem, Apache benötigt eine tatsächliche Antwort oder es nimmt es als einen Fehler in der Anfrage. –

Verwandte Themen