AWS-Signature4
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/AWS/Signature4.pm view on Meta::CPAN
=back
=cut
sub sign {
my $self = shift;
my ($request,$region,$payload_sha256_hex) = @_;
$self->_add_date_header($request);
$self->_sign($request,$region,$payload_sha256_hex);
}
=item my $url $signer->signed_url($request_or_uri [,$expires])
Pass an HTTP::Request, a URI object, or just a plain URL string
containing the proper endpoint and parameters needed for an AWS REST
API Call. This method will return an appropriately signed request as a
URI object, which can be shared with non-AWS users for the purpose of,
e.g., accessing an object in a private S3 bucket.
Pass an optional $expires argument to indicate that the URL will only
be valid for a finite period of time. The value of the argument is in
seconds.
=cut
sub signed_url {
my $self = shift;
my ($arg1,$expires) = @_;
my ($request,$uri);
if (ref $arg1 && UNIVERSAL::isa($arg1,'HTTP::Request')) {
$request = $arg1;
$uri = $request->uri;
my $content = $request->content;
$uri->query($content) if $content;
if (my $date = $request->header('X-Amz-Date') || $request->header('Date')) {
$uri->query_param('Date'=>$date);
}
}
$uri ||= URI->new($arg1);
my $date = $uri->query_param_delete('Date') || $uri->query_param_delete('X-Amz-Date');
$request = HTTP::Request->new(GET=>$uri);
$request->header('Date'=> $date);
$uri = $request->uri; # because HTTP::Request->new() copies the uri!
return $uri if $uri->query_param('X-Amz-Signature');
my $scope = $self->_scope($request);
$uri->query_param('X-Amz-Algorithm' => $self->_algorithm);
$uri->query_param('X-Amz-Credential' => $self->access_key . '/' . $scope);
$uri->query_param('X-Amz-Date' => $self->_datetime($request));
$uri->query_param('X-Amz-Expires' => $expires) if $expires;
$uri->query_param('X-Amz-SignedHeaders' => 'host');
# If there was a security token passed, we need to supply it as part of the authorization
# because AWS requires it to validate IAM Role temporary credentials.
if (defined($self->{security_token})) {
$uri->query_param('X-Amz-Security-Token' => $self->{security_token});
}
# Since we're providing auth via query parameters, we need to include UNSIGNED-PAYLOAD
# http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
# it seems to only be needed for S3.
if ($scope =~ /\/s3\/aws4_request$/) {
$self->_sign($request, undef, 'UNSIGNED-PAYLOAD');
} else {
$self->_sign($request);
}
my ($algorithm,$credential,$signedheaders,$signature) =
$request->header('Authorization') =~ /^(\S+) Credential=(\S+), SignedHeaders=(\S+), Signature=(\S+)/;
$uri->query_param_append('X-Amz-Signature' => $signature);
return $uri;
}
sub _add_date_header {
my $self = shift;
my $request = shift;
my $datetime;
unless ($datetime = $request->header('x-amz-date')) {
$datetime = $self->_zulu_time($request);
$request->header('x-amz-date'=>$datetime);
}
}
sub _scope {
my $self = shift;
my ($request,$region) = @_;
my $host = $request->uri->host;
my $datetime = $self->_datetime($request);
my ($date) = $datetime =~ /^(\d+)T/;
my $service;
if ($host =~ /^([\w.-]+)\.s3\.amazonaws.com/) { # S3 bucket virtual host
$service = 's3';
$region ||= 'us-east-1';
} elsif ($host =~ /^[\w-]+\.s3-([\w-]+)\.amazonaws\.com/) {
$service = 's3';
$region ||= $2;
} elsif ($host =~ /^(\w+)[-.]([\w-]+)\.amazonaws\.com/) {
$service = $1;
$region ||= $2;
} elsif ($host =~ /^([\w-]+)\.amazonaws\.com/) {
$service = $1;
$region = 'us-east-1';
}
$service ||= 's3';
$region ||= 'us-east-1'; # default
return "$date/$region/$service/aws4_request";
}
sub _parse_scope {
my $self = shift;
my $scope = shift;
view all matches for this distributionview release on metacpan - search on metacpan
( run in 0.824 second using v1.00-cache-2.02-grep-82fe00e-cpan-72ae3ad1e6da )