File Coverage

blib/lib/Net/ICAP/Response.pm
Criterion Covered Total %
statement 94 102 92.1
branch 19 32 59.3
condition 4 12 33.3
subroutine 15 15 100.0
pod 5 5 100.0
total 137 166 82.5


line stmt bran cond sub pod time code
1             # Net::ICAP::Response -- Response object for ICAP
2             #
3             # (c) 2012, Arthur Corliss
4             #
5             # $Revision: 0.04 $
6             #
7             # This software is licensed under the same terms as Perl, itself.
8             # Please see http://dev.perl.org/licenses/ for more information.
9             #
10             #####################################################################
11              
12             #####################################################################
13             #
14             # Environment definitions
15             #
16             #####################################################################
17              
18             package Net::ICAP::Response;
19              
20 2     2   13862 use 5.008003;
  2         6  
21              
22 2     2   10 use strict;
  2         4  
  2         34  
23 2     2   29 use warnings;
  2         4  
  2         57  
24 2     2   9 use vars qw($VERSION @ISA @_properties @_methods);
  2         4  
  2         112  
25 2     2   500 use Class::EHierarchy qw(:all);
  2         5948  
  2         280  
26 2     2   322 use Net::ICAP::Common qw(:std :debug :resp);
  2         4  
  2         319  
27 2     2   364 use Net::ICAP::Message;
  2         5  
  2         68  
28 2     2   11 use Paranoid::Debug;
  2         4  
  2         1291  
