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