File Coverage

blib/lib/Net/Amazon/S3/Request.pm
Criterion Covered Total %
statement 38 38 100.0
branch 11 12 91.6
condition 2 3 66.6
subroutine 16 16 100.0
pod 0 1 0.0
total 67 70 95.7


line stmt bran cond sub pod time code
1             package Net::Amazon::S3::Request;
2             $Net::Amazon::S3::Request::VERSION = '0.99';
3 99     99   786 use Moose 0.85;
  99         2711  
  99         869  
4 99     99   690203 use MooseX::StrictConstructor 0.16;
  99         2167  
  99         805  
5 99     99   337908 use Moose::Util::TypeConstraints;
  99         324  
  99         1037  
6 99     99   282139 use Regexp::Common qw /net/;
  99         287038  
  99         510  
7              
8             # ABSTRACT: Base class for request objects
9              
10 99     99   313075 use Net::Amazon::S3::Constraint::ACL::Canned;
  99         341  
  99         106819  
11              
12             enum 'LocationConstraint' => [
13             # https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region
14             # https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html#API_CreateBucket_RequestSyntax
15             'af-south-1',
16             'ap-east-1',
17             'ap-northeast-1',
18             'ap-northeast-2',
19             'ap-northeast-3',
20             'ap-south-1',
21             'ap-southeast-1',
22             'ap-southeast-2',
23             'ca-central-1',
24             'cn-north-1',
25             'cn-northwest-1',
26             'EU',
27             'eu-central-1',
28             'eu-north-1',
29             'eu-south-1',
30             'eu-west-1',
31             'eu-west-2',
32             'eu-west-3',
33             'me-south-1',
34             'sa-east-1',
35             'us-east-1',
36             'us-east-2',
37             'us-gov-east-1',
38             'us-gov-west-1',
39             'us-west-1',
40             'us-west-2',
41             ];
42              
43             subtype 'MaybeLocationConstraint'
44             => as 'Maybe[LocationConstraint]'
45             ;
46              
47             # maintain backward compatiblity with 'US' and 'EU' values
48             my %location_constraint_alias = (
49             US => 'us-east-1',
50             EU => 'eu-west-1',
51             );
52              
53             enum 'LocationConstraintAlias' => [ keys %location_constraint_alias ];
54              
55             coerce 'LocationConstraint'
56             => from 'LocationConstraintAlias'
57             => via { $location_constraint_alias{$_} }
58             ;
59              
60             coerce 'MaybeLocationConstraint'
61             => from 'LocationConstraintAlias'
62             => via { $location_constraint_alias{$_} }
63             ;
64              
65             # To comply with Amazon S3 requirements, bucket names must:
66             # Contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)
67             # Start with a number or letter
68             # Be between 3 and 255 characters long
69             # Not be in an IP address style (e.g., "192.168.5.4")
70              
71             subtype 'BucketName1' => as 'Str' => where {
72             $_ =~ /^[a-zA-Z0-9._-]+$/;
73             } => message {
74             "Bucket name ($_) must contain lowercase letters, numbers, periods (.), underscores (_), and dashes (-)";
75             };
76              
77             subtype 'BucketName2' => as 'BucketName1' => where {
78             $_ =~ /^[a-zA-Z0-9]/;
79             } => message {
80             "Bucket name ($_) must start with a number or letter";
81             };
82              
83             subtype 'BucketName3' => as 'BucketName2' => where {
84             length($_) >= 3 && length($_) <= 255;
85             } => message {
86             "Bucket name ($_) must be between 3 and 255 characters long";
87             };
88              
89             subtype 'BucketName' => as 'BucketName3' => where {
90             $_ !~ /^$RE{net}{IPv4}$/;
91             } => message {
92             "Bucket name ($_) must not be in an IP address style (e.g., '192.168.5.4')";
93             };
94              
95             has 's3' => ( is => 'ro', isa => 'Net::Amazon::S3', required => 1 );
96              
97             has '_http_request_content' => (
98             is => 'ro',
99             init_arg => undef,
100             isa => 'Maybe[Str]',
101             lazy => 1,
102             builder => '_request_content',
103             );
104              
105             __PACKAGE__->meta->make_immutable;
106              
107             sub _request_content {
108 139     139   4021 '';
109             }
110              
111             sub _request_path {
112 430     430   18201 '';
113             }
114              
115       358     sub _request_headers {
116             }
117              
118       464     sub _request_query_action {
119             }
120              
121       416     sub _request_query_params {
122             }
123              
124             sub _request_query_string {
125 416     416   13802 my ($self) = @_;
126              
127 416         1717 my %query_params = $self->_request_query_params;
128              
129 416         2275 my @parts = (
130             ($self->_request_query_action) x!! $self->_request_query_action,
131 74         3179 map "$_=${\ $self->s3->_urlencode( $query_params{$_} ) }", sort keys %query_params,
132             );
133              
134 416 100       4457 return '' unless @parts;
135 232         1458 return '?' . join '&', @parts;
136             }
137              
138             sub _http_request_path {
139 416     416   1107 my ($self) = @_;
140              
141 416         2196 return $self->_request_path . $self->_request_query_string;
142             }
143              
144             sub _http_request_headers {
145 430     430   1043 my ($self) = @_;
146              
147 430         1774 return +{ $self->_request_headers };
148             }
149              
150             sub _build_signed_request {
151 430     430   1454 my ($self, %params) = @_;
152              
153 430 100       2519 $params{path} = $self->_http_request_path unless exists $params{path};
154 430 100       18068 $params{method} = $self->_http_request_method unless exists $params{method};
155 430 50       2292 $params{headers} = $self->_http_request_headers unless exists $params{headers};
156 430 100 66     12932 $params{content} = $self->_http_request_content unless exists $params{content} or ! defined $self->_http_request_content;
157              
158             # Although Amazon's Signature 4 test suite explicitely handles // it appears
159             # it's inconsistent with their implementation so removing it here
160 430         1414 $params{path} =~ s{//+}{/}g;
161              
162 430 100       12283 return Net::Amazon::S3::HTTPRequest->new(
163             %params,
164             s3 => $self->s3,
165             $self->can( 'bucket' ) ? (bucket => $self->bucket) : (),
166             );
167             }
168              
169             sub _build_http_request {
170 210     210   770 my ($self, %params) = @_;
171              
172 210         1096 return $self->_build_signed_request( %params )->http_request;
173             }
174              
175             sub http_request {
176 294     294 0 695 my $self = shift;
177              
178 294         1117 return $self->_build_http_request;
179             }
180              
181             1;
182              
183             __END__
184              
185             =pod
186              
187             =encoding UTF-8
188              
189             =head1 NAME
190              
191             Net::Amazon::S3::Request - Base class for request objects
192              
193             =head1 VERSION
194              
195             version 0.99
196              
197             =head1 SYNOPSIS
198              
199             # do not instantiate directly
200              
201             =head1 DESCRIPTION
202              
203             This module is a base class for all the Net::Amazon::S3::Request::*
204             classes.
205              
206             =head1 AUTHOR
207              
208             Branislav Zahradník <barney@cpan.org>
209              
210             =head1 COPYRIGHT AND LICENSE
211              
212             This software is copyright (c) 2021 by Amazon Digital Services, Leon Brocard, Brad Fitzpatrick, Pedro Figueiredo, Rusty Conover, Branislav Zahradník.
213              
214             This is free software; you can redistribute it and/or modify it under
215             the same terms as the Perl 5 programming language system itself.
216              
217             =cut