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   63 use strict;
  8         18  
  8         246  
3 8     8   41 use warnings;
  8         17  
  8         226  
4 8     8   42 use URI::Escape qw(uri_escape_utf8);
  8         16  
  8         6680  
5              
6             sub new {
7 23     23 0 48 my $class = shift;
8 23         38 my $bucket = shift;
9 23         55 my $key = shift;
10 23         40 my $query_string = shift;
11              
12 23         82 my $self = {
13             bucket => $bucket,
14             key => $key,
15             query_string => $query_string,
16             };
17 23         97 bless $self, $class;
18             }
19              
20             sub _composer_url {
21 23     23   39 my $self = shift;
22 23         47 my $protocol = shift;
23 23         57 my $host = shift;
24 23         42 my $path = shift;
25              
26 23         101 return "$protocol://$host/$path",
27             }
28              
29             sub to_path_style_url {
30 15     15 0 32 my $self = shift;
31 15         24 my $protocol = shift;
32 15         25 my $region = shift;
33             return $self->_composer_url(
34             $protocol,
35             $self->_region_specific_host($region),
36 15         55 $self->{bucket} . '/' . $self->key_and_query
37             );
38             }
39              
40             sub to_virtual_hosted_style_url {
41 7     7 0 12 my $self = shift;
42 7         13 my $protocol = shift;
43             return $self->_composer_url(
44             $protocol,
45 7         38 sprintf("%s.s3.amazonaws.com", $self->{bucket}),
46             $self->key_and_query
47             );
48             }
49              
50             sub _region_specific_host {
51 15     15   26 my $self = shift;
52 15         33 my $region = shift;
53              
54 15 50       39 if ($region eq 'us-east-1') {
55 0         0 return 's3.amazonaws.com';
56             }
57              
58 15         138 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         2 my $main_host = shift;
67              
68 1         1 my $url;
69              
70 1         16 my $bucket = $self->{bucket};
71 1 50       9 if ($self->_is_dns_bucket($self->{bucket})) {
72             # vhost style
73 1         9 $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         4 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   4 my ($self, $bucketname) = @_;
84              
85 1 50       5 if (length $bucketname > 63) {
86 0         0 return 0;
87             }
88 1 50       4 if (length $bucketname < 3) {
89 0         0 return;
90             }
91 1 50       12 return 0 unless $bucketname =~ m{^[a-z0-9][a-z0-9.-]+$};
92 1         5 my @components = split /\./, $bucketname;
93 1         4 for my $c (@components) {
94 1 50       4 return 0 if $c =~ m{^-};
95 1 50       4 return 0 if $c =~ m{-$};
96 1 50       5 return 0 if $c eq '';
97             }
98 1         23 return 1;
99             }
100              
101              
102             sub key {
103 23     23 0 61 my $self = shift;
104              
105 23         41 my $key;
106 23 100       51 if ($self->{key}) {
107 13         89 $key = $self->urlencode($self->{key}, 1);
108             } else {
109 10         22 $key = '';
110             }
111 23         1345 return $key;
112             }
113              
114             sub add_query {
115 23     23 0 43 my $self = shift;
116              
117 23         37 my $add_query;
118 23 100       53 if ($self->{query_string}) {
119 4         11 $add_query = '?' . $self->{query_string};
120             } else {
121 19         37 $add_query = '';
122             }
123 23         103 return $add_query;
124             }
125              
126             sub key_and_query {
127 23     23 0 60 my $self = shift;
128 23         61 return $self->key . $self->add_query;
129             }
130              
131             sub urlencode {
132 17     17 0 53 my ($self, $unencoded, $allow_slash) = @_;
133 17         32 my $allowed = 'A-Za-z0-9_\-\.';
134 17 100       57 $allowed = "$allowed/" if $allow_slash;
135 17         77 return uri_escape_utf8($unencoded, "^$allowed");
136             }
137              
138             1;