AWS-Signature4

 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 distribution
 view release on metacpan -  search on metacpan

( run in 0.824 second using v1.00-cache-2.02-grep-82fe00e-cpan-72ae3ad1e6da )