2012-06-04 26 views
0

我試圖使用HTTP :: Proxy來爲某些特定域的服務器403錯誤。我已經設法修改標題,但代理繼續提供原始頁面。HTTP :: Proxy:如何替換整個HTML頁面

這裏是我使用的代碼:

package Filters::Filter403; 

use strict; 
use warnings; 
use HTTP::Proxy::HeaderFilter::simple; 
use HTTP::Proxy::BodyFilter::simple; 

our $header = HTTP::Proxy::HeaderFilter::simple->new (
    sub { 
     $_[2]->code(403); 
     $_[2]->message ('Forbidden'); 
    } 
); 

our $body = HTTP::Proxy::BodyFilter::simple->new (
    sub {  
     $_[1] = \<<'HTML'; 
<!DOCTYPE html> 
<html><head><title>403 Forbidden</title><style type="text/css"> 
body { padding: 40pt; } 
body, h1, h2, p { color: #333; font-family: Arial, sans-serif; margin: 0; } 
div { width: 200px; background: #eee; padding: 2em; } 
</style></head><body><div><h1>403</h1><h2>Forbidden</h2></div></body></html> 
HTML 
    } 
); 

1; 

這是從那裏我打電話這兩個過濾器的主要腳本代碼,這樣你就可以有一個更美好的期待:

use HTTP::Proxy qw(:log); 
use Getopt::Long; 

use FindBin qw($Bin); 
use lib $Bin; 

use Filters; 
use HTTP::Proxy::BodyFilter::complete; 

my $port = 3128; 
my $fail_at; 
my $outputfile = '/var/log/cvmfs-test/webproxy.output'; 
my $errorfile = '/var/log/cvmfs-test/webproxy.error'; 

my $ret = GetOptions ("port=i" => \$port, 
         "fail=s" => \$fail_at); 

my @fail_at = split(/,/, $fail_at); 

# Opening file for log 
open (LOG, '>>', $outputfile); 

my $proxy = HTTP::Proxy->new; 
$proxy->port($port); 
$proxy->logfh(*LOG); 
$proxy->logmask(ALL); 

if ($fail_at[0] ne 'all') { 
    foreach my $url (@fail_at) { 
     $proxy->push_filter(
      host => $url, 
      response => HTTP::Proxy::BodyFilter::complete->new, 
      response => $Filters::Filter403::header, 
      response => $Filters::Filter403::body 
     ); 
    } 
} 
else { 
    $proxy->push_filter (
     response => HTTP::Proxy::BodyFilter::complete->new(), 
     response => $Filters::Filter403::header, 
     response => $Filters::Filter403::body 
    ); 
} 

my $pid = fork(); 

# Command for the forked process 
if (defined($pid) and $pid == 0) { 
    open (my $errfh, '>', $errorfile); 
    STDOUT->fdopen(\*$errfh, 'w') || die "Couldn't set STDERR to $errorfile: $!\n"; 
    $proxy->start; 
} 

# Command for the main script 
unless ($pid == 0) { 
    print "Proxy HTTP started on port $port with PID $pid.\n"; 
    print "You can read its output in $outputfile.\n"; 
} 

exit 0; 

你能幫我嗎? 我試過Daxim的解決方案,我也嘗試使用$ { $_[1] },因爲文檔似乎暗示,但它沒有奏效。

非常感謝。

+0

您可以檢查wget -S到代理以查看內容何時到期。如果提前10年,您需要進入該代理緩存。 – Andrew

回答

1

我已經找到了解決辦法。 問題是HTTP::Proxy::BodyFilter::complete->new之後的每個過濾器都會執行空數據。我發現加載一個沉重的頁面,我的代碼被添加了多次。

這裏是工作的過濾器:

our $body = HTTP::Proxy::BodyFilter::simple->new (
    sub { 
     my ($self, $dataref, $message, $protocol, $buffer) = @_; 
     unless (defined ($buffer)){ 
      my $html = 
        '<!DOCTYPE html>'. 
        '<html><head><title>403 Forbidden</title><style type="text/css">'. 
        'body { padding: 40pt; }'. 
        'body, h1, h2, p { color: #333; font-family: Arial, sans-serif; margin: 0; }'. 
        'div { width: 200px; background: #eee; padding: 2em; }'. 
        '</style></head><body><div><h1>403</h1><h2>Forbidden</h2></div></body></html>'; 

      $$dataref = $html; 
     } 
    } 
); 

這樣,除非$緩衝區民主基金,即接收到整個響應,當過濾器沒有做任何事情。

0

請參閱HTTP::Proxy::BodyFilter::complete

$proxy->push_filter(
    response => HTTP::Proxy::BodyFilter::complete->new, 
    response => HTTP::Proxy::BodyFilter::simple->new(sub { 
     $_[1] = \<<'HTML'; 
<!DOCTYPE html> 
<html><head><title>403 Forbidden</title><style type="text/css"> 
body { padding: 40pt; } 
body, h1, h2, p { color: #333; font-family: Arial, sans-serif; margin: 0; } 
div { width: 200px; background: #eee; padding: 2em; } 
</style></head><body><div><h1>403</h1><h2>Forbidden</h2></div></body></html> 
HTML 
    }), 
); 
+0

對不起,但這不適合我。我要用主腳本的代碼更新帖子,所以你也可以在那裏看看。 – Zagorax

+0

我找到了一個解決方案。謝謝你,因爲我不會沒有你對BodyFilter :: complete的建議。 – Zagorax

+0

我看到文檔可以使用一些改進;我會爲BooK提供一個補丁。我很高興你知道你想要什麼,可以將自己的答案標記爲可接受的,因爲它最符合問題。 – daxim