cloudfiles 1.5.0 → 1.5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +6 -1
- data/cloudfiles.gemspec +1 -2
- data/lib/client.rb +6 -8
- data/lib/cloudfiles.rb +2 -5
- data/lib/cloudfiles/storage_object.rb +21 -15
- data/lib/cloudfiles/version.rb +1 -1
- data/test/cloudfiles_client_test.rb +6 -6
- data/test/cloudfiles_container_test.rb +1 -1
- metadata +6 -5
data/CHANGELOG
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
================================================================================
|
2
|
-
1.5.0 (2011/
|
2
|
+
1.5.0.1 (2011/12/05
|
3
|
+
================================================================================
|
4
|
+
o Fixed small bug with encoding or URI's
|
5
|
+
|
6
|
+
================================================================================
|
7
|
+
1.5.0 (2011/10/31)
|
3
8
|
================================================================================
|
4
9
|
o The underlying http wrapper now uses client.rb a simple abstraction to manage
|
5
10
|
each ReST call in its own function
|
data/cloudfiles.gemspec
CHANGED
@@ -3,7 +3,6 @@ require File.expand_path('../lib/cloudfiles/version', __FILE__)
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{cloudfiles}
|
5
5
|
s.version = CloudFiles::VERSION
|
6
|
-
|
7
6
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
7
|
s.authors = ["H. Wade Minter", "Rackspace Hosting"]
|
9
8
|
s.description = %q{A Ruby version of the Rackspace Cloud Files API.}
|
@@ -41,7 +40,7 @@ Gem::Specification.new do |s|
|
|
41
40
|
s.homepage = %q{http://www.rackspacecloud.com/cloud_hosting_products/files}
|
42
41
|
s.rdoc_options = ["--charset=UTF-8"]
|
43
42
|
s.require_paths = ["lib"]
|
44
|
-
s.rubygems_version = %q{1.5.0}
|
43
|
+
s.rubygems_version = %q{1.5.0.1}
|
45
44
|
s.summary = %q{A Ruby API into Rackspace Cloud Files}
|
46
45
|
s.test_files = [
|
47
46
|
"test/cf-testunit.rb",
|
data/lib/client.rb
CHANGED
@@ -34,16 +34,13 @@ end
|
|
34
34
|
class ChunkedConnectionWrapper
|
35
35
|
def initialize(data, chunk_size)
|
36
36
|
@size = chunk_size
|
37
|
-
|
38
|
-
@file = data
|
39
|
-
end
|
37
|
+
@file = data
|
40
38
|
end
|
41
39
|
|
42
40
|
def read(foo)
|
43
|
-
|
44
|
-
@file.read(@size)
|
45
|
-
end
|
41
|
+
@file.read(@size)
|
46
42
|
end
|
43
|
+
|
47
44
|
def eof!
|
48
45
|
@file.eof!
|
49
46
|
end
|
@@ -509,8 +506,9 @@ public
|
|
509
506
|
end
|
510
507
|
|
511
508
|
def self.put_object(url, token=nil, container=nil, name=nil, contents=nil,
|
512
|
-
content_length=nil, etag=nil, chunk_size=
|
509
|
+
content_length=nil, etag=nil, chunk_size=nil,
|
513
510
|
content_type=nil, headers={}, http_conn=nil, proxy=nil)
|
511
|
+
chunk_size ||= 65536
|
514
512
|
if not http_conn
|
515
513
|
http_conn = http_connection(url)
|
516
514
|
end
|
@@ -617,4 +615,4 @@ public
|
|
617
615
|
def delete_object(container, name, headers={})
|
618
616
|
_retry(nil, :delete_object, [container, name, headers])
|
619
617
|
end
|
620
|
-
end
|
618
|
+
end
|
data/lib/cloudfiles.rb
CHANGED
@@ -49,11 +49,8 @@ module CloudFiles
|
|
49
49
|
(str.respond_to?(:lines) ? str.lines : str).to_a.map { |x| x.chomp }
|
50
50
|
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
str.gsub(/([^a-zA-Z0-9_.-#{extra_exclude_chars}]+)/) do
|
55
|
-
'%' + $1.unpack('H2' * $1.bytesize).join('%').upcase
|
56
|
-
end
|
52
|
+
def self.escape(str)
|
53
|
+
URI.encode(str)
|
57
54
|
end
|
58
55
|
end
|
59
56
|
|
@@ -17,7 +17,7 @@ module CloudFiles
|
|
17
17
|
@containername = container.name
|
18
18
|
@name = objectname
|
19
19
|
@make_path = make_path
|
20
|
-
@storagepath = "#{CloudFiles.escape @containername}/#{
|
20
|
+
@storagepath = "#{CloudFiles.escape @containername}/#{escaped_name}"
|
21
21
|
|
22
22
|
if force_exists
|
23
23
|
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless container.object_exists?(objectname)
|
@@ -35,7 +35,7 @@ module CloudFiles
|
|
35
35
|
def object_metadata
|
36
36
|
@object_metadata ||= (
|
37
37
|
begin
|
38
|
-
response = SwiftClient.head_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
38
|
+
response = SwiftClient.head_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name)
|
39
39
|
rescue ClientException => e
|
40
40
|
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (e.status.to_s =~ /^20/)
|
41
41
|
end
|
@@ -57,6 +57,10 @@ module CloudFiles
|
|
57
57
|
)
|
58
58
|
end
|
59
59
|
|
60
|
+
def escaped_name
|
61
|
+
@escaped_name ||= escape_name @name
|
62
|
+
end
|
63
|
+
|
60
64
|
# Size of the object (in bytes)
|
61
65
|
def bytes
|
62
66
|
self.object_metadata[:bytes]
|
@@ -95,7 +99,7 @@ module CloudFiles
|
|
95
99
|
headers['Range'] = range
|
96
100
|
end
|
97
101
|
begin
|
98
|
-
response = SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
102
|
+
response = SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name)
|
99
103
|
response[1]
|
100
104
|
rescue ClientException => e
|
101
105
|
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" unless (e.status.to_s =~ /^20/)
|
@@ -122,7 +126,7 @@ module CloudFiles
|
|
122
126
|
headers['Range'] = range
|
123
127
|
end
|
124
128
|
begin
|
125
|
-
SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
129
|
+
SwiftClient.get_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name, nil, nil, &block)
|
126
130
|
end
|
127
131
|
end
|
128
132
|
|
@@ -146,7 +150,7 @@ module CloudFiles
|
|
146
150
|
headers = {}
|
147
151
|
metadatahash.each{ |key, value| headers['X-Object-Meta-' + key.to_s.capitalize] = value.to_s }
|
148
152
|
begin
|
149
|
-
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
153
|
+
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name, headers)
|
150
154
|
true
|
151
155
|
rescue ClientException => e
|
152
156
|
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (e.status.to_s == "404")
|
@@ -174,7 +178,7 @@ module CloudFiles
|
|
174
178
|
def set_manifest(manifest)
|
175
179
|
headers = {'X-Object-Manifest' => manifest}
|
176
180
|
begin
|
177
|
-
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
181
|
+
SwiftClient.post_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name, headers)
|
178
182
|
true
|
179
183
|
rescue ClientException => e
|
180
184
|
raise CloudFiles::Exception::NoSuchObject, "Object #{@name} does not exist" if (response.code == "404")
|
@@ -217,7 +221,7 @@ module CloudFiles
|
|
217
221
|
# If we're taking data from standard input, send that IO object to cfreq
|
218
222
|
data = $stdin if (data.nil? && $stdin.tty? == false)
|
219
223
|
begin
|
220
|
-
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name,
|
224
|
+
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name, data, nil, nil, nil, nil, headers)
|
221
225
|
rescue ClientException => e
|
222
226
|
code = e.status.to_s
|
223
227
|
raise CloudFiles::Exception::InvalidResponse, "Invalid content-length header sent" if (code == "412")
|
@@ -250,7 +254,7 @@ module CloudFiles
|
|
250
254
|
headers = {}
|
251
255
|
headers = {"X-Purge-Email" => email} if email
|
252
256
|
begin
|
253
|
-
SwiftClient.delete_object(self.container.connection.cdnurl, self.container.connection.authtoken, self.container.escaped_name,
|
257
|
+
SwiftClient.delete_object(self.container.connection.cdnurl, self.container.connection.authtoken, self.container.escaped_name, escaped_name, nil, headers)
|
254
258
|
true
|
255
259
|
rescue ClientException => e
|
256
260
|
raise CloudFiles::Exception::Connection, "Error Unable to Purge Object: #{@name}" unless (e.status.to_s =~ /^20.$/)
|
@@ -308,7 +312,6 @@ module CloudFiles
|
|
308
312
|
def save_to_filename(filename)
|
309
313
|
File.open(filename, 'wb+') do |f|
|
310
314
|
self.data_stream do |chunk|
|
311
|
-
puts chunk.length
|
312
315
|
f.write chunk
|
313
316
|
end
|
314
317
|
end
|
@@ -323,7 +326,7 @@ module CloudFiles
|
|
323
326
|
# private_object.public_url
|
324
327
|
# => nil
|
325
328
|
def public_url
|
326
|
-
self.container.public? ? self.container.cdn_url + "/#{
|
329
|
+
self.container.public? ? self.container.cdn_url + "/#{escaped_name}" : nil
|
327
330
|
end
|
328
331
|
|
329
332
|
# If the parent container is public (CDN-enabled), returns the SSL CDN URL to this object. Otherwise, return nil
|
@@ -334,7 +337,7 @@ module CloudFiles
|
|
334
337
|
# private_object.public_ssl_url
|
335
338
|
# => nil
|
336
339
|
def public_ssl_url
|
337
|
-
self.container.public? ? self.container.cdn_ssl_url + "/#{
|
340
|
+
self.container.public? ? self.container.cdn_ssl_url + "/#{escaped_name}" : nil
|
338
341
|
end
|
339
342
|
|
340
343
|
# If the parent container is public (CDN-enabled), returns the SSL CDN URL to this object. Otherwise, return nil
|
@@ -345,7 +348,7 @@ module CloudFiles
|
|
345
348
|
# private_object.public_streaming_url
|
346
349
|
# => nil
|
347
350
|
def public_streaming_url
|
348
|
-
self.container.public? ? self.container.cdn_streaming_url + "/#{
|
351
|
+
self.container.public? ? self.container.cdn_streaming_url + "/#{escaped_name}" : nil
|
349
352
|
end
|
350
353
|
|
351
354
|
# Copy this object to a new location (optionally in a new container)
|
@@ -371,9 +374,9 @@ module CloudFiles
|
|
371
374
|
new_name.sub!(/^\//,'')
|
372
375
|
headers = {'X-Copy-From' => "#{self.container.name}/#{self.name}", 'Content-Type' => self.content_type.sub(/;.+/, '')}.merge(new_headers)
|
373
376
|
# , 'Content-Type' => self.content_type
|
374
|
-
new_path = "#{CloudFiles.escape new_container}/#{
|
377
|
+
new_path = "#{CloudFiles.escape new_container}/#{escape_name new_name}"
|
375
378
|
begin
|
376
|
-
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, (CloudFiles.escape new_container), (
|
379
|
+
response = SwiftClient.put_object(self.container.connection.storageurl, self.container.connection.authtoken, (CloudFiles.escape new_container), escape_name(new_name), nil, nil, nil, nil, nil, headers)
|
377
380
|
return CloudFiles::Container.new(self.container.connection, new_container).object(new_name)
|
378
381
|
rescue ClientException => e
|
379
382
|
code = e.status.to_s
|
@@ -392,11 +395,14 @@ module CloudFiles
|
|
392
395
|
return new_object
|
393
396
|
end
|
394
397
|
|
395
|
-
|
396
398
|
def to_s # :nodoc:
|
397
399
|
@name
|
398
400
|
end
|
399
401
|
|
402
|
+
def escape_name(name)
|
403
|
+
CloudFiles.escape name
|
404
|
+
end
|
405
|
+
|
400
406
|
private
|
401
407
|
|
402
408
|
def cdn_available?
|
data/lib/cloudfiles/version.rb
CHANGED
@@ -34,7 +34,9 @@ class SwiftClientTest < Test::Unit::TestCase
|
|
34
34
|
def test_query
|
35
35
|
query = Query.new("foo=bar&baz=quu")
|
36
36
|
query.add("chunky", "bacon")
|
37
|
-
|
37
|
+
assert_match /chunky=bacon/, query.to_s
|
38
|
+
assert_match /foo=bar/, query.to_s
|
39
|
+
assert_match /baz=quu/, query.to_s
|
38
40
|
assert query.has_key? "chunky"
|
39
41
|
query.delete("chunky")
|
40
42
|
assert_equal false, query.has_key?("chunky")
|
@@ -559,10 +561,8 @@ class SwiftClientTest < Test::Unit::TestCase
|
|
559
561
|
conn.stubs(:head).returns(response)
|
560
562
|
SwiftClient.expects(:http_connection).returns([@parsed, conn])
|
561
563
|
|
562
|
-
|
563
|
-
|
564
|
-
assert response.header, headers
|
565
|
-
end
|
564
|
+
headers = SwiftClient.head_object(@url, @token, 'test_container', 'test_object')
|
565
|
+
assert_equal response.header, headers
|
566
566
|
end
|
567
567
|
|
568
568
|
def test_head_object_fails
|
@@ -794,4 +794,4 @@ class SwiftClientTest < Test::Unit::TestCase
|
|
794
794
|
sc.delete_object('test_container', 'test_object')
|
795
795
|
end
|
796
796
|
end
|
797
|
-
end
|
797
|
+
end
|
@@ -95,7 +95,7 @@ class CloudfilesContainerTest < Test::Unit::TestCase
|
|
95
95
|
CloudFiles::Container.any_instance.stubs(:post_with_headers).returns(nil)
|
96
96
|
@container = CloudFiles::Container.new(connection, 'test_container')
|
97
97
|
assert_nothing_raised do
|
98
|
-
@container.make_public(123)
|
98
|
+
@container.make_public(:ttl => 123)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudfiles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 117
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 5
|
9
9
|
- 0
|
10
|
-
|
10
|
+
- 1
|
11
|
+
version: 1.5.0.1
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- H. Wade Minter
|
@@ -16,7 +17,7 @@ autorequire:
|
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2011-
|
20
|
+
date: 2011-12-06 00:00:00 -06:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
114
|
requirements: []
|
114
115
|
|
115
116
|
rubyforge_project:
|
116
|
-
rubygems_version: 1.
|
117
|
+
rubygems_version: 1.3.7
|
117
118
|
signing_key:
|
118
119
|
specification_version: 3
|
119
120
|
summary: A Ruby API into Rackspace Cloud Files
|