Line 0
Link Here
|
|
|
1 |
--- lib/Net/Amazon/Signature/V4.pm 2013-02-26 19:12:47.000000000 +0000 |
2 |
+++ lib/Net/Amazon/Signature/V4.pm 2014-12-17 12:30:38.000000000 +0000 |
3 |
@@ -1,6 +1,5 @@ |
4 |
package Net::Amazon::Signature::V4; |
5 |
|
6 |
-use 5.10.0; |
7 |
use strict; |
8 |
use warnings; |
9 |
use sort 'stable'; |
10 |
@@ -74,6 +73,15 @@ sub sign { |
11 |
return $request; |
12 |
} |
13 |
|
14 |
+# _headers_to_sign: |
15 |
+# Return the sorted lower case headers as required by the generation of canonical headers |
16 |
+ |
17 |
+sub _headers_to_sign { |
18 |
+ my $req = shift; |
19 |
+ |
20 |
+ return sort { $a cmp $b } map { lc } $req->headers->header_field_names; |
21 |
+} |
22 |
+ |
23 |
# _canonical_request: |
24 |
# Construct the canonical request string from an HTTP::Request. |
25 |
|
26 |
@@ -90,18 +98,17 @@ sub _canonical_request { |
27 |
$creq_canonical_uri = _simplify_uri( $creq_canonical_uri ); |
28 |
$creq_canonical_query_string = _sort_query_string( $creq_canonical_query_string ); |
29 |
|
30 |
- my @sorted_headers = sort { lc($a) cmp lc($b) } $req->headers->header_field_names; |
31 |
+ my @sorted_headers = _headers_to_sign( $req ); |
32 |
my $creq_canonical_headers = join '', |
33 |
map { |
34 |
- sprintf "%s:%s\n", |
35 |
+ sprintf "%s:%s\x0a", |
36 |
lc, |
37 |
join ',', sort {$a cmp $b } _trim_whitespace($req->header($_) ) |
38 |
} |
39 |
@sorted_headers; |
40 |
my $creq_signed_headers = join ';', map {lc} @sorted_headers; |
41 |
my $creq_payload_hash = $req->header('x-amz-content-sha256') ? $req->header('x-amz-content-sha256') : sha256_hex( $req->content ); |
42 |
- |
43 |
- my $creq = join "\n", |
44 |
+ my $creq = join "\x0a", |
45 |
$creq_method, $creq_canonical_uri, $creq_canonical_query_string, |
46 |
$creq_canonical_headers, $creq_signed_headers, $creq_payload_hash; |
47 |
return $creq; |
48 |
@@ -112,13 +119,13 @@ sub _canonical_request { |
49 |
|
50 |
sub _string_to_sign { |
51 |
my ( $self, $req ) = @_; |
52 |
- my $dt = _str_to_datetime( $req->header('Date') ); |
53 |
+ my $dt = _req_datetime( $req ); |
54 |
my $creq = $self->_canonical_request($req); |
55 |
my $sts_request_date = $dt->strftime( '%Y%m%dT%H%M%SZ' ); |
56 |
my $sts_credential_scope = join '/', $dt->strftime('%Y%m%d'), $self->{endpoint}, $self->{service}, 'aws4_request'; |
57 |
my $sts_creq_hash = sha256_hex( $creq ); |
58 |
|
59 |
- my $sts = join "\n", $ALGORITHM, $sts_request_date, $sts_credential_scope, $sts_creq_hash; |
60 |
+ my $sts = join "\x0a", $ALGORITHM, $sts_request_date, $sts_credential_scope, $sts_creq_hash; |
61 |
return $sts; |
62 |
} |
63 |
|
64 |
@@ -128,7 +135,7 @@ sub _string_to_sign { |
65 |
sub _authorization { |
66 |
my ( $self, $req ) = @_; |
67 |
|
68 |
- my $dt = _str_to_datetime( $req->header('Date') ); |
69 |
+ my $dt = _req_datetime( $req ); |
70 |
my $sts = $self->_string_to_sign( $req ); |
71 |
my $k_date = hmac_sha256( $dt->strftime('%Y%m%d'), 'AWS4' . $self->{secret} ); |
72 |
my $k_region = hmac_sha256( $self->{endpoint}, $k_date ); |
73 |
@@ -137,9 +144,9 @@ sub _authorization { |
74 |
|
75 |
my $authz_signature = hmac_sha256_hex( $sts, $k_signing ); |
76 |
my $authz_credential = join '/', $self->{access_key_id}, $dt->strftime('%Y%m%d'), $self->{endpoint}, $self->{service}, 'aws4_request'; |
77 |
- my $authz_signed_headers = join ';', sort { $a cmp $b } map { lc } $req->headers->header_field_names; |
78 |
+ my $authz_signed_headers = join ';', _headers_to_sign( $req ); |
79 |
|
80 |
- my $authz = "$ALGORITHM Credential=$authz_credential, SignedHeaders=$authz_signed_headers, Signature=$authz_signature"; |
81 |
+ my $authz = "$ALGORITHM Credential=$authz_credential,SignedHeaders=$authz_signed_headers,Signature=$authz_signature"; |
82 |
return $authz; |
83 |
|
84 |
} |
85 |
@@ -173,7 +180,7 @@ sub _sort_query_string { |
86 |
my ( $key, $value ) = |
87 |
map { tr/+/ /; uri_escape( uri_unescape( $_ ) ) } # escape all non-unreserved chars |
88 |
split /=/, $param; |
89 |
- push @params, join '=', $key, ($value//''); |
90 |
+ push @params, join '=', $key, (defined $value ? $value : ''); |
91 |
} |
92 |
return join '&', |
93 |
#sort { $a cmp $b } |
94 |
@@ -208,6 +215,16 @@ sub _str_to_datetime { |
95 |
return strptime( '%d %b %Y %H:%M:%S %Z', $date ); |
96 |
} |
97 |
} |
98 |
+sub _req_datetime { |
99 |
+ my $req = shift; |
100 |
+ my $date = $req->header('X-Amz-Date') || $req->header('Date'); |
101 |
+ if (!$date) { |
102 |
+ # No date set by the caller so set one up |
103 |
+ $req->date(time); |
104 |
+ $date = $req->header('Date'); |
105 |
+ } |
106 |
+ return _str_to_datetime($date); |
107 |
+} |
108 |
|
109 |
=head1 BUGS |
110 |
|