File Coverage

blib/lib/HTTP/Proxy/HeaderFilter/standard.pm
Criterion Covered Total %
statement 40 49 81.6
branch 11 20 55.0
condition 12 14 85.7
subroutine 7 7 100.0
pod 1 1 100.0
total 71 91 78.0


line stmt bran cond sub pod time code
1             package HTTP::Proxy::HeaderFilter::standard;
2             $HTTP::Proxy::HeaderFilter::standard::VERSION = '0.302';
3 66     66   270 use strict;
  66         91  
  66         1938  
4 66     66   264 use HTTP::Proxy;
  66         97  
  66         1537  
5 66     66   29571 use HTTP::Headers::Util qw( split_header_words );
  66         42983  
  66         3696  
6 66     66   22076 use HTTP::Proxy::HeaderFilter;
  66         293  
  66         1686  
7 66     66   311 use vars qw( @ISA );
  66         67  
  66         32640  
8             @ISA = qw( HTTP::Proxy::HeaderFilter );
9              
10             # known hop-by-hop headers
11             my @hopbyhop =
12             qw( Connection Keep-Alive Proxy-Authenticate Proxy-Authorization
13             TE Trailers Transfer-Encoding Upgrade Proxy-Connection Public );
14              
15             # standard proxy header filter (RFC 2616)
16             sub filter {
17 151     151 1 12812 my ( $self, $headers, $message ) = @_;
18              
19             # the Via: header
20 151   100     666 my $via = $message->protocol() || '';
21 151 100 100     2280 if ( $self->proxy->via and $via =~ s!HTTP/!! ) {
22 142         531 $via .= " " . $self->proxy->via;
23 142   66     558 $headers->header(
24             Via => join ', ',
25             $message->headers->header('Via') || (), $via
26             );
27             }
28              
29             # the X-Forwarded-For header
30             $headers->push_header(
31 151 100 100     12638 X_Forwarded_For => $self->proxy->client_socket->peerhost )
32             if $message->isa( 'HTTP::Request' ) && $self->proxy->x_forwarded_for;
33              
34             # make a list of hop-by-hop headers
35 151         6134 my %h2h = map { (lc) => 1 } @hopbyhop;
  1510         3824  
36 151         839 my $hop = HTTP::Headers->new();
37 151         1391 my $client = HTTP::Headers->new();
38 79         2503 $h2h{ lc $_->[0] } = 1
39 151         1085 for map { split_header_words($_) } $headers->header('Connection');
40              
41             # hop-by-hop headers are set aside
42             # as well as LWP::UserAgent Client-* headers
43             $headers->scan(
44             sub {
45 1200     1200   17383 my ( $k, $v ) = @_;
46 1200 100       2952 if ( $h2h{lc $k} ) {
47 164         423 $hop->push_header( $k => $v );
48 164         3049 $headers->remove_header($k);
49             }
50 1200 100       5646 if( $k =~ /^Client-/ ) {
51 143         409 $client->push_header( $k => $v );
52 143         4039 $headers->remove_header($k);
53             }
54             }
55 151         7279 );
56              
57             # set the hop-by-hop and client headers in the proxy
58             # only the end-to-end headers are left in the message
59 151         2002 $self->proxy->hop_headers($hop);
60 151         459 $self->proxy->client_headers($client);
61              
62             # handle Max-Forwards
63 151 50 66     1303 if ( $message->isa('HTTP::Request')
64             and defined $headers->header('Max-Forwards') ) {
65 0         0 my ( $max, $method ) =
66             ( $headers->header('Max-Forwards'), $message->method );
67 0 0       0 if ( $max == 0 ) {
    0          
68             # answer directly TRACE ou OPTIONS
69 0 0       0 if ( $method eq 'TRACE' ) {
    0          
70 0         0 my $response =
71             HTTP::Response->new( 200, 'OK',
72             HTTP::Headers->new( Content_Type => 'message/http'
73             , Content_Length => 0),
74             $message->as_string );
75 0         0 $self->proxy->response($response);
76             }
77             elsif ( $method eq 'OPTIONS' ) {
78 0         0 my $response = HTTP::Response->new(200);
79 0         0 $response->header( Allow => join ', ', @HTTP::Proxy::METHODS );
80 0         0 $self->proxy->response($response);
81             }
82             }
83             # The Max-Forwards header field MAY be ignored for all
84             # other methods defined by this specification (RFC 2616)
85             elsif ( $method =~ /^(?:TRACE|OPTIONS)/ ) {
86 0         0 $headers->header( 'Max-Forwards' => --$max );
87             }
88             }
89              
90             # no encoding accepted (gzip, compress, deflate)
91             # if we plan to do anything with the response body
92 151         455 $headers->remove_header( 'Accept-Encoding' )
93 151 100       2663 if @{ $self->proxy->{body}{response}{filters} };
94             }
95              
96             1;
97              
98             __END__