29              
30             ($VERSION) = ( q$Revision: 0.04 $ =~ /(\d+(?:\.(\d+))+)/s );
31              
32             @ISA = qw(Net::ICAP::Message Class::EHierarchy);
33              
34             @_properties = (
35             [ CEH_RESTR | CEH_SCALAR, '_status' ],
36             [ CEH_RESTR | CEH_HASH,
37             '_status_text',
38             { 100 => 'Continue after ICAP Preview',
39             200 => 'OK',
40             204 => 'No Modifications Needed',
41             400 => 'Bad Request',
42             401 => 'Unauthorized',
43             403 => 'Forbidden',
44             404 => 'ICAP Service Not Found',
45             405 => 'Method Not Allowed For Service',
46             407 => 'Proxy Authentication Required',
47             408 => 'Request Time-out',
48             411 => 'Length Required',
49             414 => 'Request-URI Too Large',
50             418 => 'Bad Composition',
51             500 => 'Internal Server Error',
52             501 => 'Method Not Implemented',
53             502 => 'Bad Gateway',
54             503 => 'Service Overloaded',
55             504 => 'Gateway Time-out',
56             505 => 'ICAP Version Not Supported',
57             }
58             ],
59             );
60              
61             #####################################################################
62             #
63             # Module code follows
64             #
65             #####################################################################
66              
67             sub _initialize ($;@) {
68              
69 13     13   15030 my $obj = shift;
70 13         32 my %args = @_;
71 13         21 my $rv = 1;
72              
73 13         45 pdebug( 'entering w/%s and %s', ICAPDEBUG1, $obj, keys %args );
74 13         555 pIn();
75              
76             # Set internal state if args were passed
77 13 100       122 $rv = $obj->status( $args{status} ) if exists $args{status};
78              
79 13         33 pOut();
80 13         102 pdebug( 'leaving w/rv: %s', ICAPDEBUG1, $rv );
81              
82 13         398 return $rv;
83             }
84              
85             sub _validHeaders ($) {
86              
87             # Purpose: Returns a list of valid ICAP headers
88             # Returns: Array
89             # Usage: @val = $obj->_validHeaders;
90              
91 47     47   75 my $obj = shift;
92              
93             return (
94 47         137 qw(Allow Methods Service Server ISTag
95             Opt-body-type Max-Connections Options-TTL Service-ID
96             Preview Transfer-Preview Transfer-Ignore
97             Transfer-Complete), $obj->SUPER::_validHeaders
98             );
99             }
100              
101             sub status ($;$) {
102              
103             # Purpose: Gets/sets response status code
104             # Returns: Boolean/string
105             # Usage: $rv = $obj->status($code);
106             # Usage: $code = $obj->status;
107              
108 20     20 1 36 my $obj = shift;
109 20         30 my $status = shift;
110 20         29 my $rv;
111              
112 20         58 pdebug( 'entering w/%s', ICAPDEBUG1, $status );
113 20         655 pIn();
114              
115 20 100       164 if ( defined $status ) {
116              
117             # Write mode
118 7 50       25 if ( $obj->exists( '_status_text', $status ) ) {
119 7         322 $rv = $obj->set( '_status', $status );
120             } else {
121 0         0 $obj->error("invalid status code passed: $status");
122 0         0 $rv = 0;
123             }
124              
125             } else {
126              
127             # Read mode
128 13         36 $rv = $obj->get('_status');
129             }
130              
131 20         1114 pOut();
132 20         158 pdebug( 'leaving w/rv: %s', ICAPDEBUG1, $rv );
133              
134 20         682 return $rv;
135             }
136              
137             sub statusText ($;$) {
138              
139             # Purpose: Returns associated status description string
140             # Returns: String
141             # Usage: $text = $obj->statusText($code);
142             # Usage: $text = $obj->statusText;
143              
144 13     13 1 23 my $obj = shift;
145 13         22 my $status = shift;
146 13         16 my $rv;
147              
148 13         39 pdebug( 'entering w/%s', ICAPDEBUG1, $status );
149 13         429 pIn();
150              
151 13 50       127 $status = $obj->get('_status') unless defined $status;
152 13 50       622 if ( defined $status ) {
153 13 50       35 ($rv) = $obj->subset( '_status_text', $status )
154             if $obj->exists( '_status_text', $status );
155             }
156              
157 13 50       1067 $obj->error("invalid or undefined status")
158             unless defined $rv;
159              
160 13         37 pOut();
161 13         99 pdebug( 'leaving w/rv: %s', ICAPDEBUG1, $rv );
162              
163 13         430 return $rv;
164             }
165              
166             sub sanityCheck ($) {
167              
168             # Purpose: Checks for required information
169             # Returns: Boolean
170             # Usage: $rv = $obj->sanityCheck;
171              
172 13     13 1 23 my $obj = shift;
173 13         19 my $rv = 1;
174 13         21 my $t;
175              
176 13         33 $t = $obj->get('_status');
177 13 50 33     687 unless ( defined $t and length $t ) {
178 0         0 $obj->error('missing a valid request method');
179 0         0 $rv = 0;
180             }
181              
182 13         34 $t = $obj->get('_version');
183 13 50 33     651 unless ( defined $t and length $t ) {
184 0         0 $obj->error('missing a valid ICAP protocol version');
185 0         0 $rv = 0;
186             }
187              
188 13         36 $t = $obj->header('ISTag');
189 13 50 33     61 unless ( defined $t and length $t ) {
190 0         0 $obj->error('missing mandatory ISTag header');
191 0         0 $rv = 0;
192             }
193              
194 13 50       33 $obj->error('failed sanity check') unless $rv;
195 13 50       27 $obj->error('failed sanity check') unless $rv;
196              
197 13         66 return $rv;
198             }
199              
200             sub parse ($$) {
201              
202             # Purpose: Parses message from passed input
203             # Returns: Boolean
204             # Usage: $rv = $obj->parse($input);
205              
206 12     12 1 2062 my $obj = shift;
207 12         21 my $input = shift;
208 12         17 my $rv = 0;
209 12         22 my ( $line, $s, $v );
210              
211 12         35 pdebug( 'entering w/%s, %s', ICAPDEBUG1, $obj, $input );
212 12         464 pIn();
213              
214 12 50       106 if ( defined $input ) {
215              
216             # Purge internal state
217 12         42 $obj->set( '_status', undef );
218              
219             # Parse
220 12         832 $rv = $obj->SUPER::parse($input);
221              
222 12 100       33 if ($rv) {
223              
224             # Extract response specific fields
225 6         18 $line = $obj->get('_start');
226 6         339 ( $v, $s ) = ( $line =~ /^(\S+)\s+(\d+)/s );
227              
228             # Save the extracted information
229 6   33     19 $rv = $obj->status($s) && $obj->version($v);
230              
231             # Final sanity check
232 6 50       24 $rv = $obj->sanityCheck if $rv;
233             }
234             }
235              
236 12         30 pOut();
237 12         92 pdebug( 'leaving w/rv: %s', ICAPDEBUG1, $rv );
238              
239 12         391 return $rv;
240             }
241              
242             sub generate ($$) {
243              
244             # Purpose: Generates an ICAP response
245             # Returns: String
246             # Usage: $response = $obj->generate($ref);
247              
248 7     7 1 600 my $obj = shift;
249 7         10 my $out = shift;
250 7         12 my $rv;
251              
252 7 50       14 if ( $obj->sanityCheck ) {
253              
254             # Build start line
255 7         17 $obj->set( '_start', join ' ', ICAP_VERSION, $obj->status,
256             $obj->statusText );
257              
258             # Generate ICAP message
259 7         489 $rv = $obj->SUPER::generate($out);
260             }
261              
262 7         34 return $rv;
263             }
264              
265             1;
266              
267             __END__