/
HTTPRequest.pm
113 lines (90 loc) · 2.71 KB
/
HTTPRequest.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package AWS::S3::HTTPRequest;
use Moose;
use AWS::S3::Signer;
use Carp 'confess';
use HTTP::Date 'time2str';
use MIME::Base64 qw(encode_base64);
use URI::Escape qw(uri_escape_utf8);
use Digest::HMAC_SHA1;
use URI;
my $METADATA_PREFIX = 'x-amz-meta-';
my $AMAZON_HEADER_PREFIX = 'x-amz-';
enum 'HTTPMethod' => [qw( HEAD GET PUT POST DELETE )];
has 's3' => (
is => 'ro',
required => 1,
isa => 'AWS::S3',
);
has 'method' => (
is => 'ro',
required => 1,
isa => 'HTTPMethod'
);
has 'path' => (
is => 'ro',
required => 1,
isa => 'Str',
);
has 'headers' => (
is => 'ro',
required => 1,
isa => 'HTTP::Headers',
lazy => 1,
default => sub { HTTP::Headers->new() },
coerce => 1,
);
coerce 'HTTP::Headers' => from 'HashRef' => via { my $h = HTTP::Headers->new( %$_ ) };
has 'content' => (
is => 'ro',
required => 1,
isa => 'Str|ScalarRef|CodeRef',
default => '',
);
has 'metadata' => (
is => 'ro',
required => 1,
isa => 'HashRef',
default => sub { {} },
);
has 'contenttype' => (
is => 'ro',
required => 0,
isa => 'Str',
);
# Make the HTTP::Request object:
sub http_request {
my $s = shift;
my $method = $s->method;
my $path = $s->path;
my $headers = $s->headers;
my $content = $s->content;
my $metadata = $s->metadata;
my $protocol = $s->s3->secure ? 'https' : 'http';
my $endpoint = $s->s3->endpoint;
my $uri = "$protocol://$endpoint/$path";
if ( $path =~ m{^([^/?]+)(.*)} && _is_dns_bucket( $1 ) ) {
$uri = "$protocol://$1.$endpoint$2";
} # end if()
my $signer = AWS::S3::Signer->new(
s3 => $s->s3,
method => $method,
uri => $uri,
content => $content ? \$content : undef,
headers => $headers,
);
$headers->header( 'Authorization' => $signer->auth_header );
$headers->header( 'Date' => $signer->date );
$headers->header( 'Host' => URI->new( $uri )->host );
$headers->header( 'content-length' => $signer->content_length ) if $content;
$headers->header( 'content-type' => $signer->content_type ) if $content;
my $request = HTTP::Request->new( $method, $uri, $headers, $content );
if ( $uri =~ m{location} && 1 || $method eq 'PUT' ) {
# warn "StringToSign(" . $signer->string_to_sign . ")";
# warn "canonicalized_amz_headers(" . $signer->canonicalized_amz_headers . ")";
# warn "Request(" . $request->as_string . ")";
} # end if()
return $request;
} # end http_request()
# XXX: Not needed by us...
sub _is_dns_bucket { 1 }
__PACKAGE__->meta->make_immutable;