File Coverage

blib/lib/Squid/Guard/Request.pm
Criterion Covered Total %
statement 75 80 93.7
branch 27 34 79.4
condition 6 10 60.0
subroutine 14 14 100.0
pod 1 1 100.0
total 123 139 88.4


line stmt bran cond sub pod time code
1             package Squid::Guard::Request;
2              
3 1     1   69968 use 5.008;
  1         4  
  1         38  
4 1     1   5 use strict;
  1         2  
  1         34  
5 1     1   5 use warnings;
  1         6  
  1         49  
6 1     1   5 use Carp;
  1         2  
  1         234  
7              
8             our @ISA = qw();
9              
10             our $VERSION = '0.15';
11              
12              
13             =head1 NAME
14              
15             Squid::Guard::Request - A request to Squid::Guard
16              
17             =head1 SYNOPSYS
18              
19             use Squid::Guard::Request;
20              
21             my $req = Squid::Guard->new($str);
22              
23             =head1 DESCRIPTION
24              
25             Initializes a new Request object based on the string coming
26             from Squid to the redirector.
27              
28              
29             =head2 Squid::Guard::Request->new( $str )
30              
31             API call to create a new object. The $str parameter should be in the format used by Squid to pass a request to the redirection program: C.
32              
33             =cut
34              
35             # TODO: maybe resolve protocols via getservent()?
36             my %defaultports = (
37             'http' => 80,
38             'https' => 443,
39             'http-mgmt' => 280,
40             'gss-http' => 488,
41             'multiling-http' => 777,
42             'ftp' => 21,
43             'gopher' => 70,
44             'wais' => 210,
45             'filemaker' => 591,
46             );
47              
48             my %defaultschemes = reverse %defaultports;
49              
50             sub new {
51 4     4 1 1031 my $class = shift;
52 4         10 my $str = shift;
53              
54 4         11 my $self = {};
55              
56 4         15 $self->{str} = $str;
57 4         12 $self->{verbose} = 0;
58 4         9 $self->{debug} = 0;
59              
60 4         10 $self->{debug} = 0;
61              
62             {
63 1     1   6 no strict qw(vars refs);
  1         1  
  1         504  
  4         5  
64 4         17 local ($url, $foo, $ident, $method, $_kvpairs, $addr, $fqdn, $_scheme, $authority, $path, $query, $fragment, $host, $_port);
65 4         24 ($url, $foo, $ident, $method, $_kvpairs) = split(/\s+/, $str, 5);
66              
67 4         12 $ident =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/eg;
  0         0  
68              
69 4         14 ($addr, $fqdn) = split(/\//, $foo);
70              
71 4         12 foreach ( qw( ident _kvpairs fqdn ) ) {
72 12 100       13 ${$_} = undef if ${$_} eq '-';
  7         20  
  12         49  
73             }
74              
75             # ($_scheme, $authority, $path, $query, $fragment) = $url =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|; # taken from URI man page
76 4         39 ($_scheme, $authority, $path, $query, $fragment) = $url =~ m|(?:([^:/?#]+)://)?([^/?#]*)([^?#]*)(?:\?([^#]*))?(?:#(.*))?|; # Slightly modified for our usage: authority is needed, // isn't
77 4         17 ($host, $_port) = split( /:/, $authority );
78              
79 4         12 foreach ( qw( url ident method _kvpairs addr fqdn _scheme authority path query fragment host _port ) ) {
80 52         63 $self->{$_} = ${$_};
  52         412  
81             }
82             }
83              
84 4         15 bless($self, $class);
85 4         23 return $self;
86             }
87              
88              
89             =head2 $req->url()
90              
91             Get request url
92              
93             =cut
94              
95              
96             =head2 $req->addr()
97              
98             Get request address
99              
100             =cut
101              
102              
103             =head2 $req->fqdn()
104              
105             Get request fqdn
106              
107             =cut
108              
109              
110             =head2 $req->ident()
111              
112             Get request ident
113              
114             =cut
115              
116              
117             =head2 $req->method()
118              
119             Get request method
120              
121             =cut
122              
123              
124             =head2 $req->kvpairs()
125              
126             When called without arguments, returns a hash consisting of the extra key/value pairs found in the request. If an argument is supplied, it is taken as a key and the corresponding value (or undef) is returned. You can access the string of key/value pairs exactly as passed in the request by using _kvpairs instead
127              
128             =cut
129              
130              
131             =head2 $req->_scheme() $req->scheme() $req->authority() $req->host() $req->_port() $req->port() $req->path() $req->query() $req->path_query() $req->authority_path_query() $req->fragment()
132              
133             Get url components. These methods are inspired form the URI module.
134              
135             If a port is not specified explicitly in the request, then $req->port returns the scheme's default port.
136             If you don't want the default port substituted, then you can use the $uri->_port method instead. (behaviour consistent with URI module)
137             Similarly, $req->_scheme reports the scheme explicitly specified in the requested url, or undef if not present (this is cthe case of CONNECT requests).
138             When $req->_scheme is undef and $uri->_port is defined, $req->scheme is set to the port's default scheme.
139              
140             =cut
141              
142              
143             sub AUTOLOAD {
144 16     16   1010 my ($self) = @_; # don't use shift, otherwise the call to goto &$AUTOLOAD will suffer :(
145 16 50       48 croak "$self not an object" unless ref($self);
146 16         23 our $AUTOLOAD;
147 1     1   6 no strict 'refs';
  1         2  
  1         1274  
148 16 50       112 if ($AUTOLOAD =~ /.*::(.*)/) {
149 16         38 my $element = $1;
150 16 50       51 return if $element eq "DESTROY";
151 16 100       33 if( grep { $element eq $_ } qw( url ident method _kvpairs addr fqdn _scheme authority host _port path query fragment ) ) {
  208 100       428  
    100          
    100          
    100          
    50          
152             *$AUTOLOAD = sub {
153 73     73   1693 my $self = shift;
154 73         468 $self->{$element};
155 11         77 };
156             } elsif( $element eq 'path_query' ) {
157             *$AUTOLOAD = sub {
158 6     6   13 my $self = shift;
159 6 100 100     21 ( $self->path || '' ) . ( $self->query ? ( "?" . $self->query ) : '' );
160 1         10 };
161             } elsif( $element eq 'authority_path_query' ) {
162             *$AUTOLOAD = sub {
163 3     3   8 my $self = shift;
164 3         13 $self->authority . $self->path_query;
165 1         10 };
166             } elsif( $element eq 'port' ) {
167             *$AUTOLOAD = sub {
168 4     4   11 my $self = shift;
169 4 100 33     12 if( $self->_port ) {
    50          
170 2         9 return $self->_port;
171             } elsif( $self->_scheme && defined( $defaultports{$self->_scheme} ) ) {
172 2         102 return $defaultports{$self->_scheme};
173             } else {
174 0         0 return undef;
175             }
176 1         33 };
177             } elsif( $element eq 'scheme' ) {
178             *$AUTOLOAD = sub {
179 4     4   9 my $self = shift;
180 4 100 33     17 if( $self->_scheme ) {
    50          
181 3         9 return $self->_scheme;
182             } elsif( $self->_port && defined( $defaultschemes{$self->_port} ) ) {
183 1         5 return $defaultschemes{$self->_port};
184             } else {
185 0         0 return undef;
186             }
187             }
188 1         9 } elsif( $element eq 'kvpairs' ) {
189             *$AUTOLOAD = sub {
190 3     3   7 my $self = shift;
191 3 100       18 return undef unless $self->{'_kvpairs'};
192 2   100     13 $self->{_kvh} ||= { map { split(/=/, $_) } split(/\s+/, $self->{'_kvpairs'}) };
  2         11  
193              
194 2 50       16 @_ ? $self->{_kvh}->{$_[0]} : %{$self->{_kvh}};
  0         0  
195 1         11 };
196             } else {
197 0         0 croak "invalid method $element";
198             }
199 16         68 goto &$AUTOLOAD;
200             }
201             }
202              
203              
204             1;