File Coverage

blib/lib/Net/Amazon/S3/HTTPRequest.pm
Criterion Covered Total %
statement 61 62 98.3
branch 6 8 75.0
condition 4 7 57.1
subroutine 14 14 100.0
pod 2 2 100.0
total 87 93 93.5


line stmt bran cond sub pod time code
1             $Net::Amazon::S3::HTTPRequest::VERSION = '0.991';
2             use Moose 0.85;
3 99     99   622 use MooseX::StrictConstructor 0.16;
  99         2385  
  99         581  
4 99     99   519987 use HTTP::Date;
  99         1585  
  99         639  
5 99     99   269637 use MIME::Base64 qw( encode_base64 );
  99         229  
  99         6139  
6 99     99   660 use Moose::Util::TypeConstraints;
  99         2516  
  99         4985  
7 99     99   678 use URI::Escape qw( uri_escape_utf8 );
  99         208  
  99         1150  
8 99     99   180780 use URI::QueryParam;
  99         224  
  99         4822  
9 99     99   40974 use URI;
  99         67730  
  99         2847  
10 99     99   591  
  99         188  
  99         1866  
11             use Net::Amazon::S3::Signature::V2;
12 99     99   38078  
  99         257  
  99         64826  
13             # ABSTRACT: Create a signed HTTP::Request
14              
15             my $METADATA_PREFIX = 'x-amz-meta-';
16             my $AMAZON_HEADER_PREFIX = 'x-amz-';
17              
18             enum 'HTTPMethod' => [ qw(DELETE GET HEAD PUT POST) ];
19              
20             with 'Net::Amazon::S3::Role::Bucket';
21             has '+bucket' => (required => 0);
22              
23             has 's3' => ( is => 'ro', isa => 'Net::Amazon::S3', required => 1 );
24             has 'method' => ( is => 'ro', isa => 'HTTPMethod', required => 1 );
25             has 'path' => ( is => 'ro', isa => 'Str', required => 1 );
26             has 'headers' =>
27             ( is => 'ro', isa => 'HashRef', required => 0, default => sub { {} } );
28             has 'content' =>
29             ( is => 'ro', isa => 'Str|CodeRef|ScalarRef', required => 0, default => '' );
30             has 'metadata' =>
31             ( is => 'ro', isa => 'HashRef', required => 0, default => sub { {} } );
32             has use_virtual_host => (
33             is => 'ro',
34             isa => 'Bool',
35             lazy => 1,
36             default => sub { $_[0]->s3->use_virtual_host },
37             );
38             has authorization_method => (
39             is => 'ro',
40             isa => 'Str',
41             lazy => 1,
42             default => sub { $_[0]->s3->authorization_method },
43             );
44             has region => (
45             is => 'ro',
46             isa => 'Str',
47             lazy => 1,
48             default => sub { $_[0]->bucket->region },
49             );
50              
51             has request_uri => (
52             is => 'ro',
53             init_arg => undef,
54             lazy => 1,
55             builder => '_build_uri',
56             );
57              
58             __PACKAGE__->meta->make_immutable;
59              
60             my ($self) = @_;
61              
62 272     272   617 my $path = $self->path;
63              
64 272         6661 my $protocol = $self->s3->secure ? 'https' : 'http';
65             my $host = $self->s3->host;
66 272 50       6296 my $uri = "$protocol://$host/$path";
67 272         6541  
68 272         1028 if ($self->use_virtual_host) {
69             # use https://bucketname.s3.amazonaws.com instead of https://s3.amazonaws.com/bucketname
70 272 100       6927 # see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
71             $uri =~ s{$host/(.*?)/}{$1.$host/};
72             }
73 263         3482  
74             return $uri;
75             }
76 272         7138  
77             # make the HTTP::Request object
78             my $self = shift;
79              
80             my $method = $self->method;
81 218     218   377 my $headers = $self->headers;
82             my $content = $self->content;
83 218         5858 my $metadata = $self->metadata;
84 218         5285  
85 218         5166 my $http_headers = $self->_merge_meta( $headers, $metadata );
86 218         5154 my $uri = $self->request_uri;
87              
88 218         852 my $http_request = HTTP::Request->new( $method, $uri, $http_headers, $content );
89 218         6031 $http_request->content_length (0)
90             if $self->s3->vendor->enforce_empty_content_length
91 218         1498 && ! $http_request->content_length
92 218 100 66     282190 ;
93              
94             return $http_request;
95             }
96              
97 218         15743 my $self = shift;
98              
99             my $request = $self->_build_request;
100              
101 210     210 1 418 $self->authorization_method->new( http_request => $self )->sign_request( $request )
102             unless $request->header( 'Authorization' );
103 210         636  
104             return $request;
105 210 50       768 }
106              
107             my ( $self, $expires ) = @_;
108 210         10399  
109             my $request = $self->_build_request;
110             my $sign = $self->authorization_method->new( http_request => $self );
111              
112 8     8 1 26 return $sign->sign_uri( $request, $expires );
113             }
114 8         23  
115 8         229 my ( $self, $headers, $metadata ) = @_;
116             $headers ||= {};
117 8         4380 $metadata ||= {};
118              
119             my $http_header = HTTP::Headers->new;
120             while ( my ( $k, $v ) = each %$headers ) {
121 218     218   485 $http_header->header( $k => $v );
122 218   50     529 }
123 218   50     491 while ( my ( $k, $v ) = each %$metadata ) {
124             $http_header->header( "$METADATA_PREFIX$k" => $v );
125 218         835 }
126 218         2230  
127 228         5180 return $http_header;
128             }
129 218         5090  
130 0         0 1;
131              
132              
133 218         436 =pod
134              
135             =encoding UTF-8
136              
137             =head1 NAME
138              
139             Net::Amazon::S3::HTTPRequest - Create a signed HTTP::Request
140              
141             =head1 VERSION
142              
143             version 0.991
144              
145             =head1 SYNOPSIS
146              
147             my $http_request = Net::Amazon::S3::HTTPRequest->new(
148             s3 => $self->s3,
149             method => 'PUT',
150             path => $self->bucket . '/',
151             headers => $headers,
152             content => $content,
153             )->http_request;
154              
155             =head1 DESCRIPTION
156              
157             This module creates an HTTP::Request object that is signed
158             appropriately for Amazon S3.
159              
160             =for test_synopsis no strict 'vars'
161              
162             =head1 METHODS
163              
164             =head2 http_request
165              
166             This method creates, signs and returns a HTTP::Request object.
167              
168             =head2 query_string_authentication_uri
169              
170             This method creates, signs and returns a query string authentication
171             URI.
172              
173             =head1 AUTHOR
174              
175             Branislav Zahradník <barney@cpan.org>
176              
177             =head1 COPYRIGHT AND LICENSE
178              
179             This software is copyright (c) 2022 by Amazon Digital Services, Leon Brocard, Brad Fitzpatrick, Pedro Figueiredo, Rusty Conover, Branislav Zahradník.
180              
181             This is free software; you can redistribute it and/or modify it under
182             the same terms as the Perl 5 programming language system itself.
183              
184             =cut