File Coverage

blib/lib/Net/OpenStack/Swift.pm
Criterion Covered Total %
statement 65 302 21.5
branch 6 66 9.0
condition 0 5 0.0
subroutine 13 28 46.4
pod 14 15 93.3
total 98 416 23.5


line stmt bran cond sub pod time code
1             package Net::OpenStack::Swift;
2 5     5   290675 use Carp;
  5         26  
  5         377  
3 5     5   1634 use Mouse;
  5         116528  
  5         25  
4 5     5   2292 use Mouse::Util::TypeConstraints;
  5         13  
  5         22  
5 5     5   3003 use JSON;
  5         48928  
  5         42  
6 5     5   3931 use Path::Tiny;
  5         58751  
  5         395  
7 5     5   2389 use Data::Validator;
  5         16208  
  5         200  
8 5     5   2143 use Net::OpenStack::Swift::Util qw/uri_escape uri_unescape debugf/;
  5         24  
  5         1204  
9 5     5   2123 use Net::OpenStack::Swift::InnerKeystone;
  5         27  
  5         290  
10 5     5   45 use namespace::clean -except => 'meta';
  5         12  
  5         31  
11             our $VERSION = "0.13";
12              
13              
14             subtype 'Path' => as 'Path::Tiny';
15             coerce 'Path' => from 'Str' => via { Path::Tiny->new($_) };
16              
17              
18             has auth_version => (is => 'rw', required => 1, default => sub { $ENV{OS_AUTH_VERSION} || "2.0"});
19             has auth_url => (is => 'rw', required => 1, default => sub { $ENV{OS_AUTH_URL} || '' });
20             has user => (is => 'rw', required => 1, default => sub { $ENV{OS_USERNAME} || '' });
21             has password => (is => 'rw', required => 1, default => sub { $ENV{OS_PASSWORD} || '' });
22             has tenant_name => (is => 'rw', required => 1, default => sub { $ENV{OS_TENANT_NAME} || '' });
23             has region => (is => 'rw', required => 1, default => sub { $ENV{OS_REGION_NAME} || '' });
24             has storage_url => (is => 'rw');
25             has token => (is => 'rw');
26             has agent_options => (is => 'rw', isa => 'HashRef', default => sub{+{ timeout => 10 }});
27             has agent => (
28             is => 'rw',
29             lazy => 1,
30             default => sub {
31             my $self = shift;
32             my $furl_options = +{
33             timeout => $self->agent_options->{timeout} || 10
34             };
35             $furl_options->{agent} ||= $self->agent_options->{user_agent};
36             return Furl->new(%{$furl_options});
37             },
38             );
39              
40             sub _request {
41 0     0   0 my $self = shift;
42 0         0 my $args = shift;
43            
44             my $res = $self->agent->request(
45             method => $args->{method},
46             url => $args->{url},
47             special_headers => $args->{special_headers},
48             headers => $args->{header},
49             write_code => $args->{write_code},
50             write_file => $args->{write_file},
51             content => $args->{content},
52 0         0 );
53 0         0 return $res;
54             }
55              
56             sub auth_keystone {
57 0     0 0 0 my $self = shift;
58 0         0 (my $load_version = $self->auth_version) =~ s/\./_/;
59 0         0 my $ksclient = "Net::OpenStack::Swift::InnerKeystone::V${load_version}"->new(
60             auth_url => $self->auth_url,
61             user => $self->user,
62             password => $self->password,
63             tenant_name => $self->tenant_name,
64             );
65 0         0 $ksclient->agent($self->agent);
66 0         0 my $auth_token = $ksclient->auth();
67 0         0 my $endpoint = $ksclient->service_catalog_url_for(service_type=>'object-store', endpoint_type=>'publicURL', region=>$self->region);
68 0 0       0 croak "Not found endpoint type 'object-store'" unless $endpoint;
69 0         0 $self->token($auth_token);
70 0         0 $self->storage_url($endpoint);
71 0         0 return 1;
72             }
73              
74             sub get_auth {
75 1     1 1 3142 my $self = shift;
76 1         4 $self->auth_keystone();
77 1         113 return ($self->storage_url, $self->token);
78             }
79              
80             sub get_account {
81 1     1 1 590 my $self = shift;
82 1         30 my $rule = Data::Validator->new(
83             url => { isa => 'Str', default => $self->storage_url},
84             token => { isa => 'Str', default => $self->token },
85             marker => { isa => 'Str', default => undef },
86             limit => { isa => 'Int', default => undef },
87             prefix => { isa => 'Str', default => undef },
88             end_marker => { isa => 'Str', default => undef },
89             );
90 1         328 my $args = $rule->validate(@_);
91              
92             # make query strings
93 1         95 my @qs = ('format=json');
94 1 50       6 if ($args->{marker}) {
95 1         8 push @qs, sprintf "marker=%s", uri_escape($args->{marker});
96             }
97 1 50       81 if ($args->{limit}) {
98 0         0 push @qs, sprintf("limit=%d", $args->{limit});
99             }
100 1 50       6 if ($args->{prefix}) {
101 0         0 push @qs, sprintf("prefix=%s", uri_escape($args->{prefix}));
102             }
103 1 50       6 if ($args->{end_marker}) {
104 0         0 push @qs, sprintf("end_marker=%s", uri_escape($args->{end_marker}));
105             }
106              
107 1         4 my $request_header = ['X-Auth-Token' => $args->{token}];
108 1         8 my $request_url = sprintf "%s?%s", $args->{url}, join('&', @qs);
109 1         10 debugf("get_account() request header %s", $request_header);
110 1         7 debugf("get_account() request url: %s", $request_url);
111              
112 1         8 my $res = $self->_request({
113             method => 'GET', url => $request_url, header => $request_header
114             });
115              
116 1 50       231 croak "Account GET failed: ".$res->status_line unless $res->is_success;
117 1         66 my @headers = $res->headers->flatten();
118 1         103 debugf("get_account() response headers %s", \@headers);
119 1         8 debugf("get_account() response body %s", $res->content);
120 1         11 my %headers = @headers;
121 1         5 return (\%headers, from_json($res->content));
122             }
123              
124             sub head_account {
125 0     0 1 0 my $self = shift;
126 0         0 my $rule = Data::Validator->new(
127             url => { isa => 'Str', default => $self->storage_url},
128             token => { isa => 'Str', default => $self->token },
129             );
130 0         0 my $args = $rule->validate(@_);
131              
132 0         0 my $request_header = ['X-Auth-Token' => $args->{token}];
133 0         0 debugf("head_account() request header %s", $request_header);
134 0         0 debugf("head_account() request url: %s", $args->{url});
135              
136             my $res = $self->_request({
137 0         0 method => 'HEAD', url => $args->{url}, header => $request_header
138             });
139              
140 0 0       0 croak "Account HEAD failed: ".$res->status_line unless $res->is_success;
141 0         0 my @headers = $res->headers->flatten();
142 0         0 debugf("head_account() response headers %s", \@headers);
143 0         0 debugf("head_account() response body %s", $res->content);
144 0         0 my %headers = @headers;
145 0         0 return \%headers;
146             }
147              
148             sub post_account {
149 0     0 1 0 my $self = shift;
150 0         0 my $rule = Data::Validator->new(
151             url => { isa => 'Str', default => $self->storage_url},
152             token => { isa => 'Str', default => $self->token },
153             headers => { isa => 'HashRef'},
154             );
155 0         0 my $args = $rule->validate(@_);
156 0         0 my $request_header = ['X-Auth-Token' => $args->{token}];
157 0         0 my @additional_headers = %{ $args->{headers} };
  0         0  
158 0         0 push @{$request_header}, @additional_headers;
  0         0  
159 0         0 my $request_url = $args->{url};
160 0         0 debugf("post_account() request header %s", $request_header);
161 0         0 debugf("post_account() request url: %s", $request_url);
162              
163 0         0 my $res = $self->_request({
164             method => 'POST', url => $request_url, header => $request_header
165             });
166              
167 0 0       0 croak "Account POST failed: ".$res->status_line unless $res->is_success;
168 0         0 my @headers = $res->headers->flatten();
169 0         0 debugf("post_account() response headers %s", \@headers);
170 0         0 debugf("post_account() response body %s", $res->content);
171 0         0 my %headers = @headers;
172 0         0 return \%headers;
173             }
174              
175             sub get_container {
176 0     0 1 0 my $self = shift;
177 0         0 my $rule = Data::Validator->new(
178             url => { isa => 'Str', default => $self->storage_url},
179             token => { isa => 'Str', default => $self->token },
180             container_name => { isa => 'Path', coerce => 1 },
181             marker => { isa => 'Str', default => '', coerce => 1 },
182             limit => { isa => 'Int', default => 0, coerce => 1 },
183             prefix => { isa => 'Str', default => '', coerce => 1 },
184             delimiter => { isa => 'Str', default => '', coerce => 1 },
185             end_marker => { isa => 'Str', default => '', coerce => 1 },
186             full_listing => { isa => 'Bool', default => 0, coerce => 1 },
187             );
188 0         0 my $args = $rule->validate(@_);
189              
190 0 0       0 if ($args->{full_listing}) {
191 0         0 my @full_containers = ();
192             my ($rv_h, $rv_c) = __PACKAGE__->new->get_container(
193             url => $args->{url},
194             token => $args->{token},
195             container_name => $args->{container_name},
196             marker => $args->{marker},
197             limit => $args->{limit},
198             prefix => $args->{prefix},
199             delimiter => $args->{delimiter},
200             end_marker => $args->{end_marker},
201 0         0 );
202 0         0 my $total_count = int $rv_h->{'x-container-object-count'};
203 0         0 my $last_n = scalar @{$rv_c};
  0         0  
204 0 0       0 if (scalar @{$rv_c}) {
  0         0  
205 0         0 push @full_containers, @{$rv_c};
  0         0  
206             }
207 0         0 until ($total_count == scalar @full_containers) {
208             # find marker
209 0         0 my $marker;
210 0 0       0 unless ($args->{delimiter}) {
211 0         0 $marker = $full_containers[scalar(@full_containers) - 1]->{name};
212             }
213             else {
214 0 0       0 if (exists $full_containers[scalar(@full_containers) - 1]->{name}) {
215 0         0 $marker = $full_containers[scalar(@full_containers) - 1]->{name};
216             }
217             else {
218 0         0 $marker = $full_containers[scalar(@full_containers) - 1]->{subdir};
219             }
220             }
221             #
222             my ($rv_h2, $rv_c2) = __PACKAGE__->new->get_container(
223             url => $args->{url},
224             token => $args->{token},
225             container_name => $args->{container_name},
226             marker => $marker,
227             limit => $args->{limit},
228             prefix => $args->{prefix},
229             delimiter => $args->{delimiter},
230             end_marker => $args->{end_marker},
231 0         0 );
232 0 0       0 if (scalar @{$rv_c2}) {
  0         0  
233 0         0 push @full_containers, @{$rv_c2};
  0         0  
234             }
235             else {
236 0         0 last;
237             }
238             }
239 0         0 return ($rv_h, \@full_containers);
240             }
241              
242             # make query strings
243 0         0 my @qs = ('format=json');
244 0 0       0 if ($args->{marker}) {
245 0         0 push @qs, sprintf "marker=%s", uri_escape($args->{marker});
246             }
247 0 0       0 if ($args->{limit}) {
248 0         0 push @qs, sprintf("limit=%d", $args->{limit});
249             }
250 0 0       0 if ($args->{prefix}) {
251 0         0 push @qs, sprintf("prefix=%s", uri_escape($args->{prefix}));
252             }
253 0 0       0 if ($args->{delimiter}) {
254 0         0 push @qs, sprintf("delimiter=%s", uri_escape($args->{delimiter}));
255             }
256 0 0       0 if ($args->{end_marker}) {
257 0         0 push @qs, sprintf("end_marker=%s", uri_escape($args->{end_marker}));
258             }
259              
260 0         0 my $request_header = ['X-Auth-Token' => $args->{token}];
261 0         0 my $request_url = sprintf "%s/%s?%s", $args->{url}, uri_escape($args->{container_name}->stringify), join('&', @qs);
262 0         0 debugf("get_container() request header %s", $request_header);
263 0         0 debugf("get_container() request url: %s", $request_url);
264              
265 0         0 my $res = $self->_request({
266             method => 'GET', url => $request_url, header => $request_header
267             });
268              
269 0 0       0 croak "Container GET failed: ".$res->status_line unless $res->is_success;
270 0         0 my @headers = $res->headers->flatten();
271 0         0 debugf("get_container() response headers %s", \@headers);
272 0         0 debugf("get_container() response body %s", $res->content);
273 0         0 my %headers = @headers;
274 0         0 return (\%headers, from_json($res->content));
275             }
276              
277             sub head_container {
278 0     0 1 0 my $self = shift;
279 0         0 my $rule = Data::Validator->new(
280             url => { isa => 'Str', default => $self->storage_url},
281             token => { isa => 'Str', default => $self->token },
282             container_name => { isa => 'Path', coerce => 1 },
283             );
284 0         0 my $args = $rule->validate(@_);
285              
286 0         0 my $request_header = ['X-Auth-Token' => $args->{token}];
287 0         0 my $request_url = sprintf "%s/%s", $args->{url}, uri_escape($args->{container_name}->stringify);
288 0         0 debugf("head_container() request header %s", $request_header);
289 0         0 debugf("head_container() request url: %s", $args->{url});
290              
291 0         0 my $res = $self->_request({
292             method => 'HEAD', url => $request_url, header => $request_header
293             });
294              
295 0 0       0 croak "Container HEAD failed: ".$res->status_line unless $res->is_success;
296 0         0 my @headers = $res->headers->flatten();
297 0         0 debugf("head_container() response headers %s", \@headers);
298 0         0 debugf("head_container() response body %s", $res->content);
299 0         0 my %headers = @headers;
300 0         0 return \%headers;
301             }
302              
303             sub put_container {
304 2     2 1 1304 my $self = shift;
305             my $rule = Data::Validator->new(
306             url => { isa => 'Str', default => $self->storage_url},
307             token => { isa => 'Str', default => $self->token },
308             container_name => { isa => 'Path', coerce => 1 },
309 2     2   222 content_length => { isa => 'Int', default => sub { 0 } },
310 2         69 content_type => { isa => 'Str', default => 'application/directory'},
311             );
312 2         820 my $args = $rule->validate(@_);
313              
314             my $request_header = [
315             'X-Auth-Token' => $args->{token},
316             'Content-Length' => $args->{content_length},
317             'Content-Type' => $args->{content_type},
318 2         83 ];
319              
320 2         17 my $request_url = sprintf "%s/%s", $args->{url}, uri_escape($args->{container_name}->stringify);
321 2         104 debugf("put_account() request header %s", $request_header);
322 2         19 debugf("put_account() request url: %s", $request_url);
323              
324 2         22 my $res = $self->_request({
325             method => 'PUT', url => $request_url, header => $request_header
326             });
327              
328 2 50       687 croak "Container PUT failed: ".$res->status_line unless $res->is_success;
329 2         192 my @headers = $res->headers->flatten();
330 2         290 debugf("put_container() response headers %s", \@headers);
331 2         25 debugf("put_container() response body %s", $res->content);
332 2         20 my %headers = @headers;
333 2         15 return \%headers;
334             }
335              
336             sub post_container {
337 0     0 1   my $self = shift;
338 0           my $rule = Data::Validator->new(
339             url => { isa => 'Str', default => $self->storage_url},
340             token => { isa => 'Str', default => $self->token },
341             container_name => { isa => 'Path', coerce => 1 },
342             headers => { isa => 'HashRef'},
343             );
344 0           my $args = $rule->validate(@_);
345              
346 0           my $request_header = ['X-Auth-Token' => $args->{token}];
347 0 0 0       unless (exists $args->{headers}->{'Content-Length'} || exists($args->{headers}->{'content-length'})) {
348 0           $args->{headers}->{'Content-Length'} = 0;
349             }
350 0           my @additional_headers = %{ $args->{headers} };
  0            
351 0           push @{$request_header}, @additional_headers;
  0            
352 0           my $request_url = sprintf "%s/%s", $args->{url}, uri_escape($args->{container_name}->stringify);
353 0           debugf("post_container() request header %s", $request_header);
354 0           debugf("post_container() request url: %s", $request_url);
355              
356 0           my $res = $self->_request({
357             method => 'POST', url => $request_url, header => $request_header
358             });
359              
360 0 0         croak "Container POST failed: ".$res->status_line unless $res->is_success;
361 0           my @headers = $res->headers->flatten();
362 0           debugf("post_container() response headers %s", \@headers);
363 0           debugf("post_container() response body %s", $res->content);
364 0           my %headers = @headers;
365 0           return \%headers;
366             }
367              
368             sub delete_container {
369 0     0 1   my $self = shift;
370 0           my $rule = Data::Validator->new(
371             url => { isa => 'Str', default => $self->storage_url},
372             token => { isa => 'Str', default => $self->token },
373             container_name => { isa => 'Path', coerce => 1 },
374             );
375 0           my $args = $rule->validate(@_);
376              
377             # corecing nested path
378             #$args->{container_name} = path($args->{container_name})->stringify;
379              
380 0           my $request_header = ['X-Auth-Token' => $args->{token}];
381 0           my $request_url = sprintf "%s/%s", $args->{url}, uri_escape($args->{container_name}->stringify);
382 0           debugf("delete_container() request header %s", $request_header);
383 0           debugf("delete_container() request url: %s", $request_url);
384              
385 0           my $res = $self->_request({
386             method => 'DELETE', url => $request_url, header => $request_header,
387             content => []
388             });
389              
390 0 0         croak "Container DELETE failed: ".$res->status_line unless $res->is_success;
391 0           my @headers = $res->headers->flatten();
392 0           debugf("delete_container() response headers %s", \@headers);
393 0           debugf("delete_container() response body %s", $res->content);
394 0           my %headers = @headers;
395 0           return \%headers;
396             }
397              
398             sub get_object {
399 0     0 1   my $self = shift;
400 0           my $rule = Data::Validator->new(
401             url => { isa => 'Str', default => $self->storage_url },
402             token => { isa => 'Str', default => $self->token },
403             container_name => { isa => 'Path', coerce => 1 },
404             object_name => { isa => 'Str'},
405             write_file => { isa => 'FileHandle', xor => [qw(write_code)] },
406             write_code => { isa => 'CodeRef' },
407             );
408 0           my $args = $rule->validate(@_);
409              
410 0           my $request_header = ['X-Auth-Token' => $args->{token}];
411             my $request_url = sprintf "%s/%s/%s", $args->{url},
412             uri_escape($args->{container_name}->stringify),
413 0           uri_escape($args->{object_name});
414 0           my %special_headers = ('Content-Length' => undef);
415 0           debugf("get_object() request header %s", $request_header);
416 0           debugf("get_object() request special headers: %s", $request_url);
417 0           debugf("get_object() request url: %s", $request_url);
418              
419 0           my $request_params = {
420             method => 'GET', url => $request_url, header => $request_header,
421             special_headers => \%special_headers,
422             write_code => undef,
423             write_file => undef,
424             };
425 0 0         if (exists $args->{write_code}) {
426 0           $request_params->{write_code} = $args->{write_code};
427             }
428 0 0         if (exists $args->{write_file}) {
429 0           $request_params->{write_file} = $args->{write_file};
430             }
431 0           my $res = $self->_request($request_params);
432              
433 0 0         croak "Object GET failed: ".$res->status_line unless $res->is_success;
434 0           my @headers = $res->headers->flatten();
435 0           debugf("get_object() response headers %s", \@headers);
436 0   0       debugf("get_object() response body length %s byte", length($res->content || 0));
437 0           my %headers = @headers;
438 0           my $etag = $headers{etag};
439 0           $etag =~ s/^\s*(.*?)\s*$/$1/; # delete spaces
440 0           return $etag;
441             }
442              
443             sub head_object {
444 0     0 1   my $self = shift;
445 0           my $rule = Data::Validator->new(
446             url => { isa => 'Str', default => $self->storage_url},
447             token => { isa => 'Str', default => $self->token },
448             container_name => { isa => 'Path', coerce => 1 },
449             object_name => { isa => 'Str'},
450             );
451 0           my $args = $rule->validate(@_);
452              
453 0           my $request_header = ['X-Auth-Token' => $args->{token}];
454             my $request_url = sprintf "%s/%s/%s", $args->{url},
455             uri_escape($args->{container_name}->stringify),
456 0           uri_escape($args->{object_name});
457 0           debugf("head_object() request header %s", $request_header);
458 0           debugf("head_object() request url: %s", $request_url);
459              
460 0           my $res = $self->_request({
461             method => 'HEAD', url => $request_url, header => $request_header,
462             content => []
463             });
464              
465 0 0         croak "Object HEAD failed: ".$res->status_line unless $res->is_success;
466 0           my @headers = $res->headers->flatten();
467 0           debugf("head_object() response headers %s", \@headers);
468 0           debugf("head_object() response body %s", $res->content);
469 0           my %headers = @headers;
470 0           return \%headers;
471             }
472              
473             sub put_object {
474 0     0 1   my $self = shift;
475             my $rule = Data::Validator->new(
476             url => { isa => 'Str', default => $self->storage_url},
477             token => { isa => 'Str', default => $self->token },
478             container_name => { isa => 'Path', coerce => 1 },
479             object_name => { isa => 'Str'},
480             content => { isa => 'Str|FileHandle'},
481 0     0     content_length => { isa => 'Int', default => sub { 0 } },
482             content_type => { isa => 'Str', default => ''},
483             etag => { isa => 'Str', default => undef },
484 0     0     query_string => { isa => 'Str', default => sub {''} },
485 0           );
486 0           my $args = $rule->validate(@_);
487              
488             my $request_header = [
489             'X-Auth-Token' => $args->{token},
490             'Content-Length' => $args->{content_length},
491             'Content-Type' => $args->{content_type},
492 0           ];
493 0 0         if ($args->{etag}) {
494 0           push @{$request_header}, ('ETag' => $args->{etag});
  0            
495             }
496              
497             my $request_url = sprintf "%s/%s/%s", $args->{url},
498             uri_escape($args->{container_name}->stringify),
499 0           uri_escape($args->{object_name});
500 0 0         if ($args->{query_string}) {
501 0           $request_url .= '?'.$args->{query_string};
502             }
503 0           debugf("put_object() request header %s", $request_header);
504 0           debugf("put_object() request url: %s", $request_url);
505              
506             my $res = $self->_request({
507             method => 'PUT', url => $request_url, header => $request_header, content => $args->{content}
508 0           });
509              
510 0 0         croak "Object PUT failed: ".$res->status_line unless $res->is_success;
511 0           my @headers = $res->headers->flatten();
512 0           debugf("put_object() response headers %s", \@headers);
513 0           debugf("put_object() response body %s", $res->content);
514 0           my %headers = @headers;
515 0           my $etag = $headers{etag};
516 0           $etag =~ s/^\s*(.*?)\s*$/$1/; # delete spaces
517 0           return $etag;
518             }
519              
520             sub post_object {
521 0     0 1   my $self = shift;
522 0           my $rule = Data::Validator->new(
523             url => { isa => 'Str', default => $self->storage_url},
524             token => { isa => 'Str', default => $self->token },
525             container_name => { isa => 'Path', coerce => 1 },
526             object_name => { isa => 'Str'},
527             headers => { isa => 'HashRef'},
528             );
529 0           my $args = $rule->validate(@_);
530              
531 0           my $request_header = ['X-Auth-Token' => $args->{token}];
532 0           my @additional_headers = %{ $args->{headers} };
  0            
533 0           push @{$request_header}, @additional_headers;
  0            
534             my $request_url = sprintf "%s/%s/%s", $args->{url},
535             uri_escape($args->{container_name}->stringify),
536 0           uri_escape($args->{object_name});
537 0           debugf("post_object() request header %s", $request_header);
538 0           debugf("post_object() request url: %s", $request_url);
539              
540 0           my $res = $self->_request({
541             method => 'POST', url => $request_url, header => $request_header
542             });
543              
544 0 0         croak "Object POST failed: ".$res->status_line unless $res->is_success;
545 0           my @headers = $res->headers->flatten();
546 0           debugf("post_object() response headers %s", \@headers);
547 0           debugf("post_object() response body %s", $res->content);
548 0           my %headers = @headers;
549 0           return \%headers;
550             }
551              
552             sub delete_object {
553 0     0 1   my $self = shift;
554 0           my $rule = Data::Validator->new(
555             url => { isa => 'Str', default => $self->storage_url},
556             token => { isa => 'Str', default => $self->token },
557             container_name => { isa => 'Path', coerce => 1 },
558             object_name => { isa => 'Str'},
559             );
560 0           my $args = $rule->validate(@_);
561              
562 0           my $request_header = ['X-Auth-Token' => $args->{token}];
563             my $request_url = sprintf "%s/%s/%s", $args->{url},
564             uri_escape($args->{container_name}->stringify),
565 0           uri_escape($args->{object_name});
566 0           debugf("delete_object() request header %s", $request_header);
567 0           debugf("delete_object() request url: %s", $request_url);
568              
569 0           my $res = $self->_request({
570             method => 'DELETE', url => $request_url, header => $request_header,
571             content => []
572             });
573              
574 0 0         croak "Object DELETE failed: ".$res->status_line unless $res->is_success;
575 0           my @headers = $res->headers->flatten();
576 0           debugf("delete_object() response headers %s", \@headers);
577 0           debugf("delete_object() response body %s", $res->content);
578 0           my %headers = @headers;
579 0           return \%headers;
580             }
581              
582             1;
583             __END__