2016-08-29 28 views
14

我試圖找出是否有辦法在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腳本,運行在單獨或mod_cgi下站人,我就exit()與新的反應,但mod_perl下我需要返回原始handler子例程中的內容。這導致我跟蹤了一連串的電話,他們必須返回一些東西,直到我回到主要的handler

例如,而不是:

unless (check_something()) { ... 

,我需要做的事情一樣:

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

,我也要做主處理器類似的東西,這是相當ungly一些情況處理。

有沒有辦法在嵌套調用時關閉請求,就像我試圖用我的例子說明的那樣?

編輯:我發現我可以調用一個goto LABEL和地點,只是在主handler子程序最後返回之前的標籤。它的工作原理,但仍然感覺像一個骯髒的黑客。我真的希望有更好的方法。

+2

我對mod_perl2不是專家,但通常這看起來像是你會使用例外。在do_post_response()中,使用'die'我們有一個情況......「;並且使用'eval'模塊在handler()中捕獲它,甚至使用'Try :: Tiny'等模塊更好。如果您需要將自定義異常與其他未被捕獲的故障可能發生的異常區分開來,請添加一些'Exception :: Class'。 – mbethke

回答

2

我覺得你還是罰款調用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

+0

我在問這個問題之前試過退出。它不起作用,它不會使處理程序返回它需要返回的內容,這與調用die一樣。 –

+0

然後你的代碼中有另一個問題,或者你的mod_perl被修改了。正如我鏈接的文檔中所解釋的,mod_perl會覆蓋退出。 –

+0

是的,它覆蓋退出,因爲你在一個持久的解釋器,你不希望它真的退出。如果你使用真正的出口,那麼你實際上殺死了Apache線程。然而,它覆蓋exit的事實只是終止了當前的函數調用,但它不會返回任何東西給Apache,這就是問題所在,Apache需要一個實際的響應,或者將其視爲請求中的失敗。 –