has
's3'
=> (
is
=>
'ro'
,
isa
=>
'AWS::S3'
,
required
=> 1,
);
has
'type'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
required
=> 1,
);
has
'protocol'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
lazy
=> 1,
default
=>
sub
{
shift
->s3->secure ?
'https'
:
'http'
;
}
);
has
'endpoint'
=> (
is
=>
'ro'
,
isa
=>
'Str'
,
lazy
=> 1,
default
=>
sub
{
shift
->s3->endpoint;
}
);
has
"_action"
=> (
isa
=>
'Str'
,
is
=>
'ro'
,
init_arg
=>
undef
,
);
has
'_expect_nothing'
=> (
isa
=>
'Bool'
,
is
=>
'ro'
,
init_arg
=>
undef
);
has
'_uri'
=> (
isa
=> Uri,
is
=>
'ro'
,
lazy
=> 1,
default
=>
sub
{
my
$self
=
shift
;
my
$m
=
$self
->meta;
my
$uri
= URI->new(
$self
->protocol .
'://'
. (
$m
->has_attribute(
'bucket'
) ?
$self
->bucket .
'.'
:
''
)
.
$self
->endpoint
.
'/'
);
if
(
$m
->has_attribute(
'key'
) ) {
my
$escaped_path
= uri_escape(
$self
->key,
"^A-Za-z0-9\-\._~\/:="
);
if
(
$escaped_path
=~ m!^/! &&
$self
->s3->honor_leading_slashes ) {
$uri
->path(
'/'
.
$escaped_path
)
}
else
{
$uri
->path(
$escaped_path
)
}
}
$uri
->query_keywords(
$self
->_subresource )
if
$m
->has_attribute(
'_subresource'
);
$uri
;
}
);
has
'signerv4'
=> (
is
=>
'ro'
,
isa
=>
'AWS::S3::Signer::V4'
,
lazy
=> 1,
default
=>
sub
{
my
$s
=
shift
;
AWS::S3::Signer::V4->new(
-access_key
=>
$s
->s3->access_key_id,
-secret_key
=>
$s
->s3->secret_access_key,
);
}
);
sub
_send_request {
my
(
$s
,
$method
,
$uri
,
$headers
,
$content
) =
@_
;
my
$req
= HTTP::Request->new(
$method
=>
$uri
);
$req
->content(
$content
)
if
$content
;
delete
(
$headers
->{Authorization});
map
{
$req
->header(
$_
=>
$headers
->{
$_
} ) }
keys
%$headers
;
$s
->_sign(
$req
);
my
$res
=
$s
->s3->ua->request(
$req
);
if
(
$res
->header(
'location'
) &&
$res
->content =~ m{>TemporaryRedirect<}s ) {
$req
->uri(
$res
->header(
'location'
) );
$res
=
$s
->s3->ua->request(
$req
);
}
return
$s
->parse_response(
$res
);
}
sub
_sign {
my
(
$s
,
$request
) =
@_
;
my
$signer
=
$s
->signerv4;
if
(
defined
$s
->s3->session_token) {
$request
->header(
'X-Amz-Security-Token'
,
$s
->s3->session_token);
}
my
$digest
= Digest::SHA::sha256_hex(
$request
->content);
$request
->header(
'X-Amz-Content-SHA256'
,
$digest
);
$signer
->sign(
$request
,
$s
->s3->region,
$digest
);
$request
;
}
sub
parse_response {
my
(
$self
,
$res
) =
@_
;
AWS::S3::ResponseParser->new(
response
=>
$res
,
expect_nothing
=>
$self
->_expect_nothing,
type
=>
$self
->type,
);
}
1;