File Coverage

blib/lib/Amazon/S3/Thin/Resource.pm
Criterion Covered Total %
statement 67 71 94.3
branch 14 22 63.6
condition n/a
subroutine 14 14 100.0
pod 0 8 0.0
total 95 115 82.6


line stmt bran cond sub pod time code
1             package Amazon::S3::Thin::Resource;
2 8     8   46 use strict;
  8         15  
  8         204  
3 8     8   39 use warnings;
  8         17  
  8         186  
4 8     8   35 use URI::Escape qw(uri_escape_utf8);
  8         16  
  8         5593  
5              
6             sub new {
7 23     23 0 45 my $class = shift;
8 23         35 my $bucket = shift;
9 23         43 my $key = shift;
10 23         33 my $query_string = shift;
11              
12 23         75 my $self = {
13             bucket => $bucket,
14             key => $key,
15             query_string => $query_string,
16             };
17 23         100 bless $self, $class;
18             }
19              
20             sub _composer_url {
21 23     23   37 my $self = shift;
22 23         36 my $protocol = shift;
23 23         40 my $host = shift;
24 23         30 my $path = shift;
25              
26 23         90 return "$protocol://$host/$path",
27             }
28              
29             sub to_path_style_url {
30 15     15 0 24 my $self = shift;
31 15         26 my $protocol = shift;
32 15         24 my $region = shift;
33             return $self->_composer_url(
34             $protocol,
35             $self->_region_specific_host($region),
36 15         47 $self->{bucket} . '/' . $self->key_and_query
37             );
38             }
39              
40             sub to_virtual_hosted_style_url {
41 7     7 0 8 my $self = shift;
42 7         10 my $protocol = shift;
43             return $self->_composer_url(
44             $protocol,
45 7         32 sprintf("%s.s3.amazonaws.com", $self->{bucket}),
46             $self->key_and_query
47             );
48             }
49              
50             sub _region_specific_host {
51 15     15   37 my $self = shift;
52 15         21 my $region = shift;
53              
54 15 50       41 if ($region eq 'us-east-1') {
55 0         0 return 's3.amazonaws.com';
56             }
57              
58 15         133 return sprintf('s3.%s.amazonaws.com', $region); # 's3.eu-west-1.amazonaws.com'
59             }
60              
61              
62             # to keep B.C. for old implementation in case region is not given
63             sub to_url_without_region {
64 1     1 0 3 my $self = shift;
65 1         2 my $protocol = shift;
66 1         1 my $main_host = shift;
67              
68 1         2 my $url;
69              
70 1         5 my $bucket = $self->{bucket};
71 1 50       2 if ($self->_is_dns_bucket($self->{bucket})) {
72             # vhost style
73 1         11 $url = $self->_composer_url($protocol, $bucket . '.' . $main_host, $self->key_and_query);
74             } else {
75             # path style
76 0         0 $url = $self->_composer_url($protocol, $main_host, $self->{bucket} . "/" . $self->key_and_query);
77             }
78 1         3 return $url;
79             }
80              
81             # if a given bucket name can be safely used as a DNS name.
82             sub _is_dns_bucket {
83 1     1   3 my ($self, $bucketname) = @_;
84              
85 1 50       4 if (length $bucketname > 63) {
86 0         0 return 0;
87             }
88 1 50       3 if (length $bucketname < 3) {
89 0         0 return;
90             }
91 1 50       8 return 0 unless $bucketname =~ m{^[a-z0-9][a-z0-9.-]+$};
92 1         4 my @components = split /\./, $bucketname;
93 1         3 for my $c (@components) {
94 1 50       3 return 0 if $c =~ m{^-};
95 1 50       4 return 0 if $c =~ m{-$};
96 1 50       3 return 0 if $c eq '';
97             }
98 1         18 return 1;
99             }
100              
101              
102             sub key {
103 23     23 0 53 my $self = shift;
104              
105 23         34 my $key;
106 23 100       49 if ($self->{key}) {
107 13         61 $key = $self->urlencode($self->{key}, 1);
108             } else {
109 10         20 $key = '';
110             }
111 23         1169 return $key;
112             }
113              
114             sub add_query {
115 23     23 0 41 my $self = shift;
116              
117 23         31 my $add_query;
118 23 100       55 if ($self->{query_string}) {
119 4         8 $add_query = '?' . $self->{query_string};
120             } else {
121 19         29 $add_query = '';
122             }
123 23         88 return $add_query;
124             }
125              
126             sub key_and_query {
127 23     23 0 52 my $self = shift;
128 23         54 return $self->key . $self->add_query;
129             }
130              
131             sub urlencode {
132 17     17 0 38 my ($self, $unencoded, $allow_slash) = @_;
133 17         30 my $allowed = 'A-Za-z0-9_\-\.';
134 17 100       52 $allowed = "$allowed/" if $allow_slash;
135 17         73 return uri_escape_utf8($unencoded, "^$allowed");
136             }
137              
138             1;