Amazon-S3
view release on metacpan or search on metacpan
lib/Amazon/S3.pm view on Meta::CPAN
}
########################################################################
sub _decode_response {
########################################################################
my ( $self, $response, $keep_root ) = @_;
my $content;
if ( $response->code !~ /\A2\d{2}\z/xsm ) {
$self->_remember_errors( $response->content, 1 );
$content = undef;
}
elsif ( is_xml_response($response) ) {
$content = $self->_xpc_of_content( $response->content, $keep_root );
}
return $content;
}
########################################################################
sub is_xml_response {
########################################################################
my ($rsp) = @_;
return $FALSE
if !$rsp->content;
return $TRUE
if $rsp->content_type eq 'application/xml';
return $TRUE
if $rsp->content =~ /\A\s*<[?]xml/xsm;
return $FALSE;
}
#
# This is the necessary to find the region for a specific bucket
# and set the signer object to use that region when signing requests
########################################################################
sub adjust_region {
########################################################################
my ( $self, $bucket, $called_from_redirect ) = @_;
my $url = sprintf 'https://%s.%s', $bucket, $self->host;
my $request = HTTP::Request->new( GET => $url );
$self->{'signer'}->sign($request);
# We have to turn off our special retry since this will deliberately
# trigger that code
$self->turn_off_special_retry();
# If the bucket name has a period in it, the certificate validation
# will fail since it will expect a certificate for a subdomain.
# Setting it to verify against the expected host guards against
# that while still being secure since we will have verified
# the response as coming from the expected server.
$self->ua->ssl_opts( SSL_verifycn_name => $self->host );
my $response = $self->_do_http($request);
# Turn this off, since all other requests have the bucket after
# the host in the URL, and the host may change depending on the region
$self->ua->ssl_opts( SSL_verifycn_name => undef );
$self->turn_on_special_retry();
# If No error, then nothing to do
return $TRUE
if $response->is_success();
# If the error is due to the wrong region, then we will get
# back a block of XML with the details
return $FALSE
if !is_xml_response($response);
my $error_hash = $self->_xpc_of_content( $response->content );
my ( $endpoint, $code, $region, $message )
= @{$error_hash}{qw(Endpoint Code Region Message)};
my $condition = eval {
return 'PermanentRedirect'
if $code eq 'PermanentRedirect' && $endpoint;
return 'AuthorizationHeaderMalformed'
if $code eq 'AuthorizationHeaderMalformed' && $region;
return 'IllegalLocationConstraintException'
if $code eq 'IllegalLocationConstraintException';
return 'Other';
};
my %error_handlers = (
PermanentRedirect => sub {
# Don't recurse through multiple redirects
return $FALSE
if $called_from_redirect;
# With a permanent redirect error, they are telling us the explicit
# host to use. The endpoint will be in the form of bucket.host
my $host = $endpoint;
# Remove the bucket name from the front of the host name
# All the requests will need to be of the form https://host/bucket
$host =~ s/\A$bucket[.]//xsm;
$self->host($host);
# We will need to call ourselves again in order to trigger the
# AuthorizationHeaderMalformed error in order to get the region
return $self->adjust_region( $bucket, $TRUE );
},
AuthorizationHeaderMalformed => sub {
# Set the signer to use the correct reader evermore
$self->{signer}->{endpoint} = $region;
# Only change the host if we haven't been called as a redirect
# where an exact host has been given
if ( !$called_from_redirect ) {
$self->host( sprintf 's3-%s-amazonaws.com', $region );
}
return $TRUE;
( run in 0.904 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )