在mod_perl中代理请求时捕获500s

时间:2014-12-18 20:56:10

标签: apache perl mod-proxy mod-perl

我有一个mod_perl模块,可以在某些情况下代理对另一台服务器的请求。

e.g。

   if($something) {
            $r->proxyreq(1);
            $r->uri( ... other server .... );
            $r->args($args);

            $r->handler('proxy-server');
            return Apache2::Const::OK;
   }

有没有办法捕获这个其他服务器返回的http错误代码(例如500s)并实现回退逻辑?

1 个答案:

答案 0 :(得分:1)

$r->handler('proxy-server');表示Apache httpd服务器响应阶段采用mod_proxy(不是mod_perl)。

如果你捕获这个mod_proxy处理的HTTP返回码,那么你可以在响应阶段之后编写PerlLogHandlerPerlClenaupHandler模块来捕获它。

# PerlLogHandler Your::CatchStatusCode
package Your::CatchStatusCode;

use strict;
use warnings;

# If you use mod_perl1.
#use Apache;
#use Apache::Constants qw(DECLINED HTTP_INTERNAL_SERVER_ERROR);

# mod_perl2
use Apache2::RequestRec;
use Apache2::Const -compile => qw(DECLINED HTTP_INTERNAL_SERVER_ERROR);

sub handler {
    my $r = shift;
    my $code = $r->status();
    if ( $code == Apache2::Const::HTTP_INTERNAL_SERVER_ERROR ) {
        ...
    }
    # return untruth (not OK) for running other logging phase module (e.g. mod_log_custom)
    return Apache2::Const::DECLINED;
}
1;

或者添加您的书面脚本以插入PerlClenaupHandler

use Apache2::RequestUtil; # for push_handler
use Apache2::Const -compile => qw(OK HTTP_INTERNAL_SERVER_ERROR);
if($something) {
        $r->proxyreq(1);
        $r->uri( ... other server .... );
        $r->args($args);

        $r->handler('proxy-server');
        $r->push_handler( PerlCleanupHandler => sub {
            my $r = shift;
            # ... the same as above ...
        } );
        return Apache2::Const::OK;
}

但是PerlLogHandlerPerlCleanupHandler无法输出对HTTP客户端的响应(换句话说,您不能$r->print()),因为在请求阶段之后。