CPANPLUS
view release on metacpan or search on metacpan
inc/bundle/HTTP/Tiny.pm view on Meta::CPAN
(my $default_agent = $class) =~ s{::}{-}g;
my $version = $class->VERSION;
$default_agent .= "/$version" if defined $version;
return $default_agent;
}
sub _request {
my ($self, $method, $url, $args) = @_;
my ($scheme, $host, $port, $path_query, $auth) = $self->_split_url($url);
if ($scheme ne 'http' && $scheme ne 'https') {
die(qq/Unsupported URL scheme '$scheme'\n/);
}
my $request = {
method => $method,
scheme => $scheme,
host => $host,
port => $port,
host_port => ($port == $DefaultPort{$scheme} ? $host : "$host:$port"),
uri => $path_query,
headers => {},
};
my $peer = $args->{peer} || $host;
# Allow 'peer' to be a coderef.
if ('CODE' eq ref $peer) {
$peer = $peer->($host);
}
# We remove the cached handle so it is not reused in the case of redirect.
# If all is well, it will be recached at the end of _request. We only
# reuse for the same scheme, host and port
my $handle = delete $self->{handle};
if ( $handle ) {
unless ( $handle->can_reuse( $scheme, $host, $port, $peer ) ) {
$handle->close;
undef $handle;
}
}
$handle ||= $self->_open_handle( $request, $scheme, $host, $port, $peer );
$self->_prepare_headers_and_cb($request, $args, $url, $auth);
$handle->write_request($request);
my $response;
do { $response = $handle->read_response_header }
until (substr($response->{status},0,1) ne '1');
$self->_update_cookie_jar( $url, $response ) if $self->{cookie_jar};
my @redir_args = $self->_maybe_redirect($request, $response, $args);
my $known_message_length;
if ($method eq 'HEAD' || $response->{status} =~ /^[23]04/) {
# response has no message body
$known_message_length = 1;
}
else {
# Ignore any data callbacks during redirection.
my $cb_args = @redir_args ? +{} : $args;
my $data_cb = $self->_prepare_data_cb($response, $cb_args);
$known_message_length = $handle->read_body($data_cb, $response);
}
if ( $self->{keep_alive}
&& $handle->connected
&& $known_message_length
&& $response->{protocol} eq 'HTTP/1.1'
&& ($response->{headers}{connection} || '') ne 'close'
) {
$self->{handle} = $handle;
}
else {
$handle->close;
}
$response->{success} = substr( $response->{status}, 0, 1 ) eq '2';
$response->{url} = $url;
# Push the current response onto the stack of redirects if redirecting.
if (@redir_args) {
push @{$args->{_redirects}}, $response;
return $self->_request(@redir_args, $args);
}
# Copy the stack of redirects into the response before returning.
$response->{redirects} = delete $args->{_redirects}
if @{$args->{_redirects}};
return $response;
}
sub _open_handle {
my ($self, $request, $scheme, $host, $port, $peer) = @_;
my $handle = HTTP::Tiny::Handle->new(
timeout => $self->{timeout},
SSL_options => $self->{SSL_options},
verify_SSL => $self->{verify_SSL},
local_address => $self->{local_address},
keep_alive => $self->{keep_alive}
);
if ($self->{_has_proxy}{$scheme} && ! grep { $host =~ /\Q$_\E$/ } @{$self->{no_proxy}}) {
return $self->_proxy_connect( $request, $handle );
}
else {
return $handle->connect($scheme, $host, $port, $peer);
}
}
sub _proxy_connect {
my ($self, $request, $handle) = @_;
my @proxy_vars;
if ( $request->{scheme} eq 'https' ) {
_croak(qq{No https_proxy defined}) unless $self->{https_proxy};
@proxy_vars = $self->_split_proxy( https_proxy => $self->{https_proxy} );
if ( $proxy_vars[0] eq 'https' ) {
_croak(qq{Can't proxy https over https: $request->{uri} via $self->{https_proxy}});
( run in 1.542 second using v1.01-cache-2.11-cpan-39bf76dae61 )