File Coverage

blib/lib/Net/Async/HTTP.pm
Criterion Covered Total %
statement 349 385 90.6
branch 148 180 82.2
condition 60 94 63.8
subroutine 55 60 91.6
pod 8 13 61.5
total 620 732 84.7


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2008-2024 -- leonerd@leonerd.org.uk
5              
6             package Net::Async::HTTP 0.50;
7              
8 38     38   9076359 use v5.14;
  38         148  
9 38     38   237 use warnings;
  38         266  
  38         2487  
10 38     38   221 use base qw( IO::Async::Notifier );
  38         114  
  38         22461  
11              
12             our $DEFAULT_UA = "Perl + " . __PACKAGE__ . "/$Net::Async::HTTP::VERSION";
13             our $DEFAULT_MAXREDIR = 3;
14             our $DEFAULT_MAX_IN_FLIGHT = 4;
15             our $DEFAULT_MAX_CONNS_PER_HOST = $ENV{NET_ASYNC_HTTP_MAXCONNS} // 1;
16              
17 38     38   667070 use Carp;
  38         114  
  38         2724  
18              
19 38     38   21665 use Net::Async::HTTP::Connection;
  38         183  
  38         1807  
20              
21 38     38   20347 use HTTP::Request;
  38         46381  
  38         1491  
22 38     38   19931 use HTTP::Request::Common qw();
  38         104091  
  38         1217  
23 38     38   258 use URI;
  38         124  
  38         1765  
24              
25 38     38   205 use IO::Async::Stream 0.59;
  38         721  
  38         1333  
26 38     38   995 use IO::Async::Loop 0.59; # ->connect( handle ) ==> $stream
  38         8895  
  38         1042  
27              
28 38     38   190 use Future 0.28; # ->set_label
  38         475  
  38         1082  
29 38     38   190 use Future::Utils 0.16 qw( repeat );
  38         604  
  38         2830  
30              
31 38         349 use Metrics::Any 0.05 '$metrics',
32             strict => 1,
33 38     38   213 name_prefix => [qw( http client )];
  38         657  
34              
35 38     38   3342 use Scalar::Util qw( blessed reftype );
  38         71  
  38         2013  
36 38     38   205 use Time::HiRes qw( time );
  38         83  
  38         485  
37 38     38   2680 use List::Util 1.29 qw( first pairs pairgrep );
  38         815  
  38         3567  
38 38         3266 use Socket 2.010 qw(
39             SOCK_STREAM IPPROTO_IP IP_TOS
40             IPTOS_LOWDELAY IPTOS_THROUGHPUT IPTOS_RELIABILITY IPTOS_MINCOST
41 38     38   323 );
  38         799  
42              
43 38     38   287 use constant HTTP_PORT => 80;
  38         61  
  38         2901  
44 38     38   214 use constant HTTPS_PORT => 443;
  38         59  
  38         2028  
45              
46 38     38   242 use constant READ_LEN => 64*1024; # 64 KiB
  38         65  
  38         1985  
47 38     38   191 use constant WRITE_LEN => 64*1024; # 64 KiB
  38         82  
  38         1975  
48              
49 38     38   251 use Struct::Dumb 0.07; # equallity operator overloading
  38         847  
  38         265  
