AWS-S3

 view release on metacpan or  search on metacpan

lib/AWS/S3/Signer/V4.pm  view on Meta::CPAN

header.

The request must include a URL from which the AWS endpoint and service
can be derived, such as "ec2.us-east-1.amazonaws.com." In some cases
(e.g. S3 bucket operations) the endpoint does not indicate the
region. In this case, the region can be forced by passing a defined
value for $region. The current date and time will be added to the
request using an "X-Amz-Date header." To force the date and time to a
fixed value, include the "Date" header in the request.

The request content, or "payload" is retrieved from the HTTP::Request
object by calling its content() method.. Under some circumstances the
payload is not included directly in the request, but is in an external
file that will be uploaded as the request is executed. In this case,
you must pass a second argument containing the results of running
sha256_hex() (from the Digest::SHA module) on the content.

The method returns a true value if successful. On errors, it will
throw an exception.

=item $url = $signer->signed_url($request)

This method will generate a signed GET URL for the request. The URL
will include everything needed to perform the request.

=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] [,$verb])

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.

Pass an optional verb which is useful for HEAD requests, this defaults to GET.

=cut

sub signed_url {
    my $self = shift;
    my ( $arg1, $expires, $verb ) = @_;
    my ( $request, $uri );

    $verb ||= 'GET';
    $verb = uc($verb);

    my $incorrect_verbs = {
        POST => 1,
        PUT  => 1
    };

    if ( exists( $incorrect_verbs->{$verb} ) ) {
        die "Use AWS::S3::Signer::V4->sign sub for $verb method";
    }

    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( $verb => $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;
}



( run in 0.448 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )