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 CHANGED
@@ -1,5 +1,10 @@
1
1
  ================================================================================
2
- 1.5.0 (2011/10/31
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
@@ -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",
@@ -34,16 +34,13 @@ end
34
34
  class ChunkedConnectionWrapper
35
35
  def initialize(data, chunk_size)
36
36
  @size = chunk_size
37
- if data.respond_to? :read
38
- @file = data
39
- end
37
+ @file = data
40
38
  end
41
39
 
42
40
  def read(foo)
43
- if @file
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=65536,
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
@@ -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
- # CGI.escape, but without special treatment on spaces
53
- def self.escape(str,extra_exclude_chars = '')
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}/#{CloudFiles.escape @name, '/'}"
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, (CloudFiles.escape self.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, (CloudFiles.escape self.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, (CloudFiles.escape self.name), nil, nil, &block)
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, (CloudFiles.escape self.name), headers)
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, (CloudFiles.escape self.name), headers)
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, (CloudFiles.escape self.name), data, nil, nil, nil, nil, headers)
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, (CloudFiles.escape self.name), nil, headers)
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 + "/#{CloudFiles.escape @name, '/'}" : nil
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 + "/#{CloudFiles.escape @name, '/'}" : nil
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 + "/#{CloudFiles.escape @name, '/'}" : nil
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}/#{CloudFiles.escape new_name, '/'}"
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), (CloudFiles.escape new_name), nil, nil, nil, nil, nil, headers)
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?
@@ -1,3 +1,3 @@
1
1
  module CloudFiles
2
- VERSION = '1.5.0'
2
+ VERSION = '1.5.0.1'
3
3
  end
@@ -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
- assert_equal "chunky=bacon&baz=quu&foo=bar", query.to_s
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
- assert_nothing_raised do
563
- headers = SwiftClient.head_object(@url, @token, 'test_container', 'test_object')
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: 3
5
- prerelease:
4
+ hash: 117
5
+ prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
9
  - 0
10
- version: 1.5.0
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-11-21 00:00:00 -05:00
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.6.0
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