50             struct Ready => [qw( future connecting )];
51              
52             =head1 NAME
53              
54             C - use HTTP with C
55              
56             =head1 SYNOPSIS
57              
58             =for highlighter language=perl
59              
60             use Future::AsyncAwait;
61              
62             use IO::Async::Loop;
63             use Net::Async::HTTP;
64             use URI;
65              
66             my $loop = IO::Async::Loop->new();
67              
68             my $http = Net::Async::HTTP->new();
69              
70             $loop->add( $http );
71              
72             my $response = await $http->do_request(
73             uri => URI->new( "http://www.cpan.org/" ),
74             );
75              
76             print "Front page of http://www.cpan.org/ is:\n";
77             print $response->as_string;
78              
79             =head1 DESCRIPTION
80              
81             This object class implements an asynchronous HTTP user agent. It sends
82             requests to servers, returning L instances to yield responses when
83             they are received. The object supports multiple concurrent connections to
84             servers, and allows multiple requests in the pipeline to any one connection.
85             Normally, only one such object will be needed per program to support any
86             number of requests.
87              
88             As well as using futures the module also supports a callback-based interface.
89              
90             This module optionally supports SSL connections, if L is
91             installed. If so, SSL can be requested either by passing a URI with the
92             C scheme, or by passing a true value as the C parameter.
93              
94             =head2 Connection Pooling
95              
96             There are three ways in which connections to HTTP server hosts are managed by
97             this object, controlled by the value of C. This
98             controls when new connections are established to servers, as compared to
99             waiting for existing connections to be free, as new requests are made to them.
100              
101             They are:
102              
103             =over 2
104              
105             =item max_connections_per_host = 1
106              
107             This is the default setting. In this mode, there will be one connection per
108             host on which there are active or pending requests. If new requests are made
109             while an existing one is outstanding, they will be queued to wait for it.
110              
111             If pipelining is active on the connection (because both the C option
112             is true and the connection is known to be an HTTP/1.1 server), then requests
113             will be pipelined into the connection awaiting their response. If not, they
114             will be queued awaiting a response to the previous before sending the next.
115              
116             =item max_connections_per_host > 1
117              
118             In this mode, there can be more than one connection per host. If a new request
119             is made, it will try to re-use idle connections if there are any, or if they
120             are all busy it will create a new connection to the host, up to the configured
121             limit.
122              
123             =item max_connections_per_host = 0
124              
125             In this mode, there is no upper limit to the number of connections per host.
126             Every new request will try to reuse an idle connection, or else create a new
127             one if all the existing ones are busy.
128              
129             =back
130              
131             These modes all apply per hostname / server port pair; they do not affect the
132             behaviour of connections made to differing hostnames, or differing ports on
133             the same hostname.
134              
135             =cut
136              
137             $metrics->make_gauge( requests_in_flight =>
138             description => "Count of the number of requests sent that have not yet been completed",
139             # no labels
140             );
141             $metrics->make_counter( requests =>
142             description => "Number of HTTP requests sent",
143             labels => [qw( method )],
144             );
145             $metrics->make_counter( responses =>
146             description => "Number of HTTP responses received",
147             labels => [qw( method code )],
148             );
149             $metrics->make_timer( request_duration =>
150             description => "Duration of time spent waiting for responses",
151             # no labels
152             );
153             $metrics->make_distribution( response_bytes =>
154             name => [qw( response bytes )],
155             description => "The size in bytes of responses received",
156             units => "bytes",
157             # no labels
158             );
159              
160             sub _init
161             {
162 38     38   8609563 my $self = shift;
163              
164 38         234 $self->{connections} = {}; # { "$host:$port" } -> [ @connections ]
165              
166 38         127 $self->{read_len} = READ_LEN;
167 38         677 $self->{write_len} = WRITE_LEN;
168              
169 38         392 $self->{max_connections_per_host} = $DEFAULT_MAX_CONNS_PER_HOST;
170              
171 38         242 $self->{ssl_params} = {};
172             }
173              
174             sub _remove_from_loop
175             {
176 5     5   13554 my $self = shift;
177              
178 5         14 foreach my $conn ( map { @$_ } values %{ $self->{connections} } ) {
  6         42  
  5         23  
179 4         37 $conn->close;
180             }
181              
182 5         235 $self->SUPER::_remove_from_loop( @_ );
183             }
184              
185             =head1 PARAMETERS
186              
187             The following named parameters may be passed to C or C:
188              
189             =head2 user_agent => STRING
190              
191             A string to set in the C HTTP header. If not supplied, one will
192             be constructed that declares C and the version number.
193              
194             =head2 headers => ARRAY or HASH
195              
196             I
197              
198             A set of extra headers to apply to every outgoing request. May be specified
199             either as an even-sized array containing key/value pairs, or a hash.
200              
201             Individual header values may be added or changed without replacing the entire
202             set by using the L method and passing a key called C<+headers>:
203              
204             $http->configure( +headers => { One_More => "Key" } );
205              
206             =head2 max_redirects => INT
207              
208             Optional. How many levels of redirection to follow. If not supplied, will
209             default to 3. Give 0 to disable redirection entirely.
210              
211             =head2 max_in_flight => INT
212              
213             Optional. The maximum number of in-flight requests to allow per host when
214             pipelining is enabled and supported on that host. If more requests are made
215             over this limit they will be queued internally by the object and not sent to
216             the server until responses are received. If not supplied, will default to 4.
217             Give 0 to disable the limit entirely.
218              
219             =head2 max_connections_per_host => INT
220              
221             Optional. Controls the maximum number of connections per hostname/server port
222             pair, before requests will be queued awaiting one to be free. Give 0 to
223             disable the limit entirely. See also the L section
224             documented above.
225              
226             Currently, if not supplied it will default to 1. However, it has been found in
227             practice that most programs will raise this limit to something higher, perhaps
228             3 or 4. Therefore, a future version of this module may set a higher value.
229              
230             To test if your application will handle this correctly, you can set a
231             different default by setting an environment variable:
232              
233             $ NET_ASYNC_HTTP_MAXCONNS=3 perl ...
234              
235             =head2 timeout => NUM
236              
237             Optional. How long in seconds to wait before giving up on a request. If not
238             supplied then no default will be applied, and no timeout will take place.
239              
240             =head2 stall_timeout => NUM
241              
242             Optional. How long in seconds to wait after each write or read of data on a
243             socket, before giving up on a request. This may be more useful than
244             C on large-file operations, as it will not time out provided that
245             regular progress is still being made.
246              
247             =head2 proxy_host => STRING
248              
249             =head2 proxy_port => INT
250              
251             I
252              
253             =head2 proxy_path => PATH
254              
255             I
256              
257             Optional. Default values to apply to each C method.
258              
259             =head2 cookie_jar => HTTP::Cookies
260              
261             Optional. A reference to a L object. Will be used to set
262             cookies in requests and store them from responses.
263              
264             =head2 pipeline => BOOL
265              
266             Optional. If false, disables HTTP/1.1-style request pipelining.
267              
268             =head2 close_after_request => BOOL
269              
270             I
271              
272             Optional. If true, will set the C header on outgoing
273             requests and disable pipelining, thus making every request use a new
274             connection.
275              
276             =head2 family => INT
277              
278             =head2 local_host => STRING
279              
280             =head2 local_port => INT
281              
282             =head2 local_addrs => ARRAY
283              
284             =head2 local_addr => HASH or ARRAY
285              
286             Optional. Parameters to pass on to the C method used to connect
287             sockets to HTTP servers. Sets the socket family and local socket address to
288             C to. For more detail, see the documentation in
289             L.
290              
291             =head2 fail_on_error => BOOL
292              
293             Optional. Affects the behaviour of response handling when a C<4xx> or C<5xx>
294             response code is received. When false, these responses will be processed as
295             other responses and yielded as the result of the future, or passed to the
296             C callback. When true, such an error response causes the future
297             to fail, or the C callback to be invoked.
298              
299             The HTTP response and request objects will be passed as well as the code and
300             message, and the failure name will be C.
301              
302             ( $code_message, "http", $response, $request ) = $f->failure
303              
304             $on_error->( "$code $message", $response, $request )
305              
306             =head2 read_len => INT
307              
308             =head2 write_len => INT
309              
310             Optional. Used to set the reading and writing buffer lengths on the underlying
311             C objects that represent connections to the server. If not
312             define, a default of 64 KiB will be used.
313              
314             =head2 ip_tos => INT or STRING
315              
316             Optional. Used to set the C socket option on client sockets. If given,
317             should either be a C constant, or one of the string names
318             C, C, C or C. If undefined or left
319             absent, no option will be set.
320              
321             =head2 decode_content => BOOL
322              
323             Optional. If true, incoming responses that have a recognised
324             C are handled by the module, and decompressed content is
325             passed to the body handling callback or returned in the C. See
326             L below for details of which encoding types are recognised.
327             When this option is enabled, outgoing requests also have the
328             C header added to them if it does not already exist.
329              
330             Currently the default is false, because this behaviour is new, but it may
331             default to true in a later version. Applications which care which behaviour
332             applies should set this to a defined value to ensure it doesn't change.
333              
334             =head2 SSL_*
335              
336             Additionally, any parameters whose names start with C will be stored and
337             passed on requests to perform SSL requests. This simplifies configuration of
338             common SSL parameters.
339              
340             =head2 require_SSL => BOOL
341              
342             Optional. If true, then any attempt to make a request that does not use SSL
343             (either by calling C, or as a result of a redirection) will
344             immediately fail.
345              
346             =head2 SOCKS_*
347              
348             I
349              
350             Additionally, any parameters whose names start with C will be stored
351             and used by L to establish connections via a configured
352             proxy.
353              
354             =cut
355              
356             sub configure
357             {
358 52     52 1 21605 my $self = shift;
359 52         203 my %params = @_;
360              
361 52         246 foreach (qw( user_agent max_redirects max_in_flight max_connections_per_host
362             timeout stall_timeout proxy_host proxy_port cookie_jar pipeline
363             close_after_request family local_host local_port local_addrs local_addr
364             fail_on_error read_len write_len decode_content require_SSL ))
365             {
366 1092 100       2284 $self->{$_} = delete $params{$_} if exists $params{$_};
367             }
368              
369             # Always store internally as ARRAyref
370 52 100       249 if( my $headers = delete $params{headers} ) {
371 1 50       9 @{ $self->{headers} } =
  1 50       4  
372             ( ref $headers eq "ARRAY" ) ? @$headers :
373             ( ref $headers eq "HASH" ) ? %$headers :
374             croak "Expected 'headers' to be either ARRAY or HASH reference";
375             }
376              
377 52 100       241 if( my $more = delete $params{"+headers"} ) {
378 1 50       11 my @more =
    50          
379             ( ref $more eq "ARRAY" ) ? @$more :
380             ( ref $more eq "HASH" ) ? %$more :
381             croak "Expected '+headers' to be either ARRAY or HASH reference";
382 1         4 my %to_remove = @more;
383              
384 1         3 my $headers = $self->{headers};
385 1     1   38 @$headers = ( ( pairgrep { !exists $to_remove{$a} } @$headers ), @more );
  1         8  
386             }
387              
388 52         189 foreach ( grep { m/^SSL_/ } keys %params ) {
  3         21  
389 1         5 $self->{ssl_params}{$_} = delete $params{$_};
390             }
391              
392 52         187 foreach ( grep { m/^SOCKS_/ } keys %params ) {
  2         9  
393 0         0 $self->{socks_params}{$_} = delete $params{$_};
394             }
395              
396 52 50       223 if( exists $params{ip_tos} ) {
397             # TODO: This conversion should live in IO::Async somewhere
398 0         0 my $ip_tos = delete $params{ip_tos};
399 0 0 0     0 $ip_tos = IPTOS_LOWDELAY if defined $ip_tos and $ip_tos eq "lowdelay";
400 0 0 0     0 $ip_tos = IPTOS_THROUGHPUT if defined $ip_tos and $ip_tos eq "throughput";
401 0 0 0     0 $ip_tos = IPTOS_RELIABILITY if defined $ip_tos and $ip_tos eq "reliability";
402 0 0 0     0 $ip_tos = IPTOS_MINCOST if defined $ip_tos and $ip_tos eq "mincost";
403 0         0 $self->{ip_tos} = $ip_tos;
404             }
405              
406 52         430 $self->SUPER::configure( %params );
407              
408 52 100       881 defined $self->{user_agent} or $self->{user_agent} = $DEFAULT_UA;
409 52 100       223 defined $self->{max_redirects} or $self->{max_redirects} = $DEFAULT_MAXREDIR;
410 52 100       237 defined $self->{max_in_flight} or $self->{max_in_flight} = $DEFAULT_MAX_IN_FLIGHT;
411 52 100       295 defined $self->{pipeline} or $self->{pipeline} = 1;
412             }
413              
414             =head1 METHODS
415              
416             The following methods documented in an C expression return L
417             instances.
418              
419             When returning a Future, the following methods all indicate HTTP-level errors
420             using the Future failure name of C. If the error relates to a specific
421             response it will be included. The original request is also included.
422              
423             $f->fail( $message, "http", $response, $request )
424              
425             =cut
426              
427             sub connect_connection
428             {
429 103     103 0 206 my $self = shift;
430 103         587 my %args = @_;
431              
432 103         242 my $conn = delete $args{conn};
433 103 100       492 my $key = defined $args{path} ? "unix:$args{path}" : "$args{host}:$args{port}";
434              
435 103         264 my $on_error = $args{on_error};
436              
437 103 50       396 if( my $socks_params = $self->{socks_params} ) {
438 0         0 require Net::Async::SOCKS;
439 0         0 Net::Async::SOCKS->VERSION( '0.003' );
440              
441 0         0 unshift @{ $args{extensions} }, "SOCKS";
  0         0  
442 0         0 $args{$_} = $socks_params->{$_} for keys %$socks_params;
443             }
444              
445 103 100       382 if( $args{SSL} ) {
446 2         20 require IO::Async::SSL;
447 2         37 IO::Async::SSL->VERSION( '0.12' ); # 0.12 has ->connect(handle) bugfix
448              
449 2         7 unshift @{ $args{extensions} }, "SSL";
  2         10  
450             }
451              
452 103 100       550 if( exists $args{port} ) {
453 102         359 $args{service} = delete $args{port};
454             }
455              
456 103 100       925 unless( exists $args{host} ) {
457 1         5 $args{addr} = { family => $args{family}, path => $args{path} };
458             }
459              
460             my $f = $conn->connect(
461             family => ( $args{family} || $self->{family} || 0 ),
462 412 50       1377 ( map { defined $self->{$_} ? ( $_ => $self->{$_} ) : () }
463             qw( local_host local_port local_addrs local_addr ) ),
464             %args,
465             )->on_done( sub {
466 95     95   2569 my ( $stream ) = @_;
467 95         495 $stream->configure(
468             notifier_name => "$key,fd=" . $stream->read_handle->fileno,
469             );
470              
471             # Defend against ->setsockopt doing silly things like detecting SvPOK()
472 95 50       8560 $stream->read_handle->setsockopt( IPPROTO_IP, IP_TOS, $self->{ip_tos}+0 ) if defined $self->{ip_tos};
473              
474 95         347 $stream->ready;
475             })->on_fail( sub {
476 7     7   26611 $on_error->( $conn, "$key - $_[0] failed [$_[-1]]" );
477 103   50     1032 });
478              
479 103 100   20   44964 $f->on_ready( sub { undef $f } ) unless $f->is_ready; # intentionally cycle
  20         353  
480              
481 103         1831 return $f;
482             }
483              
484             sub get_connection
485             {
486 146     146 0 264 my $self = shift;
487 146         639 my %args = @_;
488              
489 146 50       764 my $loop = $self->get_loop or croak "Cannot ->get_connection without a Loop";
490              
491 146 100       1641 my $key = defined $args{path} ? "unix:$args{path}" : "$args{host}:$args{port}";
492 146   100     839 my $conns = $self->{connections}{$key} ||= [];
493 146   100     1129 my $ready_queue = $self->{ready_queue}{$key} ||= [];
494              
495             # Have a look to see if there are any idle connected ones first
496 146         412 foreach my $conn ( @$conns ) {
497 53 100 100     318 $conn->is_idle and $conn->read_handle and return Future->done( $conn );
498             }
499              
500 132         316 my $ready = $args{ready};
501 132 100       719 $ready or push @$ready_queue, $ready =
502             Ready( $self->loop->new_future->set_label( "[ready $key]" ), 0 );
503              
504 132         59896 my $f = $ready->future;
505              
506 132         885 my $max = $self->{max_connections_per_host};
507 132 100 100     808 if( $max and @$conns >= $max ) {
508 29         287 return $f;
509             }
510              
511             my $conn = Net::Async::HTTP::Connection->new(
512             notifier_name => "$key,connecting",
513             ready_queue => $ready_queue,
514 412         3161 ( map { $_ => $self->{$_} }
515             qw( max_in_flight read_len write_len decode_content ) ),
516             pipeline => ( $self->{pipeline} && !$self->{close_after_request} ),
517             is_proxy => $args{is_proxy},
518              
519             on_closed => sub {
520 69     69   146 my $conn = shift;
521 69         237 my $http = $conn->parent;
522              
523 69         624 $conn->remove_from_parent;
524 69         8810 @$conns = grep { $_ != $conn } @$conns;
  69         283  
525              
526 69 100       1013 if( my $next = first { !$_->connecting } @$ready_queue ) {
  2         52  
527             # Requeue another connection attempt as there's still more to do
528 2         123 $http->get_connection( %args, ready => $next );
529             }
530             },
531 103   100     418 );
532              
533 103         11918 $self->add_child( $conn );
534 103         14551 push @$conns, $conn;
535              
536             $ready->connecting = $self->connect_connection( %args,
537             conn => $conn,
538             on_error => sub {
539 7     7   11 my $conn = shift;
540              
541 7 50       27 $f->fail( @_ ) unless $f->is_cancelled;
542              
543 7         1036 $conn->remove_from_parent;
544 7         988 @$conns = grep { $_ != $conn } @$conns;
  10         32  
545 7         14 @$ready_queue = grep { $_ != $ready } @$ready_queue;
  12         150  
546              
547 7 100       95 if( my $next = first { !$_->connecting } @$ready_queue ) {
  5         167  
548             # Requeue another connection attempt as there's still more to do
549 2         39 $self->get_connection( %args, ready => $next );
550             }
551             },
552             )->on_cancel( sub {
553 1     1   33 $conn->remove_from_parent;
554 1         105 @$conns = grep { $_ != $conn } @$conns;
  2         6  
555 103         1119 });
556              
557 103         6556 return $f;
558             }
559              
560             =head2 do_request
561              
562             $response = await $http->do_request( %args );
563              
564             Send an HTTP request to a server, returning a L that will yield the
565             response. The request may be represented by an L object, or a
566             L object, depending on the arguments passed.
567              
568             The following named arguments are used for Cs:
569              
570             =over 8
571              
572             =item request => HTTP::Request
573              
574             A reference to an C object
575              
576             =item host => STRING
577              
578             Hostname of the server to connect to
579              
580             =item port => INT or STRING
581              
582             Optional. Port number or service of the server to connect to. If not defined,
583             will default to C or C depending on whether SSL is being used.
584              
585             =item family => INT or STRING
586              
587             Optional. Restricts the socket family for connecting. If not defined, will
588             default to the globally-configured value in the object. The value may either
589             be a C constant directly, or the lowercase name of one such as C.
590              
591             =item SSL => BOOL
592              
593             Optional. If true, an SSL connection will be used.
594              
595             =back
596              
597             The following named arguments are used for C requests:
598              
599             =over 8
600              
601             =item uri => URI or STRING
602              
603             A reference to a C object, or a plain string giving the request URI. If
604             the scheme is C then an SSL connection will be used.
605              
606             =item method => STRING
607              
608             Optional. The HTTP method name. If missing, C is used.
609              
610             =item content => STRING or ARRAY ref
611              
612             Optional. The body content to use for C or C requests.
613              
614             If this is a plain scalar it will be used directly, and a C
615             field must also be supplied to describe it.
616              
617             If this is an ARRAY ref and the request method is C, it will be form
618             encoded. It should contain an even-sized list of field names and values. For
619             more detail see L.
620              
621             =item content_type => STRING
622              
623             The type of non-form data C.
624              
625             =item user => STRING
626              
627             =item pass => STRING
628              
629             Optional. If both are given, the HTTP Basic Authorization header will be sent
630             with these details.
631              
632             =item headers => ARRAY|HASH
633              
634             Optional. If provided, contains additional HTTP headers to set on the
635             constructed request object. If provided as an ARRAY reference, it should
636             contain an even-sized list of name/value pairs.
637              
638             =item proxy_host => STRING
639              
640             =item proxy_port => INT
641              
642             I
643              
644             Optional. Override the hostname or port number implied by the URI.
645              
646             =item proxy_path => PATH
647              
648             I
649              
650             Optional. Set a UNIX socket path to use as a proxy. To make use of this, also
651             set the C argument to C.
652              
653             =back
654              
655             For either request type, it takes the following arguments:
656              
657             =over 8
658              
659             =item request_body => STRING | CODE | Future
660              
661             Optional. Allows request body content to be generated by a future or
662             callback, rather than being provided as part of the C object. This
663             can either be a plain string, a C reference to a generator function, or
664             a future.
665              
666             As this is passed to the underlying L C method, the
667             usual semantics apply here. If passed a C reference, it will be called
668             repeatedly whenever it's safe to write. The code should should return C
669             to indicate completion. If passed a C it is expected to eventually
670             yield the body value.
671              
672             As with the C parameter, the C field should be
673             specified explicitly in the request header, as should the content length
674             (typically via the L C method). See also
675             F.
676              
677             =item expect_continue => BOOL
678              
679             Optional. If true, sets the C request header to the value
680             C<100-continue> and does not send the C parameter until a
681             C<100 Continue> response is received from the server. If an error response is
682             received then the C code, if present, will not be invoked.
683              
684             =item on_ready => CODE
685              
686             Optional. A callback that is invoked once a socket connection is established
687             with the HTTP server, but before the request is actually sent over it. This
688             may be used by the client code to inspect the socket, or perform any other
689             operations on it. This code is expected to return a C; only once that
690             has completed will the request cycle continue. If it fails, that failure is
691             propagated to the caller.
692              
693             $f = $on_ready->( $connection );
694              
695             =item on_redirect => CODE
696              
697             Optional. A callback that is invoked if a redirect response is received,
698             before the new location is fetched. It will be passed the response and the new
699             URL.
700              
701             $on_redirect->( $response, $location );
702              
703             =item on_body_write => CODE
704              
705             Optional. A callback that is invoked after each successful C of the
706             body content. This may be used to implement an upload progress indicator or
707             similar. It will be passed the total number of bytes of body content written
708             so far (i.e. excluding bytes consumed in the header).
709              
710             $on_body_write->( $written );
711              
712             =item max_redirects => INT
713              
714             Optional. How many levels of redirection to follow. If not supplied, will
715             default to the value given in the constructor.
716              
717             =item timeout => NUM
718              
719             =item stall_timeout => NUM
720              
721             Optional. Overrides the object's configured timeout values for this one
722             request. If not specified, will use the configured defaults.
723              
724             On a timeout, the returned future will fail with either C or
725             C as the operation name.
726              
727             ( $message, "timeout" ) = $f->failure;
728              
729             =back
730              
731             =head2 do_request (void)
732              
733             $http->do_request( %args );
734              
735             When not returning a future, the following extra arguments are used as
736             callbacks instead:
737              
738             =over 8
739              
740             =item on_response => CODE
741              
742             A callback that is invoked when a response to this request has been received.
743             It will be passed an L object containing the response the
744             server sent.
745              
746             $on_response->( $response );
747              
748             =item on_header => CODE
749              
750             Alternative to C. A callback that is invoked when the header of a
751             response has been received. It is expected to return a C reference for
752             handling chunks of body content. This C reference will be invoked with
753             no arguments once the end of the request has been reached, and whatever it
754             returns will be used as the result of the returned C, if there is one.
755              
756             $on_body_chunk = $on_header->( $header );
757              
758             $on_body_chunk->( $data );
759             $response = $on_body_chunk->();
760              
761             =item on_error => CODE
762              
763             A callback that is invoked if an error occurs while trying to send the request
764             or obtain the response. It will be passed an error message.
765              
766             $on_error->( $message );
767              
768             If this is invoked because of a received C<4xx> or C<5xx> error code in an
769             HTTP response, it will be invoked with the response and request objects as
770             well.
771              
772             $on_error->( $message, $response, $request );
773              
774             =back
775              
776             =cut
777              
778             sub _do_one_request
779             {
780 144     144   1931 my $self = shift;
781 144         1154 my %args = @_;
782              
783 144         389 my $host = delete $args{host};
784 144         317 my $port = delete $args{port};
785 144         339 my $request = delete $args{request};
786 144         346 my $SSL = delete $args{SSL};
787              
788 144         591 my $start_time = time;
789 144   66     850 my $stall_timeout = $args{stall_timeout} // $self->{stall_timeout};
790              
791 144         688 $self->prepare_request( $request );
792              
793 144 100 100     1615 if( $self->{require_SSL} and not $SSL ) {
794 2         19 return Future->fail( "Non-SSL request is not allowed with 'require_SSL' set",
795             http => undef, $request );
796             }
797              
798 142 100       673 if( $metrics ) {
799 36         663 $metrics->inc_gauge( requests_in_flight => );
800 36         4457 $metrics->inc_counter( requests => [ method => $request->method ] );
801             }
802              
803 142         3454 my %conn_target;
804             my $is_proxy;
805              
806 142 100 66     1542 if( defined $args{proxy_host} or ( defined $self->{proxy_host} and not defined $args{proxy_path} ) ) {
    100 66        
      66        
807             %conn_target = (
808             host => $args{proxy_host} || $self->{proxy_host},
809             port => $args{proxy_port} || $self->{proxy_port},
810 1   33     9 );
      33        
811 1         2 $is_proxy = 1;
812             }
813             elsif( defined $args{proxy_path} or defined $self->{proxy_path} ) {
814             %conn_target = (
815             path => $args{proxy_path} || $self->{proxy_path},
816 1   33     8 );
817 1         3 $is_proxy = 1;
818             }
819             else {
820 140         592 %conn_target = (
821             host => $host,
822             port => $port,
823             );
824             }
825              
826             return $self->get_connection(
827             %conn_target,
828             is_proxy => $is_proxy,
829             ( defined $args{family} ? ( family => $args{family} ) : () ),
830             $SSL ? (
831             SSL => 1,
832             SSL_hostname => $host,
833 4         18 %{ $self->{ssl_params} },
834 7 100       41 ( map { m/^SSL_/ ? ( $_ => $args{$_} ) : () } keys %args ),
835             ) : (),
836             )->then( sub {
837 134     134   10497 my ( $conn ) = @_;
838 134 100       829 $args{on_ready} ? $args{on_ready}->( $conn )->then_done( $conn )
839             : Future->done( $conn )
840             })->then( sub {
841 134     134   13937 my ( $conn ) = @_;
842              
843             return $conn->request(
844             request => $request,
845             stall_timeout => $stall_timeout,
846             %args,
847             $SSL ? ( SSL => 1 ) : (),
848             on_done => sub {
849 120         4021 my ( $ctx ) = @_;
850              
851 120 100       584 if( $metrics ) {
852 1         13 $metrics->dec_gauge( requests_in_flight => );
853             # TODO: Some sort of error counter instead for errors?
854 1         48 $metrics->inc_counter( responses => [ method => $request->method, code => $ctx->resp_header->code ] );
855 1         114 $metrics->report_timer( request_duration => time - $start_time );
856 1         68 $metrics->report_distribution( response_bytes => $ctx->resp_bytes );
857             }
858             },
859 134 100       1556 );
860 142 100       999 } );
    100          
861             }
862              
863             sub _should_redirect
864             {
865 120     120   341 my ( $response ) = @_;
866              
867             # Should only redirect if we actually have a Location header
868 120 100 100     468 return 0 unless $response->is_redirect and defined $response->header( "Location" );
869              
870 11         748 my $req_method = $response->request->method;
871             # Should only redirect GET or HEAD requests
872 11   66     327 return $req_method eq "GET" || $req_method eq "HEAD";
873             }
874              
875             sub _do_request
876             {
877 135     135   290 my $self = shift;
878 135         535 my %args = @_;
879              
880 135         307 my $host = $args{host};
881 135         270 my $port = $args{port};
882 135         292 my $ssl = $args{SSL};
883              
884 135         286 my $on_header = delete $args{on_header};
885              
886 135 100       444 my $redirects = defined $args{max_redirects} ? $args{max_redirects} : $self->{max_redirects};
887              
888 135         259 my $request = $args{request};
889 135         233 my $response;
890             my $reqf;
891             # Defeat prototype
892             my $future = &repeat( $self->_capture_weakself( sub {
893 144     144   9350 my $self = shift;
894 144         344 my ( $previous_f ) = @_;
895              
896 144 100       431 if( $previous_f ) {
897 9         98 my $previous_response = $previous_f->get;
898 9         171 $args{previous_response} = $previous_response;
899              
900 9         32 my $location = $previous_response->header( "Location" );
901              
902 9 100       502 if( $location =~ m{^http(?:s?)://} ) {
    50          
903             # skip
904             }
905             elsif( $location =~ m{^/} ) {
906 3 50       12 my $hostport = ( $port != HTTP_PORT ) ? "$host:$port" : $host;
907 3         11 $location = "http://$hostport" . $location;
908             }
909             else {
910 0         0 return Future->fail( "Unrecognised Location: $location", http => $previous_response, $request );
911             }
912              
913 9         1991 my $loc_uri = URI->new( $location );
914 9 50       6795 unless( $loc_uri ) {
915 0         0 return Future->fail( "Unable to parse '$location' as a URI", http => $previous_response, $request );
916             }
917              
918 9         134 $self->debug_printf( "REDIRECT $loc_uri" );
919              
920 9 100       147 $args{on_redirect}->( $previous_response, $location ) if $args{on_redirect};
921              
922 9         65 %args = $self->_make_request_for_uri( $loc_uri, %args );
923 9         32 $request = $args{request};
924              
925 9         17 undef $host; undef $port; undef $ssl;
  9         19  
  9         58  
926             }
927              
928 144         630 my $uri = $request->uri;
929 144 100 66     1522 if( defined $uri->scheme and $uri->scheme =~ m/^http(s?)$/ ) {
930 103 100       5709 $host = $uri->host if !defined $host;
931 103 100       693 $port = $uri->port if !defined $port;
932 103         793 $ssl = ( $uri->scheme eq "https" );
933             }
934              
935 144 50       3131 defined $host or croak "Expected 'host'";
936 144 50       515 defined $port or $port = ( $ssl ? HTTPS_PORT : HTTP_PORT );
    100          
937              
938             return $reqf = $self->_do_one_request(
939             host => $host,
940             port => $port,
941             SSL => $ssl,
942             %args,
943             on_header => $self->_capture_weakself( sub {
944 122         1334 my $self = shift;
945 122         326 ( $response ) = @_;
946              
947             # Consume and discard the entire body of a redirect
948             return sub {
949 11 50       30 return if @_;
950 11         29 return $response;
951 122 100 100     682 } if $redirects and $response->is_redirect;
952              
953 111         1445 return $on_header->( $response );
954 144         1338 } ),
955             );
956             } ),
957             while => sub {
958 137     137   15265 my $f = shift;
959 137 100 66     772 return 0 if $f->failure or $f->is_cancelled;
960 120   100     5199 return _should_redirect( $response ) && $redirects--;
961 135         1746 } );
962              
963 135 100       27178 if( $self->{fail_on_error} ) {
964             $future = $future->then_with_f( sub {
965 3     3   194 my ( $f, $resp ) = @_;
966 3         18 my $code = $resp->code;
967              
968 3 100       30 if( $code =~ m/^[45]/ ) {
969 2         5 my $message = $resp->message;
970 2         15 $message =~ s/\r$//; # HTTP::Message bug
971              
972 2         10 return Future->fail( "$code $message", http => $resp, $request );
973             }
974              
975 1         2 return $f;
976 3         15 });
977             }
978              
979 135         2385 return $future;
980             }
981              
982             sub do_request
983             {
984 135     135 1 739045 my $self = shift;
985 135         875 my %args = @_;
986              
987 135 100       1998 if( my $uri = delete $args{uri} ) {
    50          
988 87         1189 %args = $self->_make_request_for_uri( $uri, %args );
989             }
990             elsif( !defined $args{request} ) {
991 0         0 croak "Require either 'uri' or 'request' argument";
992             }
993              
994 135 100 66     928 if( $args{on_header} ) {
    50          
995             # ok
996             }
997             elsif( $args{on_response} or defined wantarray ) {
998             $args{on_header} = sub {
999 106     106   262 my ( $response ) = @_;
1000             return sub {
1001 182 100       502 if( @_ ) {
1002 78         524 $response->add_content( @_ );
1003             }
1004             else {
1005 104         286 return $response;
1006             }
1007 106         701 };
1008             }
1009 130         912 }
1010             else {
1011 0         0 croak "Expected 'on_response' or 'on_header' as CODE ref or to return a Future";
1012             }
1013              
1014 135         452 my $on_error = delete $args{on_error};
1015 135 100       455 my $timeout = defined $args{timeout} ? $args{timeout} : $self->{timeout};
1016              
1017 135         695 my $future = $self->_do_request( %args );
1018              
1019 135 100       515 if( defined $timeout ) {
1020             $future = Future->wait_any(
1021             $future,
1022             $self->loop->timeout_future( after => $timeout )
1023 34     4   167 ->transform( fail => sub { "Timed out", timeout => } ),
  4         491304  
1024             );
1025             }
1026              
1027             $future->on_done( $self->_capture_weakself( sub {
1028 109     109   16260 my $self = shift;
1029 109         218 my $response = shift;
1030 109         507 $self->process_response( $response );
1031 135         27110 } ) );
1032              
1033             $future->on_fail( sub {
1034 8     8   1851 my ( $message, $name, @rest ) = @_;
1035 8         36 $on_error->( $message, @rest );
1036 135 100       5224 }) if $on_error;
1037              
1038 135 100       2162 if( my $on_response = delete $args{on_response} ) {
1039             $future->on_done( sub {
1040 72     72   2526 my ( $response ) = @_;
1041 72         290 $on_response->( $response );
1042 79         456 });
1043             }
1044              
1045             # DODGY HACK:
1046             # In void context we'll lose reference on the ->wait_any Future, so the
1047             # timeout logic will never happen. So lets purposely create a cycle by
1048             # capturing the $future in on_done/on_fail closures within itself. This
1049             # conveniently clears them out to drop the ref when done.
1050 135 100       2254 return $future if defined wantarray;
1051              
1052 52     52   326 $future->on_ready( sub { undef $future } );
  52         12360  
1053             }
1054              
1055             sub _make_request_for_uri
1056             {
1057 96     96   196 my $self = shift;
1058 96         379 my ( $uri, %args ) = @_;
1059              
1060 96 100 33     1046 if( !ref $uri ) {
    50          
1061 17         129 $uri = URI->new( $uri );
1062             }
1063             elsif( blessed $uri and !$uri->isa( "URI" ) ) {
1064 0         0 croak "Expected 'uri' as a URI reference";
1065             }
1066              
1067 96   100     56465 my $method = delete $args{method} || "GET";
1068              
1069 96         471 $args{host} = $uri->host;
1070 96         6019 $args{port} = $uri->port;
1071              
1072 96         3453 my $request;
1073              
1074 96 100       325 if( $method eq "POST" ) {
1075 2 50       10 defined $args{content} or croak "Expected 'content' with POST method";
1076              
1077             # Lack of content_type didn't used to be a failure condition:
1078             ref $args{content} or defined $args{content_type} or
1079 2 50 66     14 carp "No 'content_type' was given with 'content'";
1080              
1081             # This will automatically encode a form for us
1082 2         12 $request = HTTP::Request::Common::POST( $uri, Content => $args{content}, Content_Type => $args{content_type} );
1083             }
1084             else {
1085 94         840 $request = HTTP::Request->new( $method, $uri );
1086 94 100       9473 if( defined $args{content} ) {
1087 3 50       13 defined $args{content_type} or carp "No 'content_type' was given with 'content'";
1088              
1089 3         16 $request->content( $args{content} );
1090 3   50     125 $request->content_type( $args{content_type} // "" );
1091             }
1092             }
1093              
1094 96         1947 $request->protocol( "HTTP/1.1" );
1095 96 100       1409 if( $args{port} != $uri->default_port ) {
1096 22         219 $request->header( Host => "$args{host}:$args{port}" );
1097             }
1098             else {
1099 74         578 $request->header( Host => "$args{host}" );
1100             }
1101              
1102 96         6734 my $headers = $args{headers};
1103 96 100 100     768 if( $headers and reftype $headers eq "ARRAY" ) {
    100 66        
1104 1         26 $request->header( @$_ ) for pairs @$headers;
1105             }
1106             elsif( $headers and reftype $headers eq "HASH" ) {
1107 1         9 $request->header( $_, $headers->{$_} ) for keys %$headers;
1108             }
1109              
1110 96         491 my ( $user, $pass );
1111              
1112 96 100 66     461 if( defined $uri->userinfo ) {
    100          
1113 1         29 ( $user, $pass ) = split( m/:/, $uri->userinfo, 2 );
1114             }
1115             elsif( defined $args{user} and defined $args{pass} ) {
1116 1         33 $user = $args{user};
1117 1         2 $pass = $args{pass};
1118             }
1119              
1120 96 100 66     2655 if( defined $user and defined $pass ) {
1121 2         21 $request->authorization_basic( $user, $pass );
1122             }
1123              
1124 96         2328 $args{request} = $request;
1125              
1126 96         1081 return %args;
1127             }
1128              
1129             =head2 GET, HEAD, PUT, ...
1130              
1131             $response = await $http->GET( $uri, %args );
1132              
1133             $response = await $http->HEAD( $uri, %args );
1134              
1135             $response = await $http->PUT( $uri, $content, %args );
1136              
1137             $response = await $http->POST( $uri, $content, %args );
1138              
1139             I
1140              
1141             $response = await $http->PATCH( $uri, $content, %args );
1142              
1143             I
1144              
1145             $response = await $http->DELETE( $uri, %args );
1146              
1147             I
1148              
1149             Convenient wrappers for performing C, C, C, C, C
1150             or C requests with a C object and few if any other arguments,
1151             returning a C.
1152              
1153             Remember that C with non-form data (as indicated by a plain scalar
1154             instead of an C reference of form data name/value pairs) needs a
1155             C key in C<%args>.
1156              
1157             =cut
1158              
1159             sub GET
1160             {
1161 10     10 1 6618 my $self = shift;
1162 10         28 my ( $uri, @args ) = @_;
1163 10         42 return $self->do_request( method => "GET", uri => $uri, @args );
1164             }
1165              
1166             sub HEAD
1167             {
1168 0     0 1 0 my $self = shift;
1169 0         0 my ( $uri, @args ) = @_;
1170 0         0 return $self->do_request( method => "HEAD", uri => $uri, @args );
1171             }
1172              
1173             sub PUT
1174             {
1175 0     0 1 0 my $self = shift;
1176 0         0 my ( $uri, $content, @args ) = @_;
1177 0         0 return $self->do_request( method => "PUT", uri => $uri, content => $content, @args );
1178             }
1179              
1180             sub POST
1181             {
1182 0     0 0 0 my $self = shift;
1183 0         0 my ( $uri, $content, @args ) = @_;
1184 0         0 return $self->do_request( method => "POST", uri => $uri, content => $content, @args );
1185             }
1186              
1187             sub PATCH
1188             {
1189 0     0 0 0 my $self = shift;
1190 0         0 my ( $uri, $content, @args ) = @_;
1191 0         0 return $self->do_request( method => "PATCH", uri => $uri, content => $content, @args );
1192             }
1193              
1194             sub DELETE
1195             {
1196 0     0   0 my $self = shift;
1197 0         0 my ( $uri, @args ) = @_;
1198 0         0 return $self->do_request( method => "DELETE", uri => $uri, @args );
1199             }
1200              
1201             =head1 SUBCLASS METHODS
1202              
1203             The following methods are intended as points for subclasses to override, to
1204             add extra functionallity.
1205              
1206             =cut
1207              
1208             =head2 prepare_request
1209              
1210             $http->prepare_request( $request );
1211              
1212             Called just before the C object is sent to the server.
1213              
1214             =cut
1215              
1216             sub prepare_request
1217             {
1218 144     144 1 306 my $self = shift;
1219 144         360 my ( $request ) = @_;
1220              
1221 144 100       836 $request->init_header( 'User-Agent' => $self->{user_agent} ) if length $self->{user_agent};
1222 144 100       3113 if( $self->{close_after_request} ) {
1223 1         6 $request->header( "Connection" => "close" );
1224             }
1225             else {
1226 143         1000 $request->init_header( "Connection" => "keep-alive" );
1227             }
1228              
1229 144         8659 foreach ( pairs @{ $self->{headers} } ) {
  144         1463  
1230 3         91 $request->init_header( $_->key, $_->value );
1231             }
1232              
1233 144 100       745 $self->{cookie_jar}->add_cookie_header( $request ) if $self->{cookie_jar};
1234             }
1235              
1236             =head2 process_response
1237              
1238             $http->process_response( $response );
1239              
1240             Called after a non-redirect C has been received from a server.
1241             The originating request will be set in the object.
1242              
1243             =cut
1244              
1245             sub process_response
1246             {
1247 109     109 1 237 my $self = shift;
1248 109         237 my ( $response ) = @_;
1249              
1250 109 100       714 $self->{cookie_jar}->extract_cookies( $response ) if $self->{cookie_jar};
1251             }
1252              
1253             =head1 CONTENT DECODING
1254              
1255             If the required decompression modules are installed and available, compressed
1256             content can be decoded. If the received C is recognised and
1257             the required module is available, the content is transparently decoded and the
1258             decoded content is returned in the resulting response object, or passed to the
1259             data chunk handler. In this case, the original C header will
1260             be deleted from the response, and its value will be available instead as
1261             C.
1262              
1263             The following content encoding types are recognised by these modules:
1264              
1265             =over 4
1266              
1267             =cut
1268              
1269             =item * gzip (q=0.7) and deflate (q=0.5)
1270              
1271             Recognised if L version 2.057 or newer is installed.
1272              
1273             =cut
1274              
1275             if( eval { require Compress::Raw::Zlib and $Compress::Raw::Zlib::VERSION >= 2.057 } ) {
1276             my $make_zlib_decoder = sub {
1277             my ( $bits ) = @_;
1278             my $inflator = Compress::Raw::Zlib::Inflate->new(
1279             -ConsumeInput => 0,
1280             -WindowBits => $bits,
1281             );
1282             sub {
1283             my $output;
1284             my $status = @_ ? $inflator->inflate( $_[0], $output )
1285             : $inflator->inflate( "", $output, 1 );
1286             die "$status\n" if $status && $status != Compress::Raw::Zlib::Z_STREAM_END();
1287             return $output;
1288             };
1289             };
1290              
1291             # RFC1950
1292             __PACKAGE__->register_decoder(
1293             deflate => 0.5, sub { $make_zlib_decoder->( 15 ) },
1294             );
1295              
1296             # RFC1952
1297             __PACKAGE__->register_decoder(
1298             gzip => 0.7, sub { $make_zlib_decoder->( Compress::Raw::Zlib::WANT_GZIP() ) },
1299             );
1300             }
1301              
1302             =item * bzip2 (q=0.8)
1303              
1304             Recognised if L version 2.10 or newer is installed.
1305              
1306             =cut
1307              
1308             if( eval { require Compress::Bzip2 and $Compress::Bzip2::VERSION >= 2.10 } ) {
1309             __PACKAGE__->register_decoder(
1310             bzip2 => 0.8, sub {
1311             my $inflator = Compress::Bzip2::inflateInit();
1312             sub {
1313             return unless my ( $in ) = @_;
1314             my $out = $inflator->bzinflate( \$in );
1315             die $inflator->bzerror."\n" if !defined $out;
1316             return $out;
1317             };
1318             }
1319             );
1320             }
1321              
1322             =back
1323              
1324             Other content encoding types can be registered by calling the following method
1325              
1326             =head2 register_decoder
1327              
1328             Net::Async::HTTP->register_decoder( $name, $q, $make_decoder )
1329              
1330             Registers an encoding type called C<$name>, at the quality value C<$q>. In
1331             order to decode this encoding type, C<$make_decoder> will be invoked with no
1332             paramters, and expected to return a CODE reference to perform one instance of
1333             decoding.
1334              
1335             $decoder = $make_decoder->()
1336              
1337             This decoder will be invoked on string buffers to decode them until
1338             the end of stream is reached, when it will be invoked with no arguments.
1339              
1340             $content = $decoder->( $encoded_content )
1341             $content = $decoder->() # EOS
1342              
1343             =cut
1344              
1345             {
1346             my %DECODERS; # {$name} = [$q, $make_decoder]
1347              
1348             sub register_decoder
1349             {
1350 76     76 1 180 shift;
1351 76         208 my ( $name, $q, $make_decoder ) = @_;
1352              
1353 76         251 $DECODERS{$name} = [ $q, $make_decoder ];
1354             }
1355              
1356             sub can_decode
1357             {
1358 2     2 0 2 shift;
1359 2 50       5 if( @_ ) {
1360 2         3 my ( $name ) = @_;
1361              
1362 2 50       5 return unless my $d = $DECODERS{$name};
1363 2         6 return $d->[1]->();
1364             }
1365             else {
1366 0           my @ds = sort { $DECODERS{$b}[0] <=> $DECODERS{$a}[0] } keys %DECODERS;
  0            
1367 0           return join ", ", map { "$_;q=$DECODERS{$_}[0]" } @ds;
  0            
1368             }
1369             }
1370             }
1371              
1372             =head1 EXAMPLES
1373              
1374             =head2 Concurrent GET
1375              
1376             The C-returning C method makes it easy to await multiple URLs at
1377             once, by using the L C utility
1378              
1379             use Future::AsyncAwait;
1380             use Future::Utils qw( fmap_void );
1381              
1382             my @URLs = ( ... );
1383              
1384             my $http = Net::Async::HTTP->new( ... );
1385             $loop->add( $http );
1386              
1387             my $future = fmap_void {
1388             my ( $url ) = @_;
1389             $http->GET( $url )
1390             ->on_done( sub {
1391             my $response = shift;
1392             say "$url succeeded: ", $response->code;
1393             say " Content-Type:", $response->content_type;
1394             } )
1395             ->on_fail( sub {
1396             my $failure = shift;
1397             say "$url failed: $failure";
1398             } );
1399             } foreach => \@URLs,
1400             concurrent => 5;
1401              
1402             await $future;
1403              
1404             =cut
1405              
1406             =head1 SEE ALSO
1407              
1408             =over 4
1409              
1410             =item *
1411              
1412             L - Hypertext Transfer Protocol -- HTTP/1.1
1413              
1414             =back
1415              
1416             =head1 SPONSORS
1417              
1418             Parts of this code, or bugfixes to it were paid for by
1419              
1420             =over 2
1421              
1422             =item *
1423              
1424             SocialFlow L
1425              
1426             =item *
1427              
1428             Shadowcat Systems L
1429              
1430             =item *
1431              
1432             NET-A-PORTER L
1433              
1434             =item *
1435              
1436             Cisco L
1437              
1438             =back
1439              
1440             =head1 AUTHOR
1441              
1442             Paul Evans
1443              
1444             =cut
1445              
1446             0x55AA;