File Coverage

blib/lib/LWP/UserAgent.pm
Criterion Covered Total %
statement 468 606 77.2
branch 202 366 55.1
condition 74 160 46.2
subroutine 62 75 82.6
pod 42 46 91.3
total 848 1253 67.6


line stmt bran cond sub pod time code
1             package LWP::UserAgent;
2              
3 16     16   709513 use strict;
  16         131  
  16         422  
4              
5 16     16   65 use base qw(LWP::MemberMixin);
  16         22  
  16         6164  
6              
7 16     16   92 use Carp ();
  16         26  
  16         213  
8 16     16   3473 use HTTP::Request ();
  16         171191  
  16         237  
9 16     16   5397 use HTTP::Response ();
  16         67170  
  16         255  
10 16     16   5457 use HTTP::Date ();
  16         47160  
  16         298  
11              
12 16     16   7083 use LWP ();
  16         34  
  16         311  
13 16     16   5380 use LWP::Protocol ();
  16         74  
  16         348  
14              
15 16     16   92 use Scalar::Util qw(blessed);
  16         36  
  16         824  
16 16     16   87 use Try::Tiny qw(try catch);
  16         34  
  16         29397  
17              
18             our $VERSION = '6.34';
19              
20             sub new
21             {
22             # Check for common user mistake
23 34 50   34 1 318794 Carp::croak("Options to LWP::UserAgent should be key/value pairs, not hash reference")
24             if ref($_[1]) eq 'HASH';
25              
26 34         123 my($class, %cnf) = @_;
27              
28 34         70 my $agent = delete $cnf{agent};
29 34         69 my $from = delete $cnf{from};
30 34         55 my $def_headers = delete $cnf{default_headers};
31 34         58 my $timeout = delete $cnf{timeout};
32 34 50       120 $timeout = 3*60 unless defined $timeout;
33 34         67 my $local_address = delete $cnf{local_address};
34 34   100     176 my $ssl_opts = delete $cnf{ssl_opts} || {};
35 34 100       90 unless (exists $ssl_opts->{verify_hostname}) {
36             # The processing of HTTPS_CA_* below is for compatibility with Crypt::SSLeay
37 31 100 33     205 if (exists $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}) {
    50          
38 8         17 $ssl_opts->{verify_hostname} = $ENV{PERL_LWP_SSL_VERIFY_HOSTNAME};
39             }
40             elsif ($ENV{HTTPS_CA_FILE} || $ENV{HTTPS_CA_DIR}) {
41             # Crypt-SSLeay compatibility (verify peer certificate; but not the hostname)
42 0         0 $ssl_opts->{verify_hostname} = 0;
43 0         0 $ssl_opts->{SSL_verify_mode} = 1;
44             }
45             else {
46 23         80 $ssl_opts->{verify_hostname} = 1;
47             }
48             }
49 34 100       94 unless (exists $ssl_opts->{SSL_ca_file}) {
50 33 50 33     200 if (my $ca_file = $ENV{PERL_LWP_SSL_CA_FILE} || $ENV{HTTPS_CA_FILE}) {
51 0         0 $ssl_opts->{SSL_ca_file} = $ca_file;
52             }
53             }
54 34 50       97 unless (exists $ssl_opts->{SSL_ca_path}) {
55 34 50 33     195 if (my $ca_path = $ENV{PERL_LWP_SSL_CA_PATH} || $ENV{HTTPS_CA_DIR}) {
56 0         0 $ssl_opts->{SSL_ca_path} = $ca_path;
57             }
58             }
59 34         65 my $use_eval = delete $cnf{use_eval};
60 34 50       95 $use_eval = 1 unless defined $use_eval;
61 34         53 my $parse_head = delete $cnf{parse_head};
62 34 50       70 $parse_head = 1 unless defined $parse_head;
63 34         57 my $send_te = delete $cnf{send_te};
64 34 100       84 $send_te = 1 unless defined $send_te;
65 34         47 my $show_progress = delete $cnf{show_progress};
66 34         53 my $max_size = delete $cnf{max_size};
67 34         54 my $max_redirect = delete $cnf{max_redirect};
68 34 50       75 $max_redirect = 7 unless defined $max_redirect;
69 34 100       91 my $env_proxy = exists $cnf{env_proxy} ? delete $cnf{env_proxy} : $ENV{PERL_LWP_ENV_PROXY};
70 34 100       82 my $no_proxy = exists $cnf{no_proxy} ? delete $cnf{no_proxy} : [];
71 34 50       131 Carp::croak(qq{no_proxy must be an arrayref, not $no_proxy!}) if ref $no_proxy ne 'ARRAY';
72              
73 34         61 my $cookie_jar = delete $cnf{cookie_jar};
74 34         68 my $conn_cache = delete $cnf{conn_cache};
75 34         60 my $keep_alive = delete $cnf{keep_alive};
76              
77 34 50 33     112 Carp::croak("Can't mix conn_cache and keep_alive")
78             if $conn_cache && $keep_alive;
79              
80 34         60 my $protocols_allowed = delete $cnf{protocols_allowed};
81 34         48 my $protocols_forbidden = delete $cnf{protocols_forbidden};
82              
83 34         47 my $requests_redirectable = delete $cnf{requests_redirectable};
84 34 50       105 $requests_redirectable = ['GET', 'HEAD']
85             unless defined $requests_redirectable;
86              
87             # Actually ""s are just as good as 0's, but for concision we'll just say:
88 34 50 33     120 Carp::croak("protocols_allowed has to be an arrayref or 0, not \"$protocols_allowed\"!")
89             if $protocols_allowed and ref($protocols_allowed) ne 'ARRAY';
90 34 50 33     115 Carp::croak("protocols_forbidden has to be an arrayref or 0, not \"$protocols_forbidden\"!")
91             if $protocols_forbidden and ref($protocols_forbidden) ne 'ARRAY';
92 34 50 33     169 Carp::croak("requests_redirectable has to be an arrayref or 0, not \"$requests_redirectable\"!")
93             if $requests_redirectable and ref($requests_redirectable) ne 'ARRAY';
94              
95 34 50 66     130 if (%cnf && $^W) {
96 0         0 Carp::carp("Unrecognized LWP::UserAgent options: @{[sort keys %cnf]}");
  0         0  
97             }
98              
99             my $self = bless {
100             def_headers => $def_headers,
101             timeout => $timeout,
102             local_address => $local_address,
103             ssl_opts => $ssl_opts,
104             use_eval => $use_eval,
105             show_progress => $show_progress,
106             max_size => $max_size,
107             max_redirect => $max_redirect,
108             # We set proxy later as we do validation on the values
109             proxy => {},
110 34         114 no_proxy => [ @{ $no_proxy } ],
  34         352  
111             protocols_allowed => $protocols_allowed,
112             protocols_forbidden => $protocols_forbidden,
113             requests_redirectable => $requests_redirectable,
114             send_te => $send_te,
115             }, $class;
116              
117 34 100 66     311 $self->agent(defined($agent) ? $agent : $class->_agent)
    50 33        
118             if defined($agent) || !$def_headers || !$def_headers->header("User-Agent");
119 34 100       1923 $self->from($from) if $from;
120 34 50       188 $self->cookie_jar($cookie_jar) if $cookie_jar;
121 34         137 $self->parse_head($parse_head);
122 34 100       86 $self->env_proxy if $env_proxy;
123              
124 34 100       106 if (exists $cnf{proxy}) {
125             Carp::croak(qq{proxy must be an arrayref, not $cnf{proxy}!})
126 1 50       3 if ref $cnf{proxy} ne 'ARRAY';
127 1         4 $self->proxy($cnf{proxy});
128             }
129              
130 34 50       69 $self->protocols_allowed( $protocols_allowed ) if $protocols_allowed;
131 34 50       70 $self->protocols_forbidden($protocols_forbidden) if $protocols_forbidden;
132              
133 34 100       69 if ($keep_alive) {
134 1   50     5 $conn_cache ||= { total_capacity => $keep_alive };
135             }
136 34 100       63 $self->conn_cache($conn_cache) if $conn_cache;
137              
138 34         229 return $self;
139             }
140              
141              
142             sub send_request
143             {
144 73     73 0 175 my($self, $request, $arg, $size) = @_;
145 73         188 my($method, $url) = ($request->method, $request->uri);
146 73         1168 my $scheme = $url->scheme;
147              
148 73         1279 local($SIG{__DIE__}); # protect against user defined die handlers
149              
150 73         305 $self->progress("begin", $request);
151              
152 73         142 my $response = $self->run_handlers("request_send", $request);
153              
154 73 100       179 unless ($response) {
155 71         114 my $protocol;
156              
157             {
158             # Honor object-specific restrictions by forcing protocol objects
159             # into class LWP::Protocol::nogo.
160 71         94 my $x;
  71         83  
161 71 50       197 if($x = $self->protocols_allowed) {
    100          
162 0 0       0 if (grep lc($_) eq $scheme, @$x) {
163             }
164             else {
165 0         0 require LWP::Protocol::nogo;
166 0         0 $protocol = LWP::Protocol::nogo->new;
167             }
168             }
169             elsif ($x = $self->protocols_forbidden) {
170 1 50       5 if(grep lc($_) eq $scheme, @$x) {
171 1         420 require LWP::Protocol::nogo;
172 1         14 $protocol = LWP::Protocol::nogo->new;
173             }
174             }
175             # else fall thru and create the protocol object normally
176             }
177              
178             # Locate protocol to use
179 71         147 my $proxy = $request->{proxy};
180 71 100       249 if ($proxy) {
181 16         127 $scheme = $proxy->scheme;
182             }
183              
184 71 100       332 unless ($protocol) {
185             try {
186 70     70   2868 $protocol = LWP::Protocol::create($scheme, $self);
187             }
188             catch {
189 1     1   40 my $error = $_;
190 1         7 $error =~ s/ at .* line \d+.*//s; # remove file/line number
191 1         4 $response = _new_response($request, HTTP::Status::RC_NOT_IMPLEMENTED, $error);
192 1 50       6 if ($scheme eq "https") {
193 0         0 $response->message($response->message . " (LWP::Protocol::https not installed)");
194 0         0 $response->content_type("text/plain");
195 0         0 $response->content(<
196             LWP will support https URLs if the LWP::Protocol::https module
197             is installed.
198             EOT
199             }
200 70         593 };
201             }
202              
203 71 100 66     1210 if (!$response && $self->{use_eval}) {
    50          
204             # we eval, and turn dies into responses below
205             try {
206 70   50 70   3075 $response = $protocol->request($request, $proxy, $arg, $size, $self->{timeout}) || die "No response returned by $protocol";
207             }
208             catch {
209 2     2   32 my $error = $_;
210 2 50 33     11 if (blessed($error) && $error->isa("HTTP::Response")) {
211 0         0 $response = $error;
212 0         0 $response->request($request);
213             }
214             else {
215 2         4 my $full = $error;
216 2         15 (my $status = $error) =~ s/\n.*//s;
217 2         11 $status =~ s/ at .* line \d+.*//s; # remove file/line number
218 2 50       9 my $code = ($status =~ s/^(\d\d\d)\s+//) ? $1 : HTTP::Status::RC_INTERNAL_SERVER_ERROR;
219 2         6 $response = _new_response($request, $code, $status, $full);
220             }
221 70         461 };
222             }
223             elsif (!$response) {
224             $response = $protocol->request($request, $proxy,
225 0         0 $arg, $size, $self->{timeout});
226             # XXX: Should we die unless $response->is_success ???
227             }
228             }
229              
230 73         1678 $response->request($request); # record request for reference
231 73         965 $response->header("Client-Date" => HTTP::Date::time2str(time));
232              
233 73         5720 $self->run_handlers("response_done", $response);
234              
235 73         220 $self->progress("end", $response);
236 73         340 return $response;
237             }
238              
239              
240             sub prepare_request
241             {
242 75     75 1 179 my($self, $request) = @_;
243 75 100       245 die "Method missing" unless $request->method;
244 74         978 my $url = $request->uri;
245 74 50       1150 die "URL missing" unless $url;
246 74 100       743 die "URL must be absolute" unless $url->scheme;
247              
248 73         1892 $self->run_handlers("request_preprepare", $request);
249              
250 73 50       4864 if (my $def_headers = $self->{def_headers}) {
251 73         302 for my $h ($def_headers->header_field_names) {
252 133         6690 $request->init_header($h => [$def_headers->header($h)]);
253             }
254             }
255              
256 73         4817 $self->run_handlers("request_prepare", $request);
257              
258 73         772 return $request;
259             }
260              
261              
262             sub simple_request
263             {
264 75     75 1 6795 my($self, $request, $arg, $size) = @_;
265              
266             # sanity check the request passed in
267 75 50       219 if (defined $request) {
268 75 50       227 if (ref $request) {
269 75 50 33     1057 Carp::croak("You need a request object, not a " . ref($request) . " object")
      33        
      33        
270             if ref($request) eq 'ARRAY' or ref($request) eq 'HASH' or
271             !$request->can('method') or !$request->can('uri');
272             }
273             else {
274 0         0 Carp::croak("You need a request object, not '$request'");
275             }
276             }
277             else {
278 0         0 Carp::croak("No request object passed in");
279             }
280              
281 75         163 my $error;
282             try {
283 75     75   3785 $request = $self->prepare_request($request);
284             }
285             catch {
286 2     2   60 $error = $_;
287 2         15 $error =~ s/ at .* line \d+.*//s; # remove file/line number
288 75         710 };
289              
290 75 100       1283 if ($error) {
291 2         6 return _new_response($request, HTTP::Status::RC_BAD_REQUEST, $error);
292             }
293 73         224 return $self->send_request($request, $arg, $size);
294             }
295              
296              
297             sub request {
298 76     76 1 70086 my ($self, $request, $arg, $size, $previous) = @_;
299              
300 76         269 my $response = $self->simple_request($request, $arg, $size);
301 76 100       207 $response->previous($previous) if $previous;
302              
303 76 100       364 if ($response->redirects >= $self->{max_redirect}) {
304 2         91 $response->header("Client-Warning" =>
305             "Redirect loop detected (max_redirect = $self->{max_redirect})"
306             );
307 2         141 return $response;
308             }
309              
310 74 50       1541 if (my $req = $self->run_handlers("response_redirect", $response)) {
311 0         0 return $self->request($req, $arg, $size, $response);
312             }
313              
314 74         201 my $code = $response->code;
315              
316 74 100 66     1358 if ( $code == HTTP::Status::RC_MOVED_PERMANENTLY
    100 66        
      33        
      66        
317             or $code == HTTP::Status::RC_FOUND
318             or $code == HTTP::Status::RC_SEE_OTHER
319             or $code == HTTP::Status::RC_TEMPORARY_REDIRECT)
320             {
321 6         19 my $referral = $request->clone;
322              
323             # These headers should never be forwarded
324 6         822 $referral->remove_header('Host', 'Cookie');
325              
326 6 0 33     145 if ( $referral->header('Referer')
      33        
327             && $request->uri->scheme eq 'https'
328             && $referral->uri->scheme eq 'http')
329             {
330             # RFC 2616, section 15.1.3.
331             # https -> http redirect, suppressing Referer
332 0         0 $referral->remove_header('Referer');
333             }
334              
335 6 50 33     239 if ( $code == HTTP::Status::RC_SEE_OTHER
336             || $code == HTTP::Status::RC_FOUND)
337             {
338 0         0 my $method = uc($referral->method);
339 0 0 0     0 unless ($method eq "GET" || $method eq "HEAD") {
340 0         0 $referral->method("GET");
341 0         0 $referral->content("");
342 0         0 $referral->remove_content_headers;
343             }
344             }
345              
346             # And then we update the URL based on the Location:-header.
347 6         18 my $referral_uri = $response->header('Location');
348             {
349             # Some servers erroneously return a relative URL for redirects,
350             # so make it absolute if it not already is.
351 6         193 local $URI::ABS_ALLOW_RELATIVE_SCHEME = 1;
  6         7  
352 6         19 my $base = $response->base;
353 6 50       1959 $referral_uri = "" unless defined $referral_uri;
354 6         16 $referral_uri
355             = $HTTP::URI_CLASS->new($referral_uri, $base)->abs($base);
356             }
357 6         1014 $referral->uri($referral_uri);
358              
359 6 50       131 return $response unless $self->redirect_ok($referral, $response);
360 6         36 return $self->request($referral, $arg, $size, $response);
361              
362             }
363             elsif ($code == HTTP::Status::RC_UNAUTHORIZED
364             || $code == HTTP::Status::RC_PROXY_AUTHENTICATION_REQUIRED)
365             {
366 8         14 my $proxy = ($code == HTTP::Status::RC_PROXY_AUTHENTICATION_REQUIRED);
367 8 50 33     37 my $ch_header
368             = $proxy || $request->method eq 'CONNECT'
369             ? "Proxy-Authenticate"
370             : "WWW-Authenticate";
371 8         84 my @challenges = $response->header($ch_header);
372 8 50       296 unless (@challenges) {
373 0         0 $response->header(
374             "Client-Warning" => "Missing Authenticate header");
375 0         0 return $response;
376             }
377              
378 8         472 require HTTP::Headers::Util;
379 8         870 CHALLENGE: for my $challenge (@challenges) {
380 8         14 $challenge =~ tr/,/;/; # "," is used to separate auth-params!!
381 8         18 ($challenge) = HTTP::Headers::Util::split_header_words($challenge);
382 8         473 my $scheme = shift(@$challenge);
383 8         12 shift(@$challenge); # no value
384 8         40 $challenge = {@$challenge}; # make rest into a hash
385              
386 8 50       40 unless ($scheme =~ /^([a-z]+(?:-[a-z]+)*)$/) {
387 0         0 $response->header(
388             "Client-Warning" => "Bad authentication scheme '$scheme'");
389 0         0 return $response;
390             }
391 8         17 $scheme = $1; # untainted now
392 8         17 my $class = "LWP::Authen::\u$scheme";
393 8         14 $class =~ tr/-/_/;
394              
395 16     16   116 no strict 'refs';
  16         33  
  16         68632  
396 8 100       12 unless (%{"$class\::"}) {
  8         41  
397             # try to load it
398 2         3 my $error;
399             try {
400 2     2   83 (my $req = $class) =~ s{::}{/}g;
401 2 50       8 $req .= '.pm' unless $req =~ /\.pm$/;
402 2         819 require $req;
403             }
404             catch {
405 0     0   0 $error = $_;
406 2         19 };
407 2 50       33 if ($error) {
408 0 0       0 if ($error =~ /^Can\'t locate/) {
409 0         0 $response->header("Client-Warning" =>
410             "Unsupported authentication scheme '$scheme'");
411             }
412             else {
413 0         0 $response->header("Client-Warning" => $error);
414             }
415 0         0 next CHALLENGE;
416             }
417             }
418 8 50       49 unless ($class->can("authenticate")) {
419 0         0 $response->header("Client-Warning" =>
420             "Unsupported authentication scheme '$scheme'");
421 0         0 next CHALLENGE;
422             }
423 8         26 return $class->authenticate($self, $proxy, $challenge, $response,
424             $request, $arg, $size);
425             }
426 0         0 return $response;
427             }
428 60         271 return $response;
429             }
430              
431             #
432             # Now the shortcuts...
433             #
434             sub get {
435 15     15 1 16587 require HTTP::Request::Common;
436 15         15319 my($self, @parameters) = @_;
437 15         76 my @suff = $self->_process_colonic_headers(\@parameters,1);
438 15         72 return $self->request( HTTP::Request::Common::GET( @parameters ), @suff );
439             }
440              
441             sub _has_raw_content {
442 10     10   13 my $self = shift;
443 10         11 shift; # drop url
444              
445             # taken from HTTP::Request::Common::request_type_with_data
446 10         11 my $content;
447 10 100 66     34 $content = shift if @_ and ref $_[0];
448 10         12 my($k, $v);
449 10         24 while (($k,$v) = splice(@_, 0, 2)) {
450 6 50       13 if (lc($k) eq 'content') {
451 6         13 $content = $v;
452             }
453             }
454              
455             # We were given Content => 'string' ...
456 10 100 66     31 if (defined $content && ! ref ($content)) {
457 2         5 return 1;
458             }
459              
460 8         21 return;
461             }
462              
463             sub _maybe_copy_default_content_type {
464 13     13   37 my ($self, $req, @parameters) = @_;
465              
466             # If we have a default Content-Type and someone passes in a POST/PUT
467             # with Content => 'some-string-value', use that Content-Type instead
468             # of x-www-form-urlencoded
469 13         31 my $ct = $self->default_header('Content-Type');
470 13 100 100     435 return unless defined $ct && $self->_has_raw_content(@parameters);
471              
472 2         6 $req->header('Content-Type' => $ct);
473             }
474              
475             sub post {
476 6     6 1 6307 require HTTP::Request::Common;
477 6         16 my($self, @parameters) = @_;
478 6 100       21 my @suff = $self->_process_colonic_headers(\@parameters, (ref($parameters[1]) ? 2 : 1));
479 6         16 my $req = HTTP::Request::Common::POST(@parameters);
480 6         2078 $self->_maybe_copy_default_content_type($req, @parameters);
481 6         78 return $self->request($req, @suff);
482             }
483              
484              
485             sub head {
486 0     0 1 0 require HTTP::Request::Common;
487 0         0 my($self, @parameters) = @_;
488 0         0 my @suff = $self->_process_colonic_headers(\@parameters,1);
489 0         0 return $self->request( HTTP::Request::Common::HEAD( @parameters ), @suff );
490             }
491              
492              
493             sub put {
494 7     7 1 6684 require HTTP::Request::Common;
495 7         1874 my($self, @parameters) = @_;
496 7 100       60 my @suff = $self->_process_colonic_headers(\@parameters, (ref($parameters[1]) ? 2 : 1));
497 7         22 my $req = HTTP::Request::Common::PUT(@parameters);
498 7         8720 $self->_maybe_copy_default_content_type($req, @parameters);
499 7         59 return $self->request($req, @suff);
500             }
501              
502              
503             sub delete {
504 1     1 1 1458 require HTTP::Request::Common;
505 1         12 my($self, @parameters) = @_;
506 1         7 my @suff = $self->_process_colonic_headers(\@parameters,1);
507 1         5 return $self->request( HTTP::Request::Common::DELETE( @parameters ), @suff );
508             }
509              
510              
511             sub _process_colonic_headers {
512             # Process :content_cb / :content_file / :read_size_hint headers.
513 29     29   97 my($self, $args, $start_index) = @_;
514              
515 29         88 my($arg, $size);
516 29         123 for(my $i = $start_index; $i < @$args; $i += 2) {
517 19 50       48 next unless defined $args->[$i];
518              
519             #printf "Considering %s => %s\n", $args->[$i], $args->[$i + 1];
520              
521 19 50       53 if($args->[$i] eq ':content_cb') {
    50          
    50          
522             # Some sanity-checking...
523 0         0 $arg = $args->[$i + 1];
524 0 0       0 Carp::croak("A :content_cb value can't be undef") unless defined $arg;
525 0 0 0     0 Carp::croak("A :content_cb value must be a coderef")
526             unless ref $arg and UNIVERSAL::isa($arg, 'CODE');
527              
528             }
529             elsif ($args->[$i] eq ':content_file') {
530 0         0 $arg = $args->[$i + 1];
531              
532             # Some sanity-checking...
533 0 0       0 Carp::croak("A :content_file value can't be undef")
534             unless defined $arg;
535 0 0       0 Carp::croak("A :content_file value can't be a reference")
536             if ref $arg;
537 0 0       0 Carp::croak("A :content_file value can't be \"\"")
538             unless length $arg;
539              
540             }
541             elsif ($args->[$i] eq ':read_size_hint') {
542 0         0 $size = $args->[$i + 1];
543             # Bother checking it?
544              
545             }
546             else {
547 19         61 next;
548             }
549 0         0 splice @$args, $i, 2;
550 0         0 $i -= 2;
551             }
552              
553             # And return a suitable suffix-list for request(REQ,...)
554              
555 29 50       106 return unless defined $arg;
556 0 0       0 return $arg, $size if defined $size;
557 0         0 return $arg;
558             }
559              
560              
561             sub is_online {
562 0     0 1 0 my $self = shift;
563 0 0       0 return 1 if $self->get("http://www.msftncsi.com/ncsi.txt")->content eq "Microsoft NCSI";
564 0 0       0 return 1 if $self->get("http://www.apple.com")->content =~ m,Apple,;
565 0         0 return 0;
566             }
567              
568              
569             my @ANI = qw(- \ | /);
570              
571             sub progress {
572 192     192 1 337 my($self, $status, $m) = @_;
573 192 50       472 return unless $self->{show_progress};
574              
575 0         0 local($,, $\);
576 0 0       0 if ($status eq "begin") {
    0          
    0          
577 0         0 print STDERR "** ", $m->method, " ", $m->uri, " ==> ";
578 0         0 $self->{progress_start} = time;
579 0         0 $self->{progress_lastp} = "";
580 0         0 $self->{progress_ani} = 0;
581             }
582             elsif ($status eq "end") {
583 0         0 delete $self->{progress_lastp};
584 0         0 delete $self->{progress_ani};
585 0         0 print STDERR $m->status_line;
586 0         0 my $t = time - delete $self->{progress_start};
587 0 0       0 print STDERR " (${t}s)" if $t;
588 0         0 print STDERR "\n";
589             }
590             elsif ($status eq "tick") {
591 0         0 print STDERR "$ANI[$self->{progress_ani}++]\b";
592 0         0 $self->{progress_ani} %= @ANI;
593             }
594             else {
595 0         0 my $p = sprintf "%3.0f%%", $status * 100;
596 0 0       0 return if $p eq $self->{progress_lastp};
597 0         0 print STDERR "$p\b\b\b\b";
598 0         0 $self->{progress_lastp} = $p;
599             }
600 0         0 STDERR->flush;
601             }
602              
603              
604             #
605             # This whole allow/forbid thing is based on man 1 at's way of doing things.
606             #
607             sub is_protocol_supported
608             {
609 1     1 1 602 my($self, $scheme) = @_;
610 1 50       4 if (ref $scheme) {
611             # assume we got a reference to an URI object
612 0         0 $scheme = $scheme->scheme;
613             }
614             else {
615 1 50       5 Carp::croak("Illegal scheme '$scheme' passed to is_protocol_supported")
616             if $scheme =~ /\W/;
617 1         3 $scheme = lc $scheme;
618             }
619              
620 1         1 my $x;
621 1 50 33     5 if(ref($self) and $x = $self->protocols_allowed) {
    50 33        
622 0 0       0 return 0 unless grep lc($_) eq $scheme, @$x;
623             }
624             elsif (ref($self) and $x = $self->protocols_forbidden) {
625 1 50       8 return 0 if grep lc($_) eq $scheme, @$x;
626             }
627              
628 0         0 local($SIG{__DIE__}); # protect against user defined die handlers
629 0         0 $x = LWP::Protocol::implementor($scheme);
630 0 0 0     0 return 1 if $x and $x ne 'LWP::Protocol::nogo';
631 0         0 return 0;
632             }
633              
634              
635 73     73 1 289 sub protocols_allowed { shift->_elem('protocols_allowed' , @_) }
636 77     77 1 191 sub protocols_forbidden { shift->_elem('protocols_forbidden' , @_) }
637 6     6 1 14 sub requests_redirectable { shift->_elem('requests_redirectable', @_) }
638              
639              
640             sub redirect_ok
641             {
642             # RFC 2616, section 10.3.2 and 10.3.3 say:
643             # If the 30[12] status code is received in response to a request other
644             # than GET or HEAD, the user agent MUST NOT automatically redirect the
645             # request unless it can be confirmed by the user, since this might
646             # change the conditions under which the request was issued.
647              
648             # Note that this routine used to be just:
649             # return 0 if $_[1]->method eq "POST"; return 1;
650              
651 6     6 1 15 my($self, $new_request, $response) = @_;
652 6         13 my $method = $response->request->method;
653             return 0 unless grep $_ eq $method,
654 6 50       86 @{ $self->requests_redirectable || [] };
  6 50       14  
655              
656 6 50       14 if ($new_request->uri->scheme eq 'file') {
657 0         0 $response->header("Client-Warning" =>
658             "Can't redirect to a file:// URL!");
659 0         0 return 0;
660             }
661              
662             # Otherwise it's apparently okay...
663 6         112 return 1;
664             }
665              
666             sub credentials {
667 56     56 1 3839 my $self = shift;
668 56   100     132 my $netloc = lc(shift || '');
669 56   100     100 my $realm = shift || "";
670 56         92 my $old = $self->{basic_authentication}{$netloc}{$realm};
671 56 100       93 if (@_) {
672 13         44 $self->{basic_authentication}{$netloc}{$realm} = [@_];
673             }
674 56 100       109 return unless $old;
675 29 100       70 return @$old if wantarray;
676 14         57 return join(":", @$old);
677             }
678              
679             sub get_basic_credentials
680             {
681 4     4 1 12 my($self, $realm, $uri, $proxy) = @_;
682 4 50       6 return if $proxy;
683 4         11 return $self->credentials($uri->host_port, $realm);
684             }
685              
686              
687 4     4 1 33 sub timeout { shift->_elem('timeout', @_); }
688 0     0 1 0 sub local_address{ shift->_elem('local_address',@_); }
689 2     2 1 1126 sub max_size { shift->_elem('max_size', @_); }
690 6     6 1 4766 sub max_redirect { shift->_elem('max_redirect', @_); }
691 0     0 1 0 sub show_progress{ shift->_elem('show_progress', @_); }
692 0     0 1 0 sub send_te { shift->_elem('send_te', @_); }
693              
694             sub ssl_opts {
695 17     17 1 853 my $self = shift;
696 17 100       40 if (@_ == 1) {
697 13         15 my $k = shift;
698 13         57 return $self->{ssl_opts}{$k};
699             }
700 4 100       8 if (@_) {
701 2         2 my $old;
702 2         6 while (@_) {
703 2         6 my($k, $v) = splice(@_, 0, 2);
704 2 50       6 $old = $self->{ssl_opts}{$k} unless @_;
705 2 100       5 if (defined $v) {
706 1         4 $self->{ssl_opts}{$k} = $v;
707             }
708             else {
709 1         4 delete $self->{ssl_opts}{$k};
710             }
711             }
712 2         2 %{$self->{ssl_opts}} = (%{$self->{ssl_opts}}, @_);
  2         4  
  2         6  
713 2         8 return $old;
714             }
715              
716 2         3 return keys %{$self->{ssl_opts}};
  2         12  
717             }
718              
719             sub parse_head {
720 40     40 1 71 my $self = shift;
721 40 100       106 if (@_) {
722 39         60 my $flag = shift;
723 39         48 my $parser;
724             my $old = $self->set_my_handler("response_header", $flag ? sub {
725 8     8   24 my($response, $ua) = @_;
726 8         1944 require HTML::HeadParser;
727 8         16975 $parser = HTML::HeadParser->new;
728 8 50       776 $parser->xml_mode(1) if $response->content_is_xhtml;
729 8 50 33     364 $parser->utf8_mode(1) if $] >= 5.008 && $HTML::Parser::VERSION >= 3.40;
730              
731 8         82 push(@{$response->{handlers}{response_data}}, {
732             callback => sub {
733 8 50       33 return unless $parser;
734 8 50       103 unless ($parser->parse($_[3])) {
735 8         1235 my $h = $parser->header;
736 8         49 my $r = $_[0];
737 8         23 for my $f ($h->header_field_names) {
738 11         414 $r->init_header($f, [$h->header($f)]);
739             }
740 8         643 undef($parser);
741             }
742             },
743 8         12 });
744              
745             } : undef,
746 39 100       401 m_media_type => "html",
747             );
748 39         476 return !!$old;
749             }
750             else {
751 1         4 return !!$self->get_my_handler("response_header");
752             }
753             }
754              
755             sub cookie_jar {
756 1     1 1 2 my $self = shift;
757 1         1 my $old = $self->{cookie_jar};
758 1 50       3 if (@_) {
759 1         2 my $jar = shift;
760 1 50       3 if (ref($jar) eq "HASH") {
761 0         0 require HTTP::Cookies;
762 0         0 $jar = HTTP::Cookies->new(%$jar);
763             }
764 1         3 $self->{cookie_jar} = $jar;
765             $self->set_my_handler("request_prepare",
766 0     0   0 $jar ? sub { $jar->add_cookie_header($_[0]); } : undef,
767 1 50       5 );
768             $self->set_my_handler("response_done",
769 0     0   0 $jar ? sub { $jar->extract_cookies($_[0]); } : undef,
770 1 50       7 );
771             }
772 1         1 $old;
773             }
774              
775             sub default_headers {
776 62     62 1 89 my $self = shift;
777 62   66     499 my $old = $self->{def_headers} ||= HTTP::Headers->new;
778 62 50       480 if (@_) {
779 0 0 0     0 Carp::croak("default_headers not set to HTTP::Headers compatible object")
780             unless @_ == 1 && $_[0]->can("header_field_names");
781 0         0 $self->{def_headers} = shift;
782             }
783 62         185 return $old;
784             }
785              
786             sub default_header {
787 60     60 1 635 my $self = shift;
788 60         171 return $self->default_headers->header(@_);
789             }
790              
791 34     34   141 sub _agent { "libwww-perl/$VERSION" }
792              
793             sub agent {
794 41     41 1 118 my $self = shift;
795 41 100       99 if (@_) {
796 39         66 my $agent = shift;
797 39 50       81 if ($agent) {
798 39 100       158 $agent .= $self->_agent if $agent =~ /\s+$/;
799             }
800             else {
801 0         0 undef($agent)
802             }
803 39         133 return $self->default_header("User-Agent", $agent);
804             }
805 2         5 return $self->default_header("User-Agent");
806             }
807              
808             sub from { # legacy
809 3     3 1 51 my $self = shift;
810 3         15 return $self->default_header("From", @_);
811             }
812              
813              
814             sub conn_cache {
815 1     1 1 1 my $self = shift;
816 1         3 my $old = $self->{conn_cache};
817 1 50       3 if (@_) {
818 1         1 my $cache = shift;
819 1 50       4 if (ref($cache) eq "HASH") {
820 1         388 require LWP::ConnCache;
821 1         8 $cache = LWP::ConnCache->new(%$cache);
822             }
823 1         3 $self->{conn_cache} = $cache;
824             }
825 1         2 $old;
826             }
827              
828              
829             sub add_handler {
830 52     52 1 2893 my($self, $phase, $cb, %spec) = @_;
831 52   66     133 $spec{line} ||= join(":", (caller)[1,2]);
832 52   33     194 my $conf = $self->{handlers}{$phase} ||= do {
833 52         6831 require HTTP::Config;
834 52         29191 HTTP::Config->new;
835             };
836 52         460 $conf->add(%spec, callback => $cb);
837             }
838              
839             sub set_my_handler {
840 58     58 1 209 my($self, $phase, $cb, %spec) = @_;
841 58 50       497 $spec{owner} = (caller(1))[3] unless exists $spec{owner};
842 58         358 $self->remove_handler($phase, %spec);
843 58   33     490 $spec{line} ||= join(":", (caller)[1,2]);
844 58 100       281 $self->add_handler($phase, $cb, %spec) if $cb;
845             }
846              
847             sub get_my_handler {
848 9     9 1 20 my $self = shift;
849 9         14 my $phase = shift;
850 9 100       23 my $init = pop if @_ % 2;
851 9         32 my %spec = @_;
852 9         36 my $conf = $self->{handlers}{$phase};
853 9 100       19 unless ($conf) {
854 4 50       8 return unless $init;
855 4         38 require HTTP::Config;
856 4         17 $conf = $self->{handlers}{$phase} = HTTP::Config->new;
857             }
858 9 50       69 $spec{owner} = (caller(1))[3] unless exists $spec{owner};
859 9         38 my @h = $conf->find(%spec);
860 9 100 66     197 if (!@h && $init) {
861 6 50       18 if (ref($init) eq "CODE") {
    0          
862 6         14 $init->(\%spec);
863             }
864             elsif (ref($init) eq "HASH") {
865 0         0 while (my($k, $v) = each %$init) {
866 0         0 $spec{$k} = $v;
867             }
868             }
869 6   50 0   15 $spec{callback} ||= sub {};
870 6   33     46 $spec{line} ||= join(":", (caller)[1,2]);
871 6         17 $conf->add(\%spec);
872 6         46 return \%spec;
873             }
874 3 50       15 return wantarray ? @h : $h[0];
875             }
876              
877             sub remove_handler {
878 58     58 1 154 my($self, $phase, %spec) = @_;
879 58 50       136 if ($phase) {
880 58   100     262 my $conf = $self->{handlers}{$phase} || return;
881 11         39 my @h = $conf->remove(%spec);
882 11 100       283 delete $self->{handlers}{$phase} if $conf->empty;
883 11         100 return @h;
884             }
885              
886 0 0       0 return unless $self->{handlers};
887 0         0 return map $self->remove_handler($_), sort keys %{$self->{handlers}};
  0         0  
888             }
889              
890             sub handlers {
891 475     475 1 728 my($self, $phase, $o) = @_;
892 475         565 my @h;
893 475 100 100     1072 if ($o->{handlers} && $o->{handlers}{$phase}) {
894 47         69 push(@h, @{$o->{handlers}{$phase}});
  47         96  
895             }
896 475 100       980 if (my $conf = $self->{handlers}{$phase}) {
897 95         261 push(@h, $conf->matching($o));
898             }
899 475         18442 return @h;
900             }
901              
902             sub run_handlers {
903 429     429 0 829 my($self, $phase, $o) = @_;
904              
905             # here we pass $_[2] to the callbacks, instead of $o, so that they
906             # can assign to it; e.g. request_prepare is documented to allow
907             # that
908 429 100       873 if (defined(wantarray)) {
909 147         284 for my $h ($self->handlers($phase, $o)) {
910 2         5 my $ret = $h->{callback}->($_[2], $self, $h);
911 2 50       115 return $ret if $ret;
912             }
913 145         338 return undef;
914             }
915              
916 282         642 for my $h ($self->handlers($phase, $o)) {
917 53         199 $h->{callback}->($_[2], $self, $h);
918             }
919             }
920              
921              
922             # deprecated
923 0     0 0 0 sub use_eval { shift->_elem('use_eval', @_); }
924             sub use_alarm
925             {
926 0 0 0 0 0 0 Carp::carp("LWP::UserAgent->use_alarm(BOOL) is a no-op")
927             if @_ > 1 && $^W;
928 0         0 "";
929             }
930              
931              
932             sub clone
933             {
934 1     1 1 5 my $self = shift;
935 1         7 my $copy = bless { %$self }, ref $self; # copy most fields
936              
937 1         2 delete $copy->{handlers};
938 1         2 delete $copy->{conn_cache};
939              
940             # copy any plain arrays and hashes; known not to need recursive copy
941 1         4 for my $k (qw(proxy no_proxy requests_redirectable ssl_opts)) {
942 4 50       9 next unless $copy->{$k};
943 4 100       9 if (ref($copy->{$k}) eq "ARRAY") {
    50          
944 2         3 $copy->{$k} = [ @{$copy->{$k}} ];
  2         4  
945             }
946             elsif (ref($copy->{$k}) eq "HASH") {
947 2         4 $copy->{$k} = { %{$copy->{$k}} };
  2         5  
948             }
949             }
950              
951 1 50       3 if ($self->{def_headers}) {
952 1         95 $copy->{def_headers} = $self->{def_headers}->clone;
953             }
954              
955             # re-enable standard handlers
956 1         4 $copy->parse_head($self->parse_head);
957              
958             # no easy way to clone the cookie jar; so let's just remove it for now
959 1         3 $copy->cookie_jar(undef);
960              
961 1         3 $copy;
962             }
963              
964              
965             sub mirror
966             {
967 0     0 1 0 my($self, $url, $file) = @_;
968              
969 0         0 my $request = HTTP::Request->new('GET', $url);
970              
971             # If the file exists, add a cache-related header
972 0 0       0 if ( -e $file ) {
973 0         0 my ($mtime) = ( stat($file) )[9];
974 0 0       0 if ($mtime) {
975 0         0 $request->header( 'If-Modified-Since' => HTTP::Date::time2str($mtime) );
976             }
977             }
978 0         0 my $tmpfile = "$file-$$";
979              
980 0         0 my $response = $self->request($request, $tmpfile);
981 0 0       0 if ( $response->header('X-Died') ) {
982 0         0 die $response->header('X-Died');
983             }
984              
985             # Only fetching a fresh copy of the would be considered success.
986             # If the file was not modified, "304" would returned, which
987             # is considered by HTTP::Status to be a "redirect", /not/ "success"
988 0 0       0 if ( $response->is_success ) {
989 0 0       0 my @stat = stat($tmpfile) or die "Could not stat tmpfile '$tmpfile': $!";
990 0         0 my $file_length = $stat[7];
991 0         0 my ($content_length) = $response->header('Content-length');
992              
993 0 0 0     0 if ( defined $content_length and $file_length < $content_length ) {
    0 0        
994 0         0 unlink($tmpfile);
995 0         0 die "Transfer truncated: " . "only $file_length out of $content_length bytes received\n";
996             }
997             elsif ( defined $content_length and $file_length > $content_length ) {
998 0         0 unlink($tmpfile);
999 0         0 die "Content-length mismatch: " . "expected $content_length bytes, got $file_length\n";
1000             }
1001             # The file was the expected length.
1002             else {
1003             # Replace the stale file with a fresh copy
1004 0 0       0 if ( -e $file ) {
1005             # Some DOSish systems fail to rename if the target exists
1006 0         0 chmod 0777, $file;
1007 0         0 unlink $file;
1008             }
1009 0 0       0 rename( $tmpfile, $file )
1010             or die "Cannot rename '$tmpfile' to '$file': $!\n";
1011              
1012             # make sure the file has the same last modification time
1013 0 0       0 if ( my $lm = $response->last_modified ) {
1014 0         0 utime $lm, $lm, $file;
1015             }
1016             }
1017             }
1018             # The local copy is fresh enough, so just delete the temp file
1019             else {
1020 0         0 unlink($tmpfile);
1021             }
1022 0         0 return $response;
1023             }
1024              
1025              
1026             sub _need_proxy {
1027 23     23   44 my($req, $ua) = @_;
1028 23 50       56 return if exists $req->{proxy};
1029 23   100     73 my $proxy = $ua->{proxy}{$req->uri->scheme} || return;
1030 16 50       337 if ($ua->{no_proxy}) {
1031 16 50       25 if (my $host = eval { $req->uri->host }) {
  16         45  
1032 16         446 for my $domain (@{$ua->{no_proxy}}) {
  16         47  
1033 0 0       0 if ($host =~ /\Q$domain\E$/) {
1034 0         0 return;
1035             }
1036             }
1037             }
1038             }
1039 16         50 $req->{proxy} = $HTTP::URI_CLASS->new($proxy);
1040             }
1041              
1042              
1043             sub proxy {
1044 28     28 1 5186 my $self = shift;
1045 28         43 my $key = shift;
1046 28 100 100     83 if (!@_ && ref $key eq 'ARRAY') {
1047 1 50       2 die 'odd number of items in proxy arrayref!' unless @{$key} % 2 == 0;
  1         4  
1048              
1049             # This map reads the elements of $key 2 at a time
1050             return
1051 2         10 map { $self->proxy($key->[2 * $_], $key->[2 * $_ + 1]) }
1052 1         3 (0 .. @{$key} / 2 - 1);
  1         5  
1053             }
1054 27 100       56 return map { $self->proxy($_, @_) } @$key if ref $key;
  5         18  
1055              
1056 25 50       235 Carp::croak("'$key' is not a valid URI scheme") unless $key =~ /^$URI::scheme_re\z/;
1057 25         70 my $old = $self->{'proxy'}{$key};
1058 25 100       51 if (@_) {
1059 15         41 my $url = shift;
1060 15 100 66     85 if (defined($url) && length($url)) {
1061 14 50       151 Carp::croak("Proxy must be specified as absolute URI; '$url' is not") unless $url =~ /^$URI::scheme_re:/;
1062 14 50 66     108 Carp::croak("Bad http proxy specification '$url'") if $url =~ /^https?:/ && $url !~ m,^https?://\w,;
1063             }
1064 15         63 $self->{proxy}{$key} = $url;
1065 15         63 $self->set_my_handler("request_preprepare", \&_need_proxy)
1066             }
1067 25         220 return $old;
1068             }
1069              
1070              
1071             sub env_proxy {
1072 6     6 1 140 my ($self) = @_;
1073 6         1950 require Encode;
1074 6         36127 require Encode::Locale;
1075 6         10674 my($k,$v);
1076 6         30 while(($k, $v) = each %ENV) {
1077 211 50       337 if ($ENV{REQUEST_METHOD}) {
1078             # Need to be careful when called in the CGI environment, as
1079             # the HTTP_PROXY variable is under control of that other guy.
1080 0 0       0 next if $k =~ /^HTTP_/;
1081 0 0       0 $k = "HTTP_PROXY" if $k eq "CGI_HTTP_PROXY";
1082             }
1083 211         263 $k = lc($k);
1084 211 100       561 next unless $k =~ /^(.*)_proxy$/;
1085 5         12 $k = $1;
1086 5 50       24 if ($k eq 'no') {
1087 0         0 $self->no_proxy(split(/\s*,\s*/, $v));
1088             }
1089             else {
1090             # Ignore random _proxy variables, allow only valid schemes
1091 5 100       61 next unless $k =~ /^$URI::scheme_re\z/;
1092             # Ignore xxx_proxy variables if xxx isn't a supported protocol
1093 3 100       14 next unless LWP::Protocol::implementor($k);
1094 2         13 $self->proxy($k, Encode::decode(locale => $v));
1095             }
1096             }
1097             }
1098              
1099              
1100             sub no_proxy {
1101 0     0 1 0 my($self, @no) = @_;
1102 0 0       0 if (@no) {
1103 0         0 push(@{ $self->{'no_proxy'} }, @no);
  0         0  
1104             }
1105             else {
1106 0         0 $self->{'no_proxy'} = [];
1107             }
1108             }
1109              
1110              
1111             sub _new_response {
1112 5     5   14 my($request, $code, $message, $content) = @_;
1113 5   33     13 $message ||= HTTP::Status::status_message($code);
1114 5         28 my $response = HTTP::Response->new($code, $message);
1115 5         220 $response->request($request);
1116 5         64 $response->header("Client-Date" => HTTP::Date::time2str(time));
1117 5         507 $response->header("Client-Warning" => "Internal response");
1118 5         260 $response->header("Content-Type" => "text/plain");
1119 5   66     243 $response->content($content || "$code $message\n");
1120 5         147 return $response;
1121             }
1122              
1123              
1124             1;
1125              
1126             __END__