File Coverage

blib/lib/HTTP/Response.pm
Criterion Covered Total %
statement 174 175 99.4
branch 80 84 95.2
condition 51 57 89.4
subroutine 28 28 100.0
pod 24 24 100.0
total 357 368 97.0


line stmt bran cond sub pod time code
1             package HTTP::Response;
2              
3 11     11   141736 use strict;
  11         44  
  11         333  
4 11     11   55 use warnings;
  11         22  
  11         479  
5              
6             our $VERSION = '6.43';
7              
8 11     11   2304 use parent 'HTTP::Message';
  11         1524  
  11         62  
9              
10 11     11   5628 use HTTP::Status ();
  11         32  
  11         20434  
11              
12              
13             sub new
14             {
15 16     16 1 6244 my($class, $rc, $msg, $header, $content) = @_;
16 16         147 my $self = $class->SUPER::new($header, $content);
17 16         84 $self->code($rc);
18 16         62 $self->message($msg);
19 16         74 $self;
20             }
21              
22              
23             sub parse
24             {
25 5     5 1 1327 my($class, $str) = @_;
26 5 100 100     232 Carp::carp('Undefined argument to parse()') if $^W && ! defined $str;
27 5         16 my $status_line;
28 5 100 66     38 if (defined $str && $str =~ s/^(.*)\n//) {
29 3         11 $status_line = $1;
30             }
31             else {
32 2         4 $status_line = $str;
33 2         5 $str = "";
34             }
35              
36 5 100       20 $status_line =~ s/\r\z// if defined $status_line;
37              
38 5         27 my $self = $class->SUPER::parse($str);
39 5 100       19 if (defined $status_line) {
40 3         9 my($protocol, $code, $message);
41 3 100       13 if ($status_line =~ /^\d{3} /) {
42             # Looks like a response created by HTTP::Response->new
43 1         5 ($code, $message) = split(' ', $status_line, 2);
44             } else {
45 2         9 ($protocol, $code, $message) = split(' ', $status_line, 3);
46             }
47 3 100       19 $self->protocol($protocol) if $protocol;
48 3 50       19 $self->code($code) if defined($code);
49 3 50       17 $self->message($message) if defined($message);
50             }
51 5         19 $self;
52             }
53              
54              
55             sub clone
56             {
57 2     2 1 9 my $self = shift;
58 2         12 my $clone = bless $self->SUPER::clone, ref($self);
59 2         7 $clone->code($self->code);
60 2         5 $clone->message($self->message);
61 2 100       5 $clone->request($self->request->clone) if $self->request;
62             # we don't clone previous
63 2         6 $clone;
64             }
65              
66              
67 29     29 1 1859 sub code { shift->_elem('_rc', @_); }
68 27     27 1 90 sub message { shift->_elem('_msg', @_); }
69 12     12 1 29 sub previous { shift->_elem('_previous',@_); }
70 39     39 1 1384 sub request { shift->_elem('_request', @_); }
71              
72              
73             sub status_line
74             {
75 11     11 1 15 my $self = shift;
76 11   100     39 my $code = $self->{'_rc'} || "000";
77 11   100     59 my $mess = $self->{'_msg'} || HTTP::Status::status_message($code) || "Unknown code";
78 11         38 return "$code $mess";
79             }
80              
81              
82             sub base
83             {
84 7     7 1 298 my $self = shift;
85 7         22 my $base = (
86             $self->header('Content-Base'), # used to be HTTP/1.1
87             $self->header('Base'), # HTTP/1.0
88             )[0];
89 7 100 100     90 if ($base && $base =~ /^$URI::scheme_re:/o) {
90             # already absolute
91 1         6 return $HTTP::URI_CLASS->new($base);
92             }
93              
94 6         19 my $req = $self->request;
95 6 100       16 if ($req) {
96             # if $base is undef here, the return value is effectively
97             # just a copy of $self->request->uri.
98 5         16 return $HTTP::URI_CLASS->new_abs($base, $req->uri);
99             }
100              
101             # can't find an absolute base
102 1         5 return undef;
103             }
104              
105              
106             sub redirects {
107 4     4 1 8 my $self = shift;
108 4         6 my @r;
109 4         7 my $r = $self;
110 4         11 while (my $p = $r->previous) {
111 5         9 push(@r, $p);
112 5         12 $r = $p;
113             }
114 4 100       16 return @r unless wantarray;
115 1         4 return reverse @r;
116             }
117              
118              
119             sub filename
120             {
121 10     10 1 19 my $self = shift;
122 10         18 my $file;
123              
124 10         34 my $cd = $self->header('Content-Disposition');
125 10 100       36 if ($cd) {
126 7         875 require HTTP::Headers::Util;
127 7 50       25 if (my @cd = HTTP::Headers::Util::split_header_words($cd)) {
128 7         12 my ($disposition, undef, %cd_param) = @{$cd[-1]};
  7         23  
129 7         16 $file = $cd_param{filename};
130              
131             # RFC 2047 encoded?
132 7 100 100     46 if ($file && $file =~ /^=\?(.+?)\?(.+?)\?(.+)\?=$/) {
133 4         10 my $charset = $1;
134 4         11 my $encoding = uc($2);
135 4         9 my $encfile = $3;
136              
137 4 100 100     19 if ($encoding eq 'Q' || $encoding eq 'B') {
138 3         15 local($SIG{__DIE__});
139 3         6 eval {
140 3 100       7 if ($encoding eq 'Q') {
141 1         4 $encfile =~ s/_/ /g;
142 1         460 require MIME::QuotedPrint;
143 1         269 $encfile = MIME::QuotedPrint::decode($encfile);
144             }
145             else { # $encoding eq 'B'
146 2         496 require MIME::Base64;
147 2         788 $encfile = MIME::Base64::decode($encfile);
148             }
149              
150 3         871 require Encode;
151 3         15567 require Encode::Locale;
152 3         3380 Encode::from_to($encfile, $charset, "locale_fs");
153             };
154              
155 3 100       2362 $file = $encfile unless $@;
156             }
157             }
158             }
159             }
160              
161 10 100 100     46 unless (defined($file) && length($file)) {
162 5         8 my $uri;
163 5 100       16 if (my $cl = $self->header('Content-Location')) {
    100          
164 1         10 $uri = URI->new($cl);
165             }
166             elsif (my $request = $self->request) {
167 3         12 $uri = $request->uri;
168             }
169              
170 5 100       244 if ($uri) {
171 2         27 $file = ($uri->path_segments)[-1];
172             }
173             }
174              
175 10 100       128 if ($file) {
176 7         23 $file =~ s,.*[\\/],,; # basename
177             }
178              
179 10 50 66     39 if ($file && !length($file)) {
180 0         0 $file = undef;
181             }
182              
183 10         46 $file;
184             }
185              
186              
187             sub as_string
188             {
189 7     7 1 19 my $self = shift;
190 7         18 my($eol) = @_;
191 7 100       20 $eol = "\n" unless defined $eol;
192              
193 7         18 my $status_line = $self->status_line;
194 7         25 my $proto = $self->protocol;
195 7 100       19 $status_line = "$proto $status_line" if $proto;
196              
197 7         29 return join($eol, $status_line, $self->SUPER::as_string(@_));
198             }
199              
200              
201             sub dump
202             {
203 2     2 1 4 my $self = shift;
204              
205 2         6 my $status_line = $self->status_line;
206 2         14 my $proto = $self->protocol;
207 2 100       10 $status_line = "$proto $status_line" if $proto;
208              
209 2         12 return $self->SUPER::dump(
210             preheader => $status_line,
211             @_,
212             );
213             }
214              
215              
216 1     1 1 6 sub is_info { HTTP::Status::is_info (shift->{'_rc'}); }
217 4     4 1 303 sub is_success { HTTP::Status::is_success (shift->{'_rc'}); }
218 1     1 1 5 sub is_redirect { HTTP::Status::is_redirect (shift->{'_rc'}); }
219 1     1 1 6 sub is_error { HTTP::Status::is_error (shift->{'_rc'}); }
220 1     1 1 6 sub is_client_error { HTTP::Status::is_client_error (shift->{'_rc'}); }
221 1     1 1 4 sub is_server_error { HTTP::Status::is_server_error (shift->{'_rc'}); }
222              
223              
224             sub error_as_HTML
225             {
226 1     1 1 3 my $self = shift;
227 1         2 my $title = 'An Error Occurred';
228 1         3 my $body = $self->status_line;
229 1         3 $body =~ s/&/&/g;
230 1         2 $body =~ s/
231 1         5 return <
232            
233             $title
234            
235            

$title

236            

$body

237            
238            
239             EOM
240             }
241              
242              
243             sub current_age
244             {
245 13     13 1 35 my $self = shift;
246 13         20 my $time = shift;
247              
248             # Implementation of RFC 2616 section 13.2.3
249             # (age calculations)
250 13         33 my $response_time = $self->client_date;
251 13         570 my $date = $self->date;
252              
253 13         451 my $age = 0;
254 13 100 100     46 if ($response_time && $date) {
255 9         13 $age = $response_time - $date; # apparent_age
256 9 100       20 $age = 0 if $age < 0;
257             }
258              
259 13         37 my $age_v = $self->header('Age');
260 13 100 100     52 if ($age_v && $age_v > $age) {
261 4         9 $age = $age_v; # corrected_received_age
262             }
263              
264 13 100       27 if ($response_time) {
265 10         26 my $request = $self->request;
266 10 100       22 if ($request) {
267 8         21 my $request_time = $request->date;
268 8 100 100     327 if ($request_time && $request_time < $response_time) {
269             # Add response_delay to age to get 'corrected_initial_age'
270 6         12 $age += $response_time - $request_time;
271             }
272             }
273 10   66     32 $age += ($time || time) - $response_time;
274             }
275 13         66 return $age;
276             }
277              
278              
279             sub freshness_lifetime
280             {
281 24     24 1 753 my($self, %opt) = @_;
282              
283             # First look for the Cache-Control: max-age=n header
284 24         69 for my $cc ($self->header('Cache-Control')) {
285 6         19 for my $cc_dir (split(/\s*,\s*/, $cc)) {
286 6 100       35 return $1 if $cc_dir =~ /^max-age\s*=\s*(\d+)/i;
287             }
288             }
289              
290             # Next possibility is to look at the "Expires" header
291 21   66     57 my $date = $self->date || $self->client_date || $opt{time} || time;
292 21 100       600 if (my $expires = $self->expires) {
293 1         46 return $expires - $date;
294             }
295              
296             # Must apply heuristic expiration
297 20 100 100     163 return undef if exists $opt{heuristic_expiry} && !$opt{heuristic_expiry};
298              
299             # Default heuristic expiration parameters
300 16   100     60 $opt{h_min} ||= 60;
301 16   100     61 $opt{h_max} ||= 24 * 3600;
302 16   100     83 $opt{h_lastmod_fraction} ||= 0.10; # 10% since last-mod suggested by RFC2616
303 16   100     53 $opt{h_default} ||= 3600;
304              
305             # Should give a warning if more than 24 hours according to
306             # RFC 2616 section 13.2.4. Here we just make this the default
307             # maximum value.
308              
309 16 100       47 if (my $last_modified = $self->last_modified) {
310 12         604 my $h_exp = ($date - $last_modified) * $opt{h_lastmod_fraction};
311 12 100       36 return $opt{h_min} if $h_exp < $opt{h_min};
312 10 100       44 return $opt{h_max} if $h_exp > $opt{h_max};
313 2         11 return $h_exp;
314             }
315              
316             # default when all else fails
317 4 100       41 return $opt{h_min} if $opt{h_min} > $opt{h_default};
318 3         14 return $opt{h_default};
319             }
320              
321              
322             sub is_fresh
323             {
324 3     3 1 301 my($self, %opt) = @_;
325 3   66     16 $opt{time} ||= time;
326 3         11 my $f = $self->freshness_lifetime(%opt);
327 3 100       24 return undef unless defined($f);
328 2         11 return $f > $self->current_age($opt{time});
329             }
330              
331              
332             sub fresh_until
333             {
334 5     5 1 1413 my($self, %opt) = @_;
335 5   66     26 $opt{time} ||= time;
336 5         17 my $f = $self->freshness_lifetime(%opt);
337 5 100       19 return undef unless defined($f);
338 4         10 return $f - $self->current_age($opt{time}) + $opt{time};
339             }
340              
341             1;
342              
343             =pod
344              
345             =encoding UTF-8
346              
347             =head1 NAME
348              
349             HTTP::Response - HTTP style response message
350              
351             =head1 VERSION
352              
353             version 6.43
354              
355             =head1 SYNOPSIS
356              
357             Response objects are returned by the request() method of the C:
358              
359             # ...
360             $response = $ua->request($request);
361             if ($response->is_success) {
362             print $response->decoded_content;
363             }
364             else {
365             print STDERR $response->status_line, "\n";
366             }
367              
368             =head1 DESCRIPTION
369              
370             The C class encapsulates HTTP style responses. A
371             response consists of a response line, some headers, and a content
372             body. Note that the LWP library uses HTTP style responses even for
373             non-HTTP protocol schemes. Instances of this class are usually
374             created and returned by the request() method of an C
375             object.
376              
377             C is a subclass of C and therefore
378             inherits its methods. The following additional methods are available:
379              
380             =over 4
381              
382             =item $r = HTTP::Response->new( $code )
383              
384             =item $r = HTTP::Response->new( $code, $msg )
385              
386             =item $r = HTTP::Response->new( $code, $msg, $header )
387              
388             =item $r = HTTP::Response->new( $code, $msg, $header, $content )
389              
390             Constructs a new C object describing a response with
391             response code $code and optional message $msg. The optional $header
392             argument should be a reference to an C object or a
393             plain array reference of key/value pairs. The optional $content
394             argument should be a string of bytes. The meanings of these arguments are
395             described below.
396              
397             =item $r = HTTP::Response->parse( $str )
398              
399             This constructs a new response object by parsing the given string.
400              
401             =item $r->code
402              
403             =item $r->code( $code )
404              
405             This is used to get/set the code attribute. The code is a 3 digit
406             number that encode the overall outcome of an HTTP response. The
407             C module provide constants that provide mnemonic names
408             for the code attribute.
409              
410             =item $r->message
411              
412             =item $r->message( $message )
413              
414             This is used to get/set the message attribute. The message is a short
415             human readable single line string that explains the response code.
416              
417             =item $r->header( $field )
418              
419             =item $r->header( $field => $value )
420              
421             This is used to get/set header values and it is inherited from
422             C via C. See L for
423             details and other similar methods that can be used to access the
424             headers.
425              
426             =item $r->content
427              
428             =item $r->content( $bytes )
429              
430             This is used to get/set the raw content and it is inherited from the
431             C base class. See L for details and
432             other methods that can be used to access the content.
433              
434             =item $r->decoded_content( %options )
435              
436             This will return the content after any C and
437             charsets have been decoded. See L for details.
438              
439             =item $r->request
440              
441             =item $r->request( $request )
442              
443             This is used to get/set the request attribute. The request attribute
444             is a reference to the request that caused this response. It does
445             not have to be the same request passed to the $ua->request() method,
446             because there might have been redirects and authorization retries in
447             between.
448              
449             =item $r->previous
450              
451             =item $r->previous( $response )
452              
453             This is used to get/set the previous attribute. The previous
454             attribute is used to link together chains of responses. You get
455             chains of responses if the first response is redirect or unauthorized.
456             The value is C if this is the first response in a chain.
457              
458             Note that the method $r->redirects is provided as a more convenient
459             way to access the response chain.
460              
461             =item $r->status_line
462              
463             Returns the string "Ecode> Emessage>". If the message attribute
464             is not set then the official name of Ecode> (see L)
465             is substituted.
466              
467             =item $r->base
468              
469             Returns the base URI for this response. The return value will be a
470             reference to a URI object.
471              
472             The base URI is obtained from one the following sources (in priority
473             order):
474              
475             =over 4
476              
477             =item 1.
478              
479             Embedded in the document content, for instance
480             in HTML documents.
481              
482             =item 2.
483              
484             A "Content-Base:" header in the response.
485              
486             For backwards compatibility with older HTTP implementations we will
487             also look for the "Base:" header.
488              
489             =item 3.
490              
491             The URI used to request this response. This might not be the original
492             URI that was passed to $ua->request() method, because we might have
493             received some redirect responses first.
494              
495             =back
496              
497             If none of these sources provide an absolute URI, undef is returned.
498              
499             B: previous versions of HTTP::Response would also consider
500             a "Content-Location:" header,
501             as L said it should be.
502             But this was never widely implemented by browsers,
503             and now L
504             says it should no longer be considered.
505              
506             When the LWP protocol modules produce the HTTP::Response object, then any base
507             URI embedded in the document (step 1) will already have initialized the
508             "Content-Base:" header. (See L). This means that
509             this method only performs the last 2 steps (the content is not always available
510             either).
511              
512             =item $r->filename
513              
514             Returns a filename for this response. Note that doing sanity checks
515             on the returned filename (eg. removing characters that cannot be used
516             on the target filesystem where the filename would be used, and
517             laundering it for security purposes) are the caller's responsibility;
518             the only related thing done by this method is that it makes a simple
519             attempt to return a plain filename with no preceding path segments.
520              
521             The filename is obtained from one the following sources (in priority
522             order):
523              
524             =over 4
525              
526             =item 1.
527              
528             A "Content-Disposition:" header in the response. Proper decoding of
529             RFC 2047 encoded filenames requires the C (for "Q"
530             encoding), C (for "B" encoding), and C modules.
531              
532             =item 2.
533              
534             A "Content-Location:" header in the response.
535              
536             =item 3.
537              
538             The URI used to request this response. This might not be the original
539             URI that was passed to $ua->request() method, because we might have
540             received some redirect responses first.
541              
542             =back
543              
544             If a filename cannot be derived from any of these sources, undef is
545             returned.
546              
547             =item $r->as_string
548              
549             =item $r->as_string( $eol )
550              
551             Returns a textual representation of the response.
552              
553             =item $r->is_info
554              
555             =item $r->is_success
556              
557             =item $r->is_redirect
558              
559             =item $r->is_error
560              
561             =item $r->is_client_error
562              
563             =item $r->is_server_error
564              
565             These methods indicate if the response was informational, successful, a
566             redirection, or an error. See L for the meaning of these.
567              
568             =item $r->error_as_HTML
569              
570             Returns a string containing a complete HTML document indicating what
571             error occurred. This method should only be called when $r->is_error
572             is TRUE.
573              
574             =item $r->redirects
575              
576             Returns the list of redirect responses that lead up to this response
577             by following the $r->previous chain. The list order is oldest first.
578              
579             In scalar context return the number of redirect responses leading up
580             to this one.
581              
582             =item $r->current_age
583              
584             Calculates the "current age" of the response as specified by RFC 2616
585             section 13.2.3. The age of a response is the time since it was sent
586             by the origin server. The returned value is a number representing the
587             age in seconds.
588              
589             =item $r->freshness_lifetime( %opt )
590              
591             Calculates the "freshness lifetime" of the response as specified by
592             RFC 2616 section 13.2.4. The "freshness lifetime" is the length of
593             time between the generation of a response and its expiration time.
594             The returned value is the number of seconds until expiry.
595              
596             If the response does not contain an "Expires" or a "Cache-Control"
597             header, then this function will apply some simple heuristic based on
598             the "Last-Modified" header to determine a suitable lifetime. The
599             following options might be passed to control the heuristics:
600              
601             =over
602              
603             =item heuristic_expiry => $bool
604              
605             If passed as a FALSE value, don't apply heuristics and just return
606             C when "Expires" or "Cache-Control" is lacking.
607              
608             =item h_lastmod_fraction => $num
609              
610             This number represent the fraction of the difference since the
611             "Last-Modified" timestamp to make the expiry time. The default is
612             C<0.10>, the suggested typical setting of 10% in RFC 2616.
613              
614             =item h_min => $sec
615              
616             This is the lower limit of the heuristic expiry age to use. The
617             default is C<60> (1 minute).
618              
619             =item h_max => $sec
620              
621             This is the upper limit of the heuristic expiry age to use. The
622             default is C<86400> (24 hours).
623              
624             =item h_default => $sec
625              
626             This is the expiry age to use when nothing else applies. The default
627             is C<3600> (1 hour) or "h_min" if greater.
628              
629             =back
630              
631             =item $r->is_fresh( %opt )
632              
633             Returns TRUE if the response is fresh, based on the values of
634             freshness_lifetime() and current_age(). If the response is no longer
635             fresh, then it has to be re-fetched or re-validated by the origin
636             server.
637              
638             Options might be passed to control expiry heuristics, see the
639             description of freshness_lifetime().
640              
641             =item $r->fresh_until( %opt )
642              
643             Returns the time (seconds since epoch) when this entity is no longer fresh.
644              
645             Options might be passed to control expiry heuristics, see the
646             description of freshness_lifetime().
647              
648             =back
649              
650             =head1 SEE ALSO
651              
652             L, L, L, L
653              
654             =head1 AUTHOR
655              
656             Gisle Aas
657              
658             =head1 COPYRIGHT AND LICENSE
659              
660             This software is copyright (c) 1994 by Gisle Aas.
661              
662             This is free software; you can redistribute it and/or modify it under
663             the same terms as the Perl 5 programming language system itself.
664              
665             =cut
666              
667             __END__