1 # vim: ts=4 sts=4 sw=4 et:
5 # ABSTRACT: A small, simple, correct HTTP/1.1 client
6 our $VERSION = '0.049'; # VERSION
12 #pod $http = HTTP::Tiny->new( %attributes );
14 #pod This constructor returns a new HTTP::Tiny object. Valid attributes include:
18 #pod A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> — ends in a space character, the default user-agent string is appended.
19 #pod * C<cookie_jar> —
20 #pod An instance of L<HTTP::CookieJar> — or equivalent class that supports the C<add> and C<cookie_header> methods
21 #pod * C<default_headers> —
22 #pod A hashref of default headers to apply to requests
23 #pod * C<local_address> —
24 #pod The local IP address to bind to
25 #pod * C<keep_alive> —
26 #pod Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
27 #pod * C<max_redirect> —
28 #pod Maximum number of redirects allowed (defaults to 5)
30 #pod Maximum response size (only when not using a data callback). If defined, responses larger than this will return an exception.
31 #pod * C<http_proxy> —
32 #pod URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> — if set)
33 #pod * C<https_proxy> —
34 #pod URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> — if set)
36 #pod URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> — if set)
38 #pod List of domain suffixes that should not be proxied. Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> —)
40 #pod Request timeout in seconds (default is 60)
41 #pod * C<verify_SSL> —
42 #pod A boolean that indicates whether to validate the SSL certificate of an C<https> —
43 #pod connection (default is false)
44 #pod * C<SSL_options> —
45 #pod A hashref of C<SSL_*> — options to pass through to L<IO::Socket::SSL>
47 #pod Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
48 #pod prevent getting the corresponding proxies from the environment.
50 #pod Exceptions from C<max_size>, C<timeout> or other errors will result in a
51 #pod pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
52 #pod content field in the response will contain the text of the exception.
54 #pod The C<keep_alive> parameter enables a persistent connection, but only to a
55 #pod single destination scheme, host and port. Also, if any connection-relevant
56 #pod attributes are modified, or if the process ID or thread ID change, the
57 #pod persistent connection will be dropped. If you want persistent connections
58 #pod across multiple destinations, use multiple HTTP::Tiny objects.
60 #pod See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
67 cookie_jar default_headers http_proxy https_proxy keep_alive
68 local_address max_redirect max_size proxy no_proxy timeout
69 SSL_options verify_SSL
71 my %persist_ok = map {; $_ => 1 } qw(
72 cookie_jar default_headers max_redirect max_size
75 no warnings 'uninitialized';
76 for my $accessor ( @attributes ) {
80 delete $_[0]->{handle} if !$persist_ok{$accessor} && $_[1] ne $_[0]->{$accessor};
81 $_[0]->{$accessor} = $_[1]
89 my($self, $agent) = @_;
92 (defined $agent && $agent =~ / $/) ? $agent . $self->_agent : $agent;
94 return $self->{agent};
98 my($class, %args) = @_;
104 verify_SSL => $args{verify_SSL} || $args{verify_ssl} || 0, # no verification by default
105 no_proxy => $ENV{no_proxy},
110 $class->_validate_cookie_jar( $args{cookie_jar} ) if $args{cookie_jar};
112 for my $key ( @attributes ) {
113 $self->{$key} = $args{$key} if exists $args{$key}
116 $self->agent( exists $args{agent} ? $args{agent} : $class->_agent );
126 # get proxies from %ENV only if not provided; explicit undef will disable
127 # getting proxies from the environment
130 if (! exists $self->{proxy} ) {
131 $self->{proxy} = $ENV{all_proxy} || $ENV{ALL_PROXY};
134 if ( defined $self->{proxy} ) {
135 $self->_split_proxy( 'generic proxy' => $self->{proxy} ); # validate
138 delete $self->{proxy};
142 if (! exists $self->{http_proxy} ) {
143 $self->{http_proxy} = $ENV{http_proxy} || $self->{proxy};
146 if ( defined $self->{http_proxy} ) {
147 $self->_split_proxy( http_proxy => $self->{http_proxy} ); # validate
148 $self->{_has_proxy}{http} = 1;
151 delete $self->{http_proxy};
155 if (! exists $self->{https_proxy} ) {
156 $self->{https_proxy} = $ENV{https_proxy} || $ENV{HTTPS_PROXY} || $self->{proxy};
159 if ( $self->{https_proxy} ) {
160 $self->_split_proxy( https_proxy => $self->{https_proxy} ); # validate
161 $self->{_has_proxy}{https} = 1;
164 delete $self->{https_proxy};
167 # Split no_proxy to array reference if not provided as such
168 unless ( ref $self->{no_proxy} eq 'ARRAY' ) {
170 (defined $self->{no_proxy}) ? [ split /\s*,\s*/, $self->{no_proxy} ] : [];
176 #pod =method get|head|put|post|delete
178 #pod $response = $http->get($url);
179 #pod $response = $http->get($url, \%options);
180 #pod $response = $http->head($url);
182 #pod These methods are shorthand for calling C<request()> for the given method. The
183 #pod URL must have unsafe characters escaped and international domain names encoded.
184 #pod See C<request()> for valid options and a description of the response.
186 #pod The C<success> field of the response will be true if the status code is 2XX.
190 for my $sub_name ( qw/get head put post delete/ ) {
191 my $req_method = uc $sub_name;
193 eval <<"HERE"; ## no critic
195 my (\$self, \$url, \$args) = \@_;
196 \@_ == 2 || (\@_ == 3 && ref \$args eq 'HASH')
197 or Carp::croak(q/Usage: \$http->$sub_name(URL, [HASHREF])/ . "\n");
198 return \$self->request('$req_method', \$url, \$args || {});
203 #pod =method post_form
205 #pod $response = $http->post_form($url, $form_data);
206 #pod $response = $http->post_form($url, $form_data, \%options);
208 #pod This method executes a C<POST> request and sends the key/value pairs from a
209 #pod form data hash or array reference to the given URL with a C<content-type> of
210 #pod C<application/x-www-form-urlencoded>. If data is provided as an array
211 #pod reference, the order is preserved; if provided as a hash reference, the terms
212 #pod are sorted on key and value for consistency. See documentation for the
213 #pod C<www_form_urlencode> method for details on the encoding.
215 #pod The URL must have unsafe characters escaped and international domain names
216 #pod encoded. See C<request()> for valid options and a description of the response.
217 #pod Any C<content-type> header or content in the options hashref will be ignored.
219 #pod The C<success> field of the response will be true if the status code is 2XX.
224 my ($self, $url, $data, $args) = @_;
225 (@_ == 3 || @_ == 4 && ref $args eq 'HASH')
226 or Carp::croak(q/Usage: $http->post_form(URL, DATAREF, [HASHREF])/ . "\n");
229 while ( my ($key, $value) = each %{$args->{headers} || {}} ) {
230 $headers->{lc $key} = $value;
232 delete $args->{headers};
234 return $self->request('POST', $url, {
236 content => $self->www_form_urlencode($data),
239 'content-type' => 'application/x-www-form-urlencoded'
247 #pod $response = $http->mirror($url, $file, \%options)
248 #pod if ( $response->{success} ) {
249 #pod print "$file is up to date\n";
252 #pod Executes a C<GET> request for the URL and saves the response body to the file
253 #pod name provided. The URL must have unsafe characters escaped and international
254 #pod domain names encoded. If the file already exists, the request will include an
255 #pod C<If-Modified-Since> header with the modification timestamp of the file. You
256 #pod may specify a different C<If-Modified-Since> header yourself in the C<<
257 #pod $options->{headers} >> hash.
259 #pod The C<success> field of the response will be true if the status code is 2XX
260 #pod or if the status code is 304 (unmodified).
262 #pod If the file was modified and the server response includes a properly
263 #pod formatted C<Last-Modified> header, the file modification time will
264 #pod be updated accordingly.
269 my ($self, $url, $file, $args) = @_;
270 @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
271 or Carp::croak(q/Usage: $http->mirror(URL, FILE, [HASHREF])/ . "\n");
272 if ( -e $file and my $mtime = (stat($file))[9] ) {
273 $args->{headers}{'if-modified-since'} ||= $self->_http_date($mtime);
275 my $tempfile = $file . int(rand(2**31));
278 sysopen my $fh, $tempfile, Fcntl::O_CREAT()|Fcntl::O_EXCL()|Fcntl::O_WRONLY()
279 or Carp::croak(qq/Error: Could not create temporary file $tempfile for downloading: $!\n/);
281 $args->{data_callback} = sub { print {$fh} $_[0] };
282 my $response = $self->request('GET', $url, $args);
284 or Carp::croak(qq/Error: Caught error closing temporary file $tempfile: $!\n/);
286 if ( $response->{success} ) {
287 rename $tempfile, $file
288 or Carp::croak(qq/Error replacing $file with $tempfile: $!\n/);
289 my $lm = $response->{headers}{'last-modified'};
290 if ( $lm and my $mtime = $self->_parse_http_date($lm) ) {
291 utime $mtime, $mtime, $file;
294 $response->{success} ||= $response->{status} eq '304';
301 #pod $response = $http->request($method, $url);
302 #pod $response = $http->request($method, $url, \%options);
304 #pod Executes an HTTP request of the given method type ('GET', 'HEAD', 'POST',
305 #pod 'PUT', etc.) on the given URL. The URL must have unsafe characters escaped and
306 #pod international domain names encoded.
308 #pod If the URL includes a "user:password" stanza, they will be used for Basic-style
309 #pod authorization headers. (Authorization headers will not be included in a
310 #pod redirected request.) For example:
312 #pod $http->request('GET', 'http://Aladdin:open sesame@example.com/');
314 #pod If the "user:password" stanza contains reserved characters, they must
315 #pod be percent-escaped:
317 #pod $http->request('GET', 'http://john%40example.com:password@example.com/');
319 #pod A hashref of options may be appended to modify the request.
321 #pod Valid options are:
325 #pod A hashref containing headers to include with the request. If the value for
326 #pod a header is an array reference, the header will be output multiple times with
327 #pod each value in the array. These headers over-write any default headers.
329 #pod A scalar to include as the body of the request OR a code reference
330 #pod that will be called iteratively to produce the body of the request
331 #pod * C<trailer_callback> —
332 #pod A code reference that will be called if it exists to provide a hashref
333 #pod of trailing headers (only used with chunked transfer-encoding)
334 #pod * C<data_callback> —
335 #pod A code reference that will be called for each chunks of the response
338 #pod The C<Host> header is generated from the URL in accordance with RFC 2616. It
339 #pod is a fatal error to specify C<Host> in the C<headers> option. Other headers
340 #pod may be ignored or overwritten if necessary for transport compliance.
342 #pod If the C<content> option is a code reference, it will be called iteratively
343 #pod to provide the content body of the request. It should return the empty
344 #pod string or undef when the iterator is exhausted.
346 #pod If the C<content> option is the empty string, no C<content-type> or
347 #pod C<content-length> headers will be generated.
349 #pod If the C<data_callback> option is provided, it will be called iteratively until
350 #pod the entire response body is received. The first argument will be a string
351 #pod containing a chunk of the response body, the second argument will be the
352 #pod in-progress response hash reference, as described below. (This allows
353 #pod customizing the action of the callback based on the C<status> or C<headers>
354 #pod received prior to the content body.)
356 #pod The C<request> method returns a hashref containing the response. The hashref
357 #pod will have the following keys:
361 #pod Boolean indicating whether the operation returned a 2XX status code
363 #pod URL that provided the response. This is the URL of the request unless
364 #pod there were redirections, in which case it is the last URL queried
365 #pod in a redirection chain
367 #pod The HTTP status code of the response
369 #pod The response phrase returned by the server
371 #pod The body of the response. If the response does not have any content
372 #pod or if a data callback is provided to consume the response body,
373 #pod this will be the empty string
375 #pod A hashref of header fields. All header field names will be normalized
376 #pod to be lower case. If a header is repeated, the value will be an arrayref;
377 #pod it will otherwise be a scalar string containing the value
379 #pod On an exception during the execution of the request, the C<status> field will
380 #pod contain 599, and the C<content> field will contain the text of the exception.
384 my %idempotent = map { $_ => 1 } qw/GET HEAD PUT DELETE OPTIONS TRACE/;
387 my ($self, $method, $url, $args) = @_;
388 @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
389 or Carp::croak(q/Usage: $http->request(METHOD, URL, [HASHREF])/ . "\n");
390 $args ||= {}; # we keep some state in this during _request
392 # RFC 2616 Section 8.1.4 mandates a single retry on broken socket
395 $response = eval { $self->_request($method, $url, $args) };
396 last unless $@ && $idempotent{$method}
397 && $@ =~ m{^(?:Socket closed|Unexpected end)};
401 # maybe we got a response hash thrown from somewhere deep
402 if ( ref $e eq 'HASH' && exists $e->{status} ) {
406 # otherwise, stringify it
412 reason => 'Internal Exception',
415 'content-type' => 'text/plain',
416 'content-length' => length $e,
423 #pod =method www_form_urlencode
425 #pod $params = $http->www_form_urlencode( $data );
426 #pod $response = $http->get("http://example.com/query?$params");
428 #pod This method converts the key/value pairs from a data hash or array reference
429 #pod into a C<x-www-form-urlencoded> string. The keys and values from the data
430 #pod reference will be UTF-8 encoded and escaped per RFC 3986. If a value is an
431 #pod array reference, the key will be repeated with each of the values of the array
432 #pod reference. If data is provided as a hash reference, the key/value pairs in the
433 #pod resulting string will be sorted by key and value for consistent ordering.
437 sub www_form_urlencode {
438 my ($self, $data) = @_;
439 (@_ == 2 && ref $data)
440 or Carp::croak(q/Usage: $http->www_form_urlencode(DATAREF)/ . "\n");
441 (ref $data eq 'HASH' || ref $data eq 'ARRAY')
442 or Carp::croak("form data must be a hash or array reference\n");
444 my @params = ref $data eq 'HASH' ? %$data : @$data;
446 or Carp::croak("form data reference must have an even number of terms\n");
450 my ($key, $value) = splice(@params, 0, 2);
451 if ( ref $value eq 'ARRAY' ) {
452 unshift @params, map { $key => $_ } @$value;
455 push @terms, join("=", map { $self->_uri_escape($_) } $key, $value);
459 return join("&", (ref $data eq 'ARRAY') ? (@terms) : (sort @terms) );
462 #--------------------------------------------------------------------------#
464 #--------------------------------------------------------------------------#
472 my $class = ref($_[0]) || $_[0];
473 (my $default_agent = $class) =~ s{::}{-}g;
474 return $default_agent . "/" . ($class->VERSION || 0);
478 my ($self, $method, $url, $args) = @_;
480 my ($scheme, $host, $port, $path_query, $auth) = $self->_split_url($url);
486 host_port => ($port == $DefaultPort{$scheme} ? $host : "$host:$port"),
491 # We remove the cached handle so it is not reused in the case of redirect.
492 # If all is well, it will be recached at the end of _request. We only
493 # reuse for the same scheme, host and port
494 my $handle = delete $self->{handle};
496 unless ( $handle->can_reuse( $scheme, $host, $port ) ) {
501 $handle ||= $self->_open_handle( $request, $scheme, $host, $port );
503 $self->_prepare_headers_and_cb($request, $args, $url, $auth);
504 $handle->write_request($request);
507 do { $response = $handle->read_response_header }
508 until (substr($response->{status},0,1) ne '1');
510 $self->_update_cookie_jar( $url, $response ) if $self->{cookie_jar};
512 if ( my @redir_args = $self->_maybe_redirect($request, $response, $args) ) {
514 return $self->_request(@redir_args, $args);
517 my $known_message_length;
518 if ($method eq 'HEAD' || $response->{status} =~ /^[23]04/) {
519 # response has no message body
520 $known_message_length = 1;
523 my $data_cb = $self->_prepare_data_cb($response, $args);
524 $known_message_length = $handle->read_body($data_cb, $response);
527 if ( $self->{keep_alive}
528 && $known_message_length
529 && $response->{protocol} eq 'HTTP/1.1'
530 && ($response->{headers}{connection} || '') ne 'close'
532 $self->{handle} = $handle;
538 $response->{success} = substr( $response->{status}, 0, 1 ) eq '2';
539 $response->{url} = $url;
544 my ($self, $request, $scheme, $host, $port) = @_;
546 my $handle = HTTP::Tiny::Handle->new(
547 timeout => $self->{timeout},
548 SSL_options => $self->{SSL_options},
549 verify_SSL => $self->{verify_SSL},
550 local_address => $self->{local_address},
551 keep_alive => $self->{keep_alive}
554 if ($self->{_has_proxy}{$scheme} && ! grep { $host =~ /\Q$_\E$/ } @{$self->{no_proxy}}) {
555 return $self->_proxy_connect( $request, $handle );
558 return $handle->connect($scheme, $host, $port);
563 my ($self, $request, $handle) = @_;
566 if ( $request->{scheme} eq 'https' ) {
567 Carp::croak(qq{No https_proxy defined}) unless $self->{https_proxy};
568 @proxy_vars = $self->_split_proxy( https_proxy => $self->{https_proxy} );
569 if ( $proxy_vars[0] eq 'https' ) {
570 Carp::croak(qq{Can't proxy https over https: $request->{uri} via $self->{https_proxy}});
574 Carp::croak(qq{No http_proxy defined}) unless $self->{http_proxy};
575 @proxy_vars = $self->_split_proxy( http_proxy => $self->{http_proxy} );
578 my ($p_scheme, $p_host, $p_port, $p_auth) = @proxy_vars;
580 if ( length $p_auth && ! defined $request->{headers}{'proxy-authorization'} ) {
581 $self->_add_basic_auth_header( $request, 'proxy-authorization' => $p_auth );
584 $handle->connect($p_scheme, $p_host, $p_port);
586 if ($request->{scheme} eq 'https') {
587 $self->_create_proxy_tunnel( $request, $handle );
590 # non-tunneled proxy requires absolute URI
591 $request->{uri} = "$request->{scheme}://$request->{host_port}$request->{uri}";
598 my ($self, $type, $proxy) = @_;
600 my ($scheme, $host, $port, $path_query, $auth) = eval { $self->_split_url($proxy) };
603 defined($scheme) && length($scheme) && length($host) && length($port)
604 && $path_query eq '/'
606 Carp::croak(qq{$type URL must be in format http[s]://[auth@]<host>:<port>/\n});
609 return ($scheme, $host, $port, $auth);
612 sub _create_proxy_tunnel {
613 my ($self, $request, $handle) = @_;
615 $handle->_assert_ssl;
617 my $agent = exists($request->{headers}{'user-agent'})
618 ? $request->{headers}{'user-agent'} : $self->{agent};
620 my $connect_request = {
622 uri => $request->{host_port},
624 host => $request->{host_port},
625 'user-agent' => $agent,
629 if ( $request->{headers}{'proxy-authorization'} ) {
630 $connect_request->{headers}{'proxy-authorization'} =
631 delete $request->{headers}{'proxy-authorization'};
634 $handle->write_request($connect_request);
636 do { $response = $handle->read_response_header }
637 until (substr($response->{status},0,1) ne '1');
639 # if CONNECT failed, throw the response so it will be
640 # returned from the original request() method;
641 unless (substr($response->{status},0,1) eq '2') {
645 # tunnel established, so start SSL handshake
646 $handle->start_ssl( $request->{host} );
651 sub _prepare_headers_and_cb {
652 my ($self, $request, $args, $url, $auth) = @_;
654 for ($self->{default_headers}, $args->{headers}) {
656 while (my ($k, $v) = each %$_) {
657 $request->{headers}{lc $k} = $v;
661 if (exists $request->{headers}{'host'}) {
662 die(qq/The 'Host' header must not be provided as header option\n/);
665 $request->{headers}{'host'} = $request->{host_port};
666 $request->{headers}{'user-agent'} ||= $self->{agent};
667 $request->{headers}{'connection'} = "close"
668 unless $self->{keep_alive};
670 if ( defined $args->{content} ) {
671 if (ref $args->{content} eq 'CODE') {
672 $request->{headers}{'content-type'} ||= "application/octet-stream";
673 $request->{headers}{'transfer-encoding'} = 'chunked'
674 unless $request->{headers}{'content-length'}
675 || $request->{headers}{'transfer-encoding'};
676 $request->{cb} = $args->{content};
678 elsif ( length $args->{content} ) {
679 my $content = $args->{content};
680 if ( $] ge '5.008' ) {
681 utf8::downgrade($content, 1)
682 or die(qq/Wide character in request message body\n/);
684 $request->{headers}{'content-type'} ||= "application/octet-stream";
685 $request->{headers}{'content-length'} = length $content
686 unless $request->{headers}{'content-length'}
687 || $request->{headers}{'transfer-encoding'};
688 $request->{cb} = sub { substr $content, 0, length $content, '' };
690 $request->{trailer_cb} = $args->{trailer_callback}
691 if ref $args->{trailer_callback} eq 'CODE';
694 ### If we have a cookie jar, then maybe add relevant cookies
695 if ( $self->{cookie_jar} ) {
696 my $cookies = $self->cookie_jar->cookie_header( $url );
697 $request->{headers}{cookie} = $cookies if length $cookies;
700 # if we have Basic auth parameters, add them
701 if ( length $auth && ! defined $request->{headers}{authorization} ) {
702 $self->_add_basic_auth_header( $request, 'authorization' => $auth );
708 sub _add_basic_auth_header {
709 my ($self, $request, $header, $auth) = @_;
710 require MIME::Base64;
711 $request->{headers}{$header} =
712 "Basic " . MIME::Base64::encode_base64($auth, "");
716 sub _prepare_data_cb {
717 my ($self, $response, $args) = @_;
718 my $data_cb = $args->{data_callback};
719 $response->{content} = '';
721 if (!$data_cb || $response->{status} !~ /^2/) {
722 if (defined $self->{max_size}) {
724 $_[1]->{content} .= $_[0];
725 die(qq/Size of response body exceeds the maximum allowed of $self->{max_size}\n/)
726 if length $_[1]->{content} > $self->{max_size};
730 $data_cb = sub { $_[1]->{content} .= $_[0] };
736 sub _update_cookie_jar {
737 my ($self, $url, $response) = @_;
739 my $cookies = $response->{headers}->{'set-cookie'};
740 return unless defined $cookies;
742 my @cookies = ref $cookies ? @$cookies : $cookies;
744 $self->cookie_jar->add( $url, $_ ) for @cookies;
749 sub _validate_cookie_jar {
750 my ($class, $jar) = @_;
753 for my $method ( qw/add cookie_header/ ) {
754 Carp::croak(qq/Cookie jar must provide the '$method' method\n/)
755 unless ref($jar) && ref($jar)->can($method);
761 sub _maybe_redirect {
762 my ($self, $request, $response, $args) = @_;
763 my $headers = $response->{headers};
764 my ($status, $method) = ($response->{status}, $request->{method});
765 if (($status eq '303' or ($status =~ /^30[127]/ && $method =~ /^GET|HEAD$/))
766 and $headers->{location}
767 and ++$args->{redirects} <= $self->{max_redirect}
769 my $location = ($headers->{location} =~ /^\//)
770 ? "$request->{scheme}://$request->{host_port}$headers->{location}"
771 : $headers->{location} ;
772 return (($status eq '303' ? 'GET' : $method), $location);
780 # URI regex adapted from the URI module
781 my ($scheme, $host, $path_query) = $url =~ m<\A([^:/?#]+)://([^/?#]*)([^#]*)>
782 or die(qq/Cannot parse URL: '$url'\n/);
784 $scheme = lc $scheme;
785 $path_query = "/$path_query" unless $path_query =~ m<\A/>;
788 if ( (my $i = index $host, '@') != -1 ) {
790 $auth = substr $host, 0, $i, ''; # take up to the @ for auth
791 substr $host, 0, 1, ''; # knock the @ off the host
793 # userinfo might be percent escaped, so recover real auth info
794 $auth =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
796 my $port = $host =~ s/:(\d*)\z// && length $1 ? $1
797 : $scheme eq 'http' ? 80
798 : $scheme eq 'https' ? 443
801 return ($scheme, (length $host ? lc $host : "localhost") , $port, $path_query, $auth);
804 # Date conversions adapted from HTTP::Date
805 my $DoW = "Sun|Mon|Tue|Wed|Thu|Fri|Sat";
806 my $MoY = "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec";
808 my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($_[1]);
809 return sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
810 substr($DoW,$wday*4,3),
811 $mday, substr($MoY,$mon*4,3), $year+1900,
816 sub _parse_http_date {
817 my ($self, $str) = @_;
820 if ($str =~ /^[SMTWF][a-z]+, +(\d{1,2}) ($MoY) +(\d\d\d\d) +(\d\d):(\d\d):(\d\d) +GMT$/) {
821 @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
823 elsif ($str =~ /^[SMTWF][a-z]+, +(\d\d)-($MoY)-(\d{2,4}) +(\d\d):(\d\d):(\d\d) +GMT$/ ) {
824 @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
826 elsif ($str =~ /^[SMTWF][a-z]+ +($MoY) +(\d{1,2}) +(\d\d):(\d\d):(\d\d) +(?:[^0-9]+ +)?(\d\d\d\d)$/ ) {
827 @tl_parts = ($5, $4, $3, $2, (index($MoY,$1)/4), $6);
830 my $t = @tl_parts ? Time::Local::timegm(@tl_parts) : -1;
835 # URI escaping adapted from URI::Escape
836 # c.f. http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
837 # perl 5.6 ready UTF-8 encoding adapted from JSON::PP
838 my %escapes = map { chr($_) => sprintf("%%%02X", $_) } 0..255;
840 my $unsafe_char = qr/[^A-Za-z0-9\-\._~]/;
843 my ($self, $str) = @_;
844 if ( $] ge '5.008' ) {
848 $str = pack("U*", unpack("C*", $str)) # UTF-8 encode a byte string
849 if ( length $str == do { use bytes; length $str } );
850 $str = pack("C*", unpack("C*", $str)); # clear UTF-8 flag
852 $str =~ s/($unsafe_char)/$escapes{$1}/ge;
857 HTTP::Tiny::Handle; # hide from PAUSE/indexers
861 use Errno qw[EINTR EPIPE];
862 use IO::Socket qw[SOCK_STREAM];
864 # for thread safety, we need to know thread id or else fake it;
865 # requires "threads.pm" to hide it from the minimum version detector
866 if ( eval { require "threads.pm"; 1 } ) { ## no critic
867 *_get_tid = sub { threads->tid };
870 *_get_tid = sub () { 0 };
873 # PERL_HTTP_TINY_IPV4_ONLY is a private environment variable to force old
874 # behavior if someone is unable to boostrap CPAN from a new perl install; it is
875 # not intended for general, per-client use and may be removed in the future
877 $ENV{PERL_HTTP_TINY_IPV4_ONLY} ? 'IO::Socket::INET' :
878 eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.25) } ? 'IO::Socket::IP' :
881 sub BUFSIZE () { 32768 } ## no critic
883 my $Printable = sub {
888 s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
892 my $Token = qr/[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/;
895 my ($class, %args) = @_;
899 max_line_size => 16384,
900 max_header_lines => 64,
908 @_ == 4 || die(q/Usage: $handle->connect(scheme, host, port)/ . "\n");
909 my ($self, $scheme, $host, $port) = @_;
911 if ( $scheme eq 'https' ) {
914 elsif ( $scheme ne 'http' ) {
915 die(qq/Unsupported URL scheme '$scheme'\n/);
917 $self->{fh} = $SOCKET_CLASS->new(
920 $self->{local_address} ?
921 ( LocalAddr => $self->{local_address} ) : (),
924 Timeout => $self->{timeout},
925 KeepAlive => !!$self->{keep_alive}
926 ) or die(qq/Could not connect to '$host:$port': $@\n/);
929 or die(qq/Could not binmode() socket: '$!'\n/);
931 $self->start_ssl($host) if $scheme eq 'https';
933 $self->{scheme} = $scheme;
934 $self->{host} = $host;
935 $self->{port} = $port;
937 $self->{tid} = _get_tid();
943 my ($self, $host) = @_;
945 # As this might be used via CONNECT after an SSL session
946 # to a proxy, we shut down any existing SSL before attempting
948 if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
949 unless ( $self->{fh}->stop_SSL ) {
950 my $ssl_err = IO::Socket::SSL->errstr;
951 die(qq/Error halting prior SSL connection: $ssl_err/);
955 my $ssl_args = $self->_ssl_args($host);
956 IO::Socket::SSL->start_SSL(
959 SSL_create_ctx_callback => sub {
961 Net::SSLeay::CTX_set_mode($ctx, Net::SSLeay::MODE_AUTO_RETRY());
965 unless ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
966 my $ssl_err = IO::Socket::SSL->errstr;
967 die(qq/SSL connection failed for $host: $ssl_err\n/);
972 @_ == 1 || die(q/Usage: $handle->close()/ . "\n");
974 CORE::close($self->{fh})
975 or die(qq/Could not close socket: '$!'\n/);
979 @_ == 2 || die(q/Usage: $handle->write(buf)/ . "\n");
980 my ($self, $buf) = @_;
982 if ( $] ge '5.008' ) {
983 utf8::downgrade($buf, 1)
984 or die(qq/Wide character in write()\n/);
987 my $len = length $buf;
990 local $SIG{PIPE} = 'IGNORE';
994 or die(qq/Timed out while waiting for socket to become ready for writing\n/);
995 my $r = syswrite($self->{fh}, $buf, $len, $off);
999 last unless $len > 0;
1001 elsif ($! == EPIPE) {
1002 die(qq/Socket closed by remote server: $!\n/);
1004 elsif ($! != EINTR) {
1005 if ($self->{fh}->can('errstr')){
1006 my $err = $self->{fh}->errstr();
1007 die (qq/Could not write to SSL socket: '$err'\n /);
1010 die(qq/Could not write to socket: '$!'\n/);
1019 @_ == 2 || @_ == 3 || die(q/Usage: $handle->read(len [, allow_partial])/ . "\n");
1020 my ($self, $len, $allow_partial) = @_;
1023 my $got = length $self->{rbuf};
1026 my $take = ($got < $len) ? $got : $len;
1027 $buf = substr($self->{rbuf}, 0, $take, '');
1033 or die(q/Timed out while waiting for socket to become ready for reading/ . "\n");
1034 my $r = sysread($self->{fh}, $buf, $len, length $buf);
1039 elsif ($! != EINTR) {
1040 if ($self->{fh}->can('errstr')){
1041 my $err = $self->{fh}->errstr();
1042 die (qq/Could not read from SSL socket: '$err'\n /);
1045 die(qq/Could not read from socket: '$!'\n/);
1049 if ($len && !$allow_partial) {
1050 die(qq/Unexpected end of stream\n/);
1056 @_ == 1 || die(q/Usage: $handle->readline()/ . "\n");
1060 if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) {
1063 if (length $self->{rbuf} >= $self->{max_line_size}) {
1064 die(qq/Line size exceeds the maximum allowed size of $self->{max_line_size}\n/);
1067 or die(qq/Timed out while waiting for socket to become ready for reading\n/);
1068 my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf});
1072 elsif ($! != EINTR) {
1073 if ($self->{fh}->can('errstr')){
1074 my $err = $self->{fh}->errstr();
1075 die (qq/Could not read from SSL socket: '$err'\n /);
1078 die(qq/Could not read from socket: '$!'\n/);
1082 die(qq/Unexpected end of stream while looking for line\n/);
1085 sub read_header_lines {
1086 @_ == 1 || @_ == 2 || die(q/Usage: $handle->read_header_lines([headers])/ . "\n");
1087 my ($self, $headers) = @_;
1093 my $line = $self->readline;
1095 if (++$lines >= $self->{max_header_lines}) {
1096 die(qq/Header lines exceeds maximum number allowed of $self->{max_header_lines}\n/);
1098 elsif ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) {
1099 my ($field_name) = lc $1;
1100 if (exists $headers->{$field_name}) {
1101 for ($headers->{$field_name}) {
1102 $_ = [$_] unless ref $_ eq "ARRAY";
1108 $val = \($headers->{$field_name} = $2);
1111 elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) {
1113 or die(qq/Unexpected header continuation line\n/);
1114 next unless length $1;
1115 $$val .= ' ' if length $$val;
1118 elsif ($line =~ /\A \x0D?\x0A \z/x) {
1122 die(q/Malformed header line: / . $Printable->($line) . "\n");
1129 @_ == 2 || die(q/Usage: $handle->write_request(request)/ . "\n");
1130 my($self, $request) = @_;
1131 $self->write_request_header(@{$request}{qw/method uri headers/});
1132 $self->write_body($request) if $request->{cb};
1137 'content-md5' => 'Content-MD5',
1140 'www-authenticate' => 'WWW-Authenticate',
1141 'x-xss-protection' => 'X-XSS-Protection',
1144 # to avoid multiple small writes and hence nagle, you can pass the method line or anything else to
1146 sub write_header_lines {
1147 (@_ == 2 || @_ == 3 && ref $_[1] eq 'HASH') || die(q/Usage: $handle->write_header_lines(headers[,prefix])/ . "\n");
1148 my($self, $headers, $prefix_data) = @_;
1150 my $buf = (defined $prefix_data ? $prefix_data : '');
1151 while (my ($k, $v) = each %$headers) {
1152 my $field_name = lc $k;
1153 if (exists $HeaderCase{$field_name}) {
1154 $field_name = $HeaderCase{$field_name};
1157 $field_name =~ /\A $Token+ \z/xo
1158 or die(q/Invalid HTTP header field name: / . $Printable->($field_name) . "\n");
1159 $field_name =~ s/\b(\w)/\u$1/g;
1160 $HeaderCase{lc $field_name} = $field_name;
1162 for (ref $v eq 'ARRAY' ? @$v : $v) {
1163 $_ = '' unless defined $_;
1164 $buf .= "$field_name: $_\x0D\x0A";
1168 return $self->write($buf);
1171 # return value indicates whether message length was defined; this is generally
1172 # true unless there was no content-length header and we just read until EOF.
1173 # Other message length errors are thrown as exceptions
1175 @_ == 3 || die(q/Usage: $handle->read_body(callback, response)/ . "\n");
1176 my ($self, $cb, $response) = @_;
1177 my $te = $response->{headers}{'transfer-encoding'} || '';
1178 my $chunked = grep { /chunked/i } ( ref $te eq 'ARRAY' ? @$te : $te ) ;
1180 ? $self->read_chunked_body($cb, $response)
1181 : $self->read_content_body($cb, $response);
1185 @_ == 2 || die(q/Usage: $handle->write_body(request)/ . "\n");
1186 my ($self, $request) = @_;
1187 if ($request->{headers}{'content-length'}) {
1188 return $self->write_content_body($request);
1191 return $self->write_chunked_body($request);
1195 sub read_content_body {
1196 @_ == 3 || @_ == 4 || die(q/Usage: $handle->read_content_body(callback, response, [read_length])/ . "\n");
1197 my ($self, $cb, $response, $content_length) = @_;
1198 $content_length ||= $response->{headers}{'content-length'};
1200 if ( defined $content_length ) {
1201 my $len = $content_length;
1203 my $read = ($len > BUFSIZE) ? BUFSIZE : $len;
1204 $cb->($self->read($read, 0), $response);
1207 return length($self->{rbuf}) == 0;
1211 $cb->($chunk, $response) while length( $chunk = $self->read(BUFSIZE, 1) );
1216 sub write_content_body {
1217 @_ == 2 || die(q/Usage: $handle->write_content_body(request)/ . "\n");
1218 my ($self, $request) = @_;
1220 my ($len, $content_length) = (0, $request->{headers}{'content-length'});
1222 my $data = $request->{cb}->();
1224 defined $data && length $data
1227 if ( $] ge '5.008' ) {
1228 utf8::downgrade($data, 1)
1229 or die(qq/Wide character in write_content()\n/);
1232 $len += $self->write($data);
1235 $len == $content_length
1236 or die(qq/Content-Length missmatch (got: $len expected: $content_length)\n/);
1241 sub read_chunked_body {
1242 @_ == 3 || die(q/Usage: $handle->read_chunked_body(callback, $response)/ . "\n");
1243 my ($self, $cb, $response) = @_;
1246 my $head = $self->readline;
1248 $head =~ /\A ([A-Fa-f0-9]+)/x
1249 or die(q/Malformed chunk head: / . $Printable->($head) . "\n");
1254 $self->read_content_body($cb, $response, $len);
1256 $self->read(2) eq "\x0D\x0A"
1257 or die(qq/Malformed chunk: missing CRLF after chunk data\n/);
1259 $self->read_header_lines($response->{headers});
1263 sub write_chunked_body {
1264 @_ == 2 || die(q/Usage: $handle->write_chunked_body(request)/ . "\n");
1265 my ($self, $request) = @_;
1269 my $data = $request->{cb}->();
1271 defined $data && length $data
1274 if ( $] ge '5.008' ) {
1275 utf8::downgrade($data, 1)
1276 or die(qq/Wide character in write_chunked_body()\n/);
1279 $len += length $data;
1281 my $chunk = sprintf '%X', length $data;
1282 $chunk .= "\x0D\x0A";
1284 $chunk .= "\x0D\x0A";
1286 $self->write($chunk);
1288 $self->write("0\x0D\x0A");
1289 $self->write_header_lines($request->{trailer_cb}->())
1290 if ref $request->{trailer_cb} eq 'CODE';
1294 sub read_response_header {
1295 @_ == 1 || die(q/Usage: $handle->read_response_header()/ . "\n");
1298 my $line = $self->readline;
1300 $line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x
1301 or die(q/Malformed Status-Line: / . $Printable->($line). "\n");
1303 my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4);
1305 die (qq/Unsupported HTTP protocol: $protocol\n/)
1306 unless $version =~ /0*1\.0*[01]/;
1311 headers => $self->read_header_lines,
1312 protocol => $protocol,
1316 sub write_request_header {
1317 @_ == 4 || die(q/Usage: $handle->write_request_header(method, request_uri, headers)/ . "\n");
1318 my ($self, $method, $request_uri, $headers) = @_;
1320 return $self->write_header_lines($headers, "$method $request_uri HTTP/1.1\x0D\x0A");
1324 my ($self, $type, $timeout) = @_;
1325 $timeout = $self->{timeout}
1326 unless defined $timeout && $timeout >= 0;
1328 my $fd = fileno $self->{fh};
1329 defined $fd && $fd >= 0
1330 or die(qq/select(2): 'Bad file descriptor'\n/);
1333 my $pending = $timeout;
1336 vec(my $fdset = '', $fd, 1) = 1;
1339 $nfound = ($type eq 'read')
1340 ? select($fdset, undef, undef, $pending)
1341 : select(undef, $fdset, undef, $pending) ;
1342 if ($nfound == -1) {
1344 or die(qq/select(2): '$!'\n/);
1345 redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0;
1355 @_ == 1 || @_ == 2 || die(q/Usage: $handle->can_read([timeout])/ . "\n");
1357 if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
1358 return 1 if $self->{fh}->pending;
1360 return $self->_do_timeout('read', @_)
1364 @_ == 1 || @_ == 2 || die(q/Usage: $handle->can_write([timeout])/ . "\n");
1366 return $self->_do_timeout('write', @_)
1370 # Need IO::Socket::SSL 1.42 for SSL_create_ctx_callback
1371 die(qq/IO::Socket::SSL 1.42 must be installed for https support\n/)
1372 unless eval {require IO::Socket::SSL; IO::Socket::SSL->VERSION(1.42)};
1373 # Need Net::SSLeay 1.49 for MODE_AUTO_RETRY
1374 die(qq/Net::SSLeay 1.49 must be installed for https support\n/)
1375 unless eval {require Net::SSLeay; Net::SSLeay->VERSION(1.49)};
1379 my ($self,$scheme,$host,$port) = @_;
1382 || $self->{tid} != _get_tid()
1383 || length($self->{rbuf})
1384 || $scheme ne $self->{scheme}
1385 || $host ne $self->{host}
1386 || $port ne $self->{port}
1387 || eval { $self->can_read(0) }
1392 # Try to find a CA bundle to validate the SSL cert,
1393 # prefer Mozilla::CA or fallback to a system file
1397 return $self->{SSL_options}->{SSL_ca_file}
1398 if $self->{SSL_options}->{SSL_ca_file} and -e $self->{SSL_options}->{SSL_ca_file};
1400 return Mozilla::CA::SSL_ca_file()
1401 if eval { require Mozilla::CA };
1403 foreach my $ca_bundle (qw{
1404 /etc/ssl/certs/ca-certificates.crt
1405 /etc/pki/tls/certs/ca-bundle.crt
1406 /etc/ssl/ca-bundle.pem
1409 return $ca_bundle if -e $ca_bundle;
1412 die qq/Couldn't find a CA bundle with which to verify the SSL certificate.\n/
1413 . qq/Try installing Mozilla::CA from CPAN\n/;
1417 my ($self, $host) = @_;
1421 # This test reimplements IO::Socket::SSL::can_client_sni(), which wasn't
1422 # added until IO::Socket::SSL 1.84
1423 if ( Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000 ) {
1424 $ssl_args{SSL_hostname} = $host, # Sane SNI support
1427 if ($self->{verify_SSL}) {
1428 $ssl_args{SSL_verifycn_scheme} = 'http'; # enable CN validation
1429 $ssl_args{SSL_verifycn_name} = $host; # set validation hostname
1430 $ssl_args{SSL_verify_mode} = 0x01; # enable cert validation
1431 $ssl_args{SSL_ca_file} = $self->_find_CA_file;
1434 $ssl_args{SSL_verifycn_scheme} = 'none'; # disable CN validation
1435 $ssl_args{SSL_verify_mode} = 0x00; # disable cert validation
1438 # user options override settings from verify_SSL
1439 for my $k ( keys %{$self->{SSL_options}} ) {
1440 $ssl_args{$k} = $self->{SSL_options}{$k} if $k =~ m/^SSL_/;
1456 HTTP::Tiny - A small, simple, correct HTTP/1.1 client
1466 my $response = HTTP::Tiny->new->get('http://example.com/');
1468 die "Failed!\n" unless $response->{success};
1470 print "$response->{status} $response->{reason}\n";
1472 while (my ($k, $v) = each %{$response->{headers}}) {
1473 for (ref $v eq 'ARRAY' ? @$v : $v) {
1478 print $response->{content} if length $response->{content};
1482 This is a very simple HTTP/1.1 client, designed for doing simple
1483 requests without the overhead of a large framework like L<LWP::UserAgent>.
1485 It is more correct and more complete than L<HTTP::Lite>. It supports
1486 proxies and redirection. It also correctly resumes after EINTR.
1488 If L<IO::Socket::IP> 0.25 or later is installed, HTTP::Tiny will use it instead
1489 of L<IO::Socket::INET> for transparent support for both IPv4 and IPv6.
1491 Cookie support requires L<HTTP::CookieJar> or an equivalent class.
1497 $http = HTTP::Tiny->new( %attributes );
1499 This constructor returns a new HTTP::Tiny object. Valid attributes include:
1505 C<agent> — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> — ends in a space character, the default user-agent string is appended.
1509 C<cookie_jar> — An instance of L<HTTP::CookieJar> — or equivalent class that supports the C<add> and C<cookie_header> methods
1513 C<default_headers> — A hashref of default headers to apply to requests
1517 C<local_address> — The local IP address to bind to
1521 C<keep_alive> — Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
1525 C<max_redirect> — Maximum number of redirects allowed (defaults to 5)
1529 C<max_size> — Maximum response size (only when not using a data callback). If defined, responses larger than this will return an exception.
1533 C<http_proxy> — URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> — if set)
1537 C<https_proxy> — URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> — if set)
1541 C<proxy> — URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> — if set)
1545 C<no_proxy> — List of domain suffixes that should not be proxied. Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> —)
1549 C<timeout> — Request timeout in seconds (default is 60)
1553 C<verify_SSL> — A boolean that indicates whether to validate the SSL certificate of an C<https> — connection (default is false)
1557 C<SSL_options> — A hashref of C<SSL_*> — options to pass through to L<IO::Socket::SSL>
1561 Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
1562 prevent getting the corresponding proxies from the environment.
1564 Exceptions from C<max_size>, C<timeout> or other errors will result in a
1565 pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
1566 content field in the response will contain the text of the exception.
1568 The C<keep_alive> parameter enables a persistent connection, but only to a
1569 single destination scheme, host and port. Also, if any connection-relevant
1570 attributes are modified, or if the process ID or thread ID change, the
1571 persistent connection will be dropped. If you want persistent connections
1572 across multiple destinations, use multiple HTTP::Tiny objects.
1574 See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
1576 =head2 get|head|put|post|delete
1578 $response = $http->get($url);
1579 $response = $http->get($url, \%options);
1580 $response = $http->head($url);
1582 These methods are shorthand for calling C<request()> for the given method. The
1583 URL must have unsafe characters escaped and international domain names encoded.
1584 See C<request()> for valid options and a description of the response.
1586 The C<success> field of the response will be true if the status code is 2XX.
1590 $response = $http->post_form($url, $form_data);
1591 $response = $http->post_form($url, $form_data, \%options);
1593 This method executes a C<POST> request and sends the key/value pairs from a
1594 form data hash or array reference to the given URL with a C<content-type> of
1595 C<application/x-www-form-urlencoded>. If data is provided as an array
1596 reference, the order is preserved; if provided as a hash reference, the terms
1597 are sorted on key and value for consistency. See documentation for the
1598 C<www_form_urlencode> method for details on the encoding.
1600 The URL must have unsafe characters escaped and international domain names
1601 encoded. See C<request()> for valid options and a description of the response.
1602 Any C<content-type> header or content in the options hashref will be ignored.
1604 The C<success> field of the response will be true if the status code is 2XX.
1608 $response = $http->mirror($url, $file, \%options)
1609 if ( $response->{success} ) {
1610 print "$file is up to date\n";
1613 Executes a C<GET> request for the URL and saves the response body to the file
1614 name provided. The URL must have unsafe characters escaped and international
1615 domain names encoded. If the file already exists, the request will include an
1616 C<If-Modified-Since> header with the modification timestamp of the file. You
1617 may specify a different C<If-Modified-Since> header yourself in the C<<
1618 $options->{headers} >> hash.
1620 The C<success> field of the response will be true if the status code is 2XX
1621 or if the status code is 304 (unmodified).
1623 If the file was modified and the server response includes a properly
1624 formatted C<Last-Modified> header, the file modification time will
1625 be updated accordingly.
1629 $response = $http->request($method, $url);
1630 $response = $http->request($method, $url, \%options);
1632 Executes an HTTP request of the given method type ('GET', 'HEAD', 'POST',
1633 'PUT', etc.) on the given URL. The URL must have unsafe characters escaped and
1634 international domain names encoded.
1636 If the URL includes a "user:password" stanza, they will be used for Basic-style
1637 authorization headers. (Authorization headers will not be included in a
1638 redirected request.) For example:
1640 $http->request('GET', 'http://Aladdin:open sesame@example.com/');
1642 If the "user:password" stanza contains reserved characters, they must
1645 $http->request('GET', 'http://john%40example.com:password@example.com/');
1647 A hashref of options may be appended to modify the request.
1655 C<headers> — A hashref containing headers to include with the request. If the value for a header is an array reference, the header will be output multiple times with each value in the array. These headers over-write any default headers.
1659 C<content> — A scalar to include as the body of the request OR a code reference that will be called iteratively to produce the body of the request
1663 C<trailer_callback> — A code reference that will be called if it exists to provide a hashref of trailing headers (only used with chunked transfer-encoding)
1667 C<data_callback> — A code reference that will be called for each chunks of the response body received.
1671 The C<Host> header is generated from the URL in accordance with RFC 2616. It
1672 is a fatal error to specify C<Host> in the C<headers> option. Other headers
1673 may be ignored or overwritten if necessary for transport compliance.
1675 If the C<content> option is a code reference, it will be called iteratively
1676 to provide the content body of the request. It should return the empty
1677 string or undef when the iterator is exhausted.
1679 If the C<content> option is the empty string, no C<content-type> or
1680 C<content-length> headers will be generated.
1682 If the C<data_callback> option is provided, it will be called iteratively until
1683 the entire response body is received. The first argument will be a string
1684 containing a chunk of the response body, the second argument will be the
1685 in-progress response hash reference, as described below. (This allows
1686 customizing the action of the callback based on the C<status> or C<headers>
1687 received prior to the content body.)
1689 The C<request> method returns a hashref containing the response. The hashref
1690 will have the following keys:
1696 C<success> — Boolean indicating whether the operation returned a 2XX status code
1700 C<url> — URL that provided the response. This is the URL of the request unless there were redirections, in which case it is the last URL queried in a redirection chain
1704 C<status> — The HTTP status code of the response
1708 C<reason> — The response phrase returned by the server
1712 C<content> — The body of the response. If the response does not have any content or if a data callback is provided to consume the response body, this will be the empty string
1716 C<headers> — A hashref of header fields. All header field names will be normalized to be lower case. If a header is repeated, the value will be an arrayref; it will otherwise be a scalar string containing the value
1720 On an exception during the execution of the request, the C<status> field will
1721 contain 599, and the C<content> field will contain the text of the exception.
1723 =head2 www_form_urlencode
1725 $params = $http->www_form_urlencode( $data );
1726 $response = $http->get("http://example.com/query?$params");
1728 This method converts the key/value pairs from a data hash or array reference
1729 into a C<x-www-form-urlencoded> string. The keys and values from the data
1730 reference will be UTF-8 encoded and escaped per RFC 3986. If a value is an
1731 array reference, the key will be repeated with each of the values of the array
1732 reference. If data is provided as a hash reference, the key/value pairs in the
1733 resulting string will be sorted by key and value for consistent ordering.
1735 =for Pod::Coverage SSL_options
1752 Direct C<https> connections are supported only if L<IO::Socket::SSL> 1.56 or
1753 greater and L<Net::SSLeay> 1.49 or greater are installed. An exception will be
1754 thrown if new enough versions of these modules are not installed or if the SSL
1755 encryption fails. An C<https> connection may be made via an C<http> proxy that
1756 supports the CONNECT command (i.e. RFC 2817). You may not proxy C<https> via
1757 a proxy that itself requires C<https> to communicate.
1759 SSL provides two distinct capabilities:
1765 Encrypted communication channel
1769 Verification of server identity
1773 B<By default, HTTP::Tiny does not verify server identity>.
1775 Server identity verification is controversial and potentially tricky because it
1776 depends on a (usually paid) third-party Certificate Authority (CA) trust model
1777 to validate a certificate as legitimate. This discriminates against servers
1778 with self-signed certificates or certificates signed by free, community-driven
1779 CA's such as L<CAcert.org|http://cacert.org>.
1781 By default, HTTP::Tiny does not make any assumptions about your trust model,
1782 threat level or risk tolerance. It just aims to give you an encrypted channel
1785 Setting the C<verify_SSL> attribute to a true value will make HTTP::Tiny verify
1786 that an SSL connection has a valid SSL certificate corresponding to the host
1787 name of the connection and that the SSL certificate has been verified by a CA.
1788 Assuming you trust the CA, this will protect against a L<man-in-the-middle
1789 attack|http://en.wikipedia.org/wiki/Man-in-the-middle_attack>. If you are
1790 concerned about security, you should enable this option.
1792 Certificate verification requires a file containing trusted CA certificates.
1793 If the L<Mozilla::CA> module is installed, HTTP::Tiny will use the CA file
1794 included with it as a source of trusted CA's. (This means you trust Mozilla,
1795 the author of Mozilla::CA, the CPAN mirror where you got Mozilla::CA, the
1796 toolchain used to install it, and your operating system security, right?)
1798 If that module is not available, then HTTP::Tiny will search several
1799 system-specific default locations for a CA certificate file:
1805 /etc/ssl/certs/ca-certificates.crt
1809 /etc/pki/tls/certs/ca-bundle.crt
1813 /etc/ssl/ca-bundle.pem
1817 An exception will be raised if C<verify_SSL> is true and no CA certificate file
1820 If you desire complete control over SSL connections, the C<SSL_options> attribute
1821 lets you provide a hash reference that will be passed through to
1822 C<IO::Socket::SSL::start_SSL()>, overriding any options set by HTTP::Tiny. For
1823 example, to provide your own trusted CA file:
1826 SSL_ca_file => $file_path,
1829 The C<SSL_options> attribute could also be used for such things as providing a
1830 client certificate for authentication to a server or controlling the choice of
1831 cipher used for the SSL connection. See L<IO::Socket::SSL> documentation for
1834 =head1 PROXY SUPPORT
1836 HTTP::Tiny can proxy both C<http> and C<https> requests. Only Basic proxy
1837 authorization is supported and it must be provided as part of the proxy URL:
1838 C<http://user:pass@proxy.example.com/>.
1840 HTTP::Tiny supports the following proxy environment variables:
1850 https_proxy or HTTPS_PROXY
1854 all_proxy or ALL_PROXY
1858 Tunnelling C<https> over an C<http> proxy using the CONNECT method is
1859 supported. If your proxy uses C<https> itself, you can not tunnel C<https>
1862 Be warned that proxying an C<https> connection opens you to the risk of a
1863 man-in-the-middle attack by the proxy server.
1865 The C<no_proxy> environment variable is supported in the format of a
1866 comma-separated list of domain extensions proxy should not be used for.
1868 Proxy arguments passed to C<new> will override their corresponding
1869 environment variables.
1873 HTTP::Tiny is I<conditionally compliant> with the
1874 L<HTTP/1.1 specifications|http://www.w3.org/Protocols/>:
1880 "Message Syntax and Routing" [RFC7230]
1884 "Semantics and Content" [RFC7231]
1888 "Conditional Requests" [RFC7232]
1892 "Range Requests" [RFC7233]
1900 "Authentication" [RFC7235]
1904 It attempts to meet all "MUST" requirements of the specification, but does not
1905 implement all "SHOULD" requirements. (Note: it was developed against the
1906 earlier RFC 2616 specification and may not yet meet the revised RFC 7230-7235
1909 Some particular limitations of note include:
1915 HTTP::Tiny focuses on correct transport. Users are responsible for ensuring
1916 that user-defined headers and content are compliant with the HTTP/1.1
1921 Users must ensure that URLs are properly escaped for unsafe characters and that
1922 international domain names are properly encoded to ASCII. See L<URI::Escape>,
1923 L<URI::_punycode> and L<Net::IDN::Encode>.
1927 Redirection is very strict against the specification. Redirection is only
1928 automatic for response codes 301, 302 and 307 if the request method is 'GET' or
1929 'HEAD'. Response code 303 is always converted into a 'GET' redirection, as
1930 mandated by the specification. There is no automatic support for status 305
1931 ("Use proxy") redirections.
1935 There is no provision for delaying a request body using an C<Expect> header.
1936 Unexpected C<1XX> responses are silently ignored as per the specification.
1940 Only 'chunked' C<Transfer-Encoding> is supported.
1944 There is no support for a Request-URI of '*' for the 'OPTIONS' request.
1948 Despite the limitations listed above, HTTP::Tiny is considered
1949 feature-complete. New feature requests should be directed to
1958 L<HTTP::Tiny::UA> - Higher level UA features for HTTP::Tiny
1962 L<HTTP::Thin> - HTTP::Tiny wrapper with L<HTTP::Request>/L<HTTP::Response> compatibility
1966 L<HTTP::Tiny::Mech> - Wrap L<WWW::Mechanize> instance in HTTP::Tiny compatible interface
1970 L<IO::Socket::IP> - Required for IPv6 support
1974 L<IO::Socket::SSL> - Required for SSL support
1978 L<LWP::UserAgent> - If HTTP::Tiny isn't enough for you, this is the "standard" way to do things
1982 L<Mozilla::CA> - Required if you want to validate SSL certificates
1986 L<Net::SSLeay> - Required for SSL support
1990 =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
1994 =head2 Bugs / Feature Requests
1996 Please report any bugs or feature requests through the issue tracker
1997 at L<https://github.com/chansen/p5-http-tiny/issues>.
1998 You will be notified automatically of any progress on your issue.
2002 This is open source software. The code repository is available for
2003 public review and contribution under the terms of the license.
2005 L<https://github.com/chansen/p5-http-tiny>
2007 git clone https://github.com/chansen/p5-http-tiny.git
2015 Christian Hansen <chansen@cpan.org>
2019 David Golden <dagolden@cpan.org>
2025 =for stopwords Alan Gardner James Raspass Jess Robinson Lukas Eklund Martin J. Evans Martin-Louis Bright Mike Doherty Petr Písař Serguei Trouchelle Syohei YOSHIDA Sören Kornetzki Alessandro Ghedini Tom Hukins Tony Cook Brad Gilbert Chris Nehren Weyl Claes Jakobsson Clinton Gormley Craig Berry David Mitchell Edward Zborowski
2031 Alan Gardner <gardner@pythian.com>
2035 James Raspass <jraspass@gmail.com>
2039 Jess Robinson <castaway@desert-island.me.uk>
2043 Lukas Eklund <leklund@gmail.com>
2047 Martin J. Evans <mjegh@ntlworld.com>
2051 Martin-Louis Bright <mlbright@gmail.com>
2055 Mike Doherty <doherty@cpan.org>
2059 Petr Písař <ppisar@redhat.com>
2063 Serguei Trouchelle <stro@cpan.org>
2067 Syohei YOSHIDA <syohex@gmail.com>
2071 Sören Kornetzki <soeren.kornetzki@delti.com>
2075 Alessandro Ghedini <al3xbio@gmail.com>
2079 Tom Hukins <tom@eborcom.com>
2083 Tony Cook <tony@develop-help.com>
2087 Brad Gilbert <bgills@cpan.org>
2091 Chris Nehren <apeiron@cpan.org>
2095 Chris Weyl <rsrchboy@cpan.org>
2099 Claes Jakobsson <claes@surfar.nu>
2103 Clinton Gormley <clint@traveljury.com>
2107 Craig Berry <cberry@cpan.org>
2111 David Mitchell <davem@iabyn.com>
2115 Edward Zborowski <ed@rubensteintech.com>
2119 =head1 COPYRIGHT AND LICENSE
2121 This software is copyright (c) 2014 by Christian Hansen.
2123 This is free software; you can redistribute it and/or modify it under
2124 the same terms as the Perl 5 programming language system itself.