s33r 0.5.2 → 0.5.3

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.
@@ -40,8 +40,9 @@ class BrowserController < ApplicationController
40
40
  def delete
41
41
  bucket_name = params[:bucket_name]
42
42
  resource_key = params[:resource_key]
43
+
43
44
  if resource_key
44
- @s3.do_delete(:bucket => bucket_name, :key => resource_key)
45
+ @s3.do_delete(:bucket => bucket_name, :key => resource_key.to_s)
45
46
  to_url = url_for(:action => 'show_bucket', :bucket_name => bucket_name)
46
47
  notice = "Resource"
47
48
  else
@@ -1,6 +1,6 @@
1
- <%= start_form_tag :action => 'create_bucket' %>
1
+ <% form_for '', :url => {:action => 'create_bucket'} do %>
2
2
  <p>Create a new bucket: <%= text_field 'bucket', 'name' %></p>
3
3
  <p>Use your default bucket prefix (<strong><%= @default_prefix %></strong>)?
4
4
  <%= check_box_tag 'bucket[prefix]', 1, true %></p>
5
5
  <p><%= submit_tag 'Create' %></p>
6
- <%= end_form_tag %>
6
+ <% end %>
@@ -1,5 +1,5 @@
1
- <%= start_form_tag({:action => 'upload'}, :multipart => true) %>
1
+ <% form_for '', :url => {:action => 'upload'}, :html => {:multipart => true} do %>
2
2
  <%= hidden_field 'upload', 'bucket_name', :value => @bucket_name %>
3
3
  <p>Upload a file to this bucket:<br /><%= file_field('upload', 'filename', :size => 20) %></p>
4
4
  <p><%= submit_tag 'Upload' %></p>
5
- <%= end_form_tag %>
5
+ <% end %>
@@ -5,7 +5,7 @@
5
5
  # ENV['RAILS_ENV'] ||= 'production'
6
6
 
7
7
  # Specifies gem version of Rails to use when vendor/rails is not present
8
- RAILS_GEM_VERSION = '1.1.6'
8
+ RAILS_GEM_VERSION = '1.2.1'
9
9
 
10
10
  # Bootstrap the Rails environment, frameworks, and default configuration
11
11
  require File.join(File.dirname(__FILE__), 'boot')
@@ -63,4 +63,4 @@ config, S3_OPTIONS =
63
63
 
64
64
  options = config.merge(S3_OPTIONS)
65
65
 
66
- S3_CLIENT = S33r::Client.new(options)
66
+ S3_CLIENT = S33r::Client.new(options)
@@ -13,11 +13,17 @@ ActionController::Routing::Routes.draw do |map|
13
13
  # -- just remember to delete public/index.html.
14
14
  map.connect '', :controller => 'browser'
15
15
 
16
- map.connect '/show_bucket/:bucket_name', :controller => 'browser', :action => 'show_bucket'
17
- map.connect '/plain_bucket/:bucket_name/listing.txt', :controller => 'browser', :action => 'plain_bucket'
18
- map.connect '/add_index/:bucket_name', :controller => 'browser', :action => 'add_index'
19
- map.connect '/delete/:bucket_name', :controller => 'browser', :action => 'delete'
20
- map.connect '/delete/:bucket_name/:resource_key', :controller => 'browser', :action => 'delete'
16
+ bucket = { :bucket_name => /.*/ }
17
+ map.connect '/show_bucket/:bucket_name', :controller => 'browser', :action => 'show_bucket',
18
+ :requirements => bucket
19
+ map.connect '/plain_bucket/:bucket_name/listing.txt', :controller => 'browser', :action => 'plain_bucket',
20
+ :requirements => bucket
21
+ map.connect '/add_index/:bucket_name', :controller => 'browser', :action => 'add_index',
22
+ :requirements => bucket
23
+ map.connect '/delete/:bucket_name/key/:resource_key', :controller => 'browser', :action => 'delete',
24
+ :requirements => bucket.merge({:resource_key => /.*/})
25
+ map.connect '/delete/:bucket_name', :controller => 'browser', :action => 'delete',
26
+ :requirements => bucket
21
27
  map.connect '/create_bucket', :controller => 'browser', :action => 'create_bucket'
22
28
 
23
29
  # Install the default route as the lowest priority.
data/lib/s33r.rb CHANGED
@@ -10,15 +10,25 @@ require 'net/https'
10
10
  require 'stringio'
11
11
 
12
12
  require 'rubygems'
13
- require_gem 'builder'
13
+
14
+ if respond_to? 'gem'
15
+ gem 'builder'
16
+ else
17
+ require_gem 'builder'
18
+ end
19
+
14
20
 
15
21
  begin
16
22
  require 'xml/libxml'
17
23
  rescue LoadError
18
- require_gem 'libxml-ruby'
24
+ if respond_to? 'gem'
25
+ gem 'libxml-ruby'
26
+ else
27
+ require_gem 'libxml-ruby'
28
+ end
19
29
  end
20
30
 
21
- to_load = ['mimetypes', 'builder', 'libxml_extensions', 's33r_http', 'networking',
31
+ to_load = ['mimetypes', 'orderly_xml_markup', 'libxml_extensions', 's33r_http', 'networking',
22
32
  's33r_exception', 'utility', 's3_acl', 's3_logging', 'bucket_listing', 'client', 'bucket', 's3_obj']
23
33
 
24
34
  base = File.join(File.dirname(__FILE__), 's33r')
data/lib/s33r/client.rb CHANGED
@@ -211,10 +211,12 @@ module S33r
211
211
  # Delete a Bucket.
212
212
  #
213
213
  # +options+:
214
- # * <tt>:force => true</tt>: To clear the content of the bucket first.
214
+ # * <tt>:force => true</tt>: To clear the content of the bucket first. This option adds :escape => true to ensure bucket deletion.
215
+ # * <tt>:escape => true</tt>: CGI::escape keys when they are appended to the path.
215
216
  def delete_bucket(bucket_name, options={})
216
217
  options[:bucket] = bucket_name
217
218
  if options[:force]
219
+ options[:escape] = true
218
220
  listing(options).keys.each { |key| do_delete(options.merge(:key => key)) }
219
221
  end
220
222
  do_delete(options).ok?
@@ -1,6 +1,8 @@
1
+ require 'builder'
2
+
1
3
  module S33r
2
4
  # Variant of XmlMarkup which explicitly orders attributes.
3
- class OrderlyXmlMarkup < Builder::XmlMarkup
5
+ class OrderlyXmlMarkup < ::Builder::XmlMarkup
4
6
 
5
7
  # Override Builder _insert_attributes so attributes are ordered.
6
8
  def _insert_attributes(attrs, order=[])
data/lib/s33r/utility.rb CHANGED
@@ -281,7 +281,8 @@ module S33r
281
281
  str
282
282
  end
283
283
 
284
- # Returns the path for this bucket and key.
284
+ # Returns the path for this bucket and key. By default, keys are not CGI-escaped; if you want
285
+ # escaping, use the <tt>:escape => true</tt> option.
285
286
  #
286
287
  # +options+:
287
288
  # * <tt>:bucket => 'my-bucket'</tt>: get a path which includes the bucket (unless
@@ -293,6 +294,7 @@ module S33r
293
294
  # * <tt>:subdomain => true</tt>: don't include the bucket name in the path.
294
295
  # * <tt>:acl => true</tt>: append ?acl to the front of the querystring.
295
296
  # * <tt>:logging => true</tt>: append ?logging to the start of the querystring.
297
+ # * <tt>:escape => true</tt>: CGI::escape keys when they are appended to the path.
296
298
  def s3_path(options={})
297
299
  bucket = options[:bucket]
298
300
  key = options[:key]
@@ -308,7 +310,10 @@ module S33r
308
310
 
309
311
  path = '/'
310
312
  path += (bucket + '/') if bucket and !options[:subdomain]
311
- path += key if key
313
+ if key
314
+ key = CGI::escape(key) if options[:escape]
315
+ path += key
316
+ end
312
317
  path += '?' + qstring unless '' == qstring
313
318
  path
314
319
  end
@@ -42,32 +42,32 @@ context 'S33r ACL functions' do
42
42
  end
43
43
 
44
44
  specify 'should represent a grant for a CanonicalUser' do
45
- clean_xml(@canonical_user_grant.to_xml).should.equal @acl_grant_xml1
45
+ clean_xml(@canonical_user_grant.to_xml).should == @acl_grant_xml1
46
46
  end
47
47
 
48
48
  specify 'should represent a grant for an AmazonUserByEmail' do
49
- clean_xml(@amazon_grant.to_xml).should.equal @acl_grant_xml2
49
+ clean_xml(@amazon_grant.to_xml).should == @acl_grant_xml2
50
50
  end
51
51
 
52
52
  specify 'should represent a grant for AllUsers' do
53
- clean_xml(@group_grant.to_xml).should.equal @acl_grant_xml3
53
+ clean_xml(@group_grant.to_xml).should == @acl_grant_xml3
54
54
  end
55
55
 
56
56
  specify 'should represent a grant for AuthenticatedUsers' do
57
- clean_xml(@group_grant2.to_xml).should.equal @acl_grant_xml4
57
+ clean_xml(@group_grant2.to_xml).should == @acl_grant_xml4
58
58
  end
59
59
 
60
60
  specify 'should generate a valid AccessControlPolicy document' do
61
- clean_xml(@full_acl_doc.to_xml).should.equal @full_acl_xml
61
+ clean_xml(@full_acl_doc.to_xml).should == @full_acl_xml
62
62
  end
63
63
 
64
64
  specify 'should provide convenience classes for grants' do
65
- clean_xml(@con_full_acl_doc.to_xml).should.equal @full_acl_xml
65
+ clean_xml(@con_full_acl_doc.to_xml).should == @full_acl_xml
66
66
  end
67
67
 
68
68
  specify 'needs equality method for grantees' do
69
69
  test_grantee = Group.new(:all_users)
70
- test_grantee.should.equal @group_grantee
70
+ test_grantee.should == @group_grantee
71
71
  test_grantee.should.not.equal @amazon_grantee
72
72
  end
73
73
 
@@ -82,7 +82,7 @@ context 'S33r ACL functions' do
82
82
  "</Grantee>"
83
83
  doc = XML.get_xml_doc(xml)
84
84
  grantee = Grantee.from_xml(doc)
85
- grantee.should.equal @amazon_grantee
85
+ grantee.should == @amazon_grantee
86
86
  end
87
87
 
88
88
  specify 'should correctly create Group grantee from XML node' do
@@ -91,7 +91,7 @@ context 'S33r ACL functions' do
91
91
  "</Grantee>"
92
92
  doc = XML.get_xml_doc(xml)
93
93
  grantee = Grantee.from_xml(doc)
94
- grantee.should.equal @group_grantee
94
+ grantee.should == @group_grantee
95
95
  end
96
96
 
97
97
  specify 'should correctly create Group grantee for AuthenticatedUsers from XML node' do
@@ -100,14 +100,14 @@ context 'S33r ACL functions' do
100
100
  "</Grantee>"
101
101
  doc = XML.get_xml_doc(xml)
102
102
  grantee = Grantee.from_xml(doc)
103
- grantee.should.equal @group_grantee2
103
+ grantee.should == @group_grantee2
104
104
  p grantee.group_type
105
105
  p @group_grantee2.group_type
106
106
  end
107
107
 
108
108
  specify 'should parse AccessControlPolicy documents' do
109
109
  acl_doc_from_xml = Policy.from_xml(@full_acl_xml)
110
- acl_doc_from_xml.owner.should.equal @full_acl_doc.owner
110
+ acl_doc_from_xml.owner.should == @full_acl_doc.owner
111
111
  @full_acl_doc.grants.each do |g|
112
112
  acl_doc_from_xml.grants = acl_doc_from_xml.grants.delete_if { |i| i == g }
113
113
  end
@@ -35,22 +35,22 @@ context 'S33r bucket listing' do
35
35
  end
36
36
 
37
37
  specify 'should present bucket metadata as typed properties' do
38
- @bucket_listing.name.should.equal('testingtesting')
39
- @bucket_listing.prefix.should.equal('')
40
- @bucket_listing.marker.should.equal('')
41
- @bucket_listing.max_keys.should.equal(1000)
42
- @bucket_listing.is_truncated.should.equal(false)
38
+ @bucket_listing.name.should ==('testingtesting')
39
+ @bucket_listing.prefix.should ==('')
40
+ @bucket_listing.marker.should ==('')
41
+ @bucket_listing.max_keys.should ==(1000)
42
+ @bucket_listing.is_truncated.should ==(false)
43
43
  @bucket_listing.delimiter.should.be nil
44
44
  end
45
45
 
46
46
  specify 'when listing XML is reset, should update all properties correctly' do
47
47
  @bucket_listing.set_listing_xml(@with_bucket_listing_xml2)
48
- @bucket_listing.name.should.equal('testing2')
49
- @bucket_listing.prefix.should.equal('/home/ell/')
50
- @bucket_listing.marker.should.equal('')
51
- @bucket_listing.max_keys.should.equal(100)
52
- @bucket_listing.delimiter.should.equal('/')
53
- @bucket_listing.is_truncated.should.equal(false)
48
+ @bucket_listing.name.should ==('testing2')
49
+ @bucket_listing.prefix.should ==('/home/ell/')
50
+ @bucket_listing.marker.should ==('')
51
+ @bucket_listing.max_keys.should ==(100)
52
+ @bucket_listing.delimiter.should ==('/')
53
+ @bucket_listing.is_truncated.should ==(false)
54
54
  end
55
55
 
56
56
  specify 'should provide private setters for metadata' do
@@ -59,7 +59,7 @@ context 'S33r bucket listing' do
59
59
  # names of the setters
60
60
  setters = @bucket_property_setters
61
61
  # all methods should be a superset of the private setters
62
- methods.superset?(setters.to_set).should.equal true
62
+ methods.superset?(setters.to_set).should == true
63
63
  end
64
64
 
65
65
  specify 'should store resources (<Contents> elements) in a hash' do
@@ -21,11 +21,11 @@ context 'S33r logging' do
21
21
  end
22
22
 
23
23
  specify 'should generate BucketLoggingStatus XML document to enable logging' do
24
- clean_xml(@logging_resource_to_enable.to_xml).should.equal @logging_enabled_xml
24
+ clean_xml(@logging_resource_to_enable.to_xml).should == @logging_enabled_xml
25
25
  end
26
26
 
27
27
  specify 'should generate BucketLoggingStatus XML document to disable logging' do
28
- clean_xml(@logging_resource_to_disable.to_xml).should.equal @logging_disabled_xml
28
+ clean_xml(@logging_resource_to_disable.to_xml).should == @logging_disabled_xml
29
29
  end
30
30
 
31
31
  specify 'should represent LogDelivery grants so buckets can act as logging targets' do
@@ -42,6 +42,6 @@ context 'S33r logging' do
42
42
 
43
43
  specify 'should be able to simply add logging target grants to an ACL' do
44
44
  @logging_acl_doc_no_grants.add_log_target_grants
45
- clean_xml(@logging_acl_doc_no_grants.to_xml).should.equal @logging_acl_xml
45
+ clean_xml(@logging_acl_doc_no_grants.to_xml).should == @logging_acl_xml
46
46
  end
47
47
  end
@@ -23,15 +23,15 @@ context 'S3 object' do
23
23
  end
24
24
 
25
25
  specify 'can be initialised from XML fragment with correct data types' do
26
- @s3obj.key.should.equal '/home/ell/dir1/four.txt'
26
+ @s3obj.key.should == '/home/ell/dir1/four.txt'
27
27
  d = @s3obj.last_modified
28
- [d.year, d.month, d.day, d.hour, d.min, d.sec].should.equal [2006, 8, 19, 22, 53, 29]
29
- @s3obj.etag.should.equal '24ce59274b89287b3960c184153ac24b'
30
- @s3obj.size.should.equal 14
28
+ [d.year, d.month, d.day, d.hour, d.min, d.sec].should == [2006, 8, 19, 22, 53, 29]
29
+ @s3obj.etag.should == '24ce59274b89287b3960c184153ac24b'
30
+ @s3obj.size.should == 14
31
31
  end
32
32
 
33
33
  specify 'can be associated with bucket on creation' do
34
- @s3obj2.bucket.name.should.equal 'quotes'
34
+ @s3obj2.bucket.name.should == 'quotes'
35
35
  end
36
36
 
37
37
  specify 'can be created from a file' do
@@ -39,7 +39,7 @@ context 'S3 object' do
39
39
  end
40
40
 
41
41
  specify 'should treat the owner as an object in his/her own right' do
42
- [@s3obj.owner.user_id, @s3obj.owner.display_name].should.equal \
42
+ [@s3obj.owner.user_id, @s3obj.owner.display_name].should == \
43
43
  ['56efddfead5aa65da942f156fb2b294f44d78fd932d701331edc5fba19620fd4', 'elliotsmith3']
44
44
  @s3obj.owner.should_be_instance_of S3ACL::CanonicalUser
45
45
  end
@@ -57,18 +57,18 @@ context 'S3 object' do
57
57
  end
58
58
 
59
59
  specify 'should return authenticated URL' do
60
- @s3obj2.url(:authenticated => true, :expires => 1141889120).should.equal @correct_authenticated_url
60
+ @s3obj2.url(:authenticated => true, :expires => 1141889120).should == @correct_authenticated_url
61
61
  end
62
62
 
63
63
  specify 'should return public URL' do
64
- @s3obj2.url.should.equal @correct_public_url
64
+ @s3obj2.url.should == @correct_public_url
65
65
  end
66
66
 
67
67
  specify 'should optionally return HTTPS URL' do
68
- @s3obj2.url(:use_ssl => true).should.equal @correct_public_url_with_ssl
68
+ @s3obj2.url(:use_ssl => true).should == @correct_public_url_with_ssl
69
69
  end
70
70
 
71
71
  specify 'should optionally return URL with domain name set to bucket name' do
72
- @s3obj2.url(:subdomain => true).should.equal @correct_public_url_with_subdomain
72
+ @s3obj2.url(:subdomain => true).should == @correct_public_url_with_subdomain
73
73
  end
74
74
  end
@@ -45,38 +45,40 @@ context 'S33r utility' do
45
45
  @correct_acl_url = "http://s3.amazonaws.com/quotes/?acl"
46
46
  @correct_acl_url_with_key = "http://s3.amazonaws.com/quotes/nelson?acl"
47
47
  @correct_public_url_with_qstring = "http://s3.amazonaws.com/quotes/?prefix=%2Fhome&max-keys=400"
48
+ @url_with_escaped_key = "http://s3.amazonaws.com/quotes/some+key"
49
+ @url_with_unescaped_key = "http://s3.amazonaws.com/quotes/some key"
48
50
  end
49
51
 
50
52
  specify 'should load config files containing standard S33r settings' do
51
53
  config, _ = S33r.load_config(@yaml_file)
52
- config[:access].should.equal Testing::ACCESS_KEY
54
+ config[:access].should == Testing::ACCESS_KEY
53
55
  end
54
56
 
55
57
  specify 'can parse ERb embedded in config. file' do
56
58
  config, _ = S33r.load_config(@yaml_file)
57
- config[:secret].should.equal Testing::SECRET_ACCESS_KEY
59
+ config[:secret].should == Testing::SECRET_ACCESS_KEY
58
60
  end
59
61
 
60
62
  specify 'can parse extra application-specific settings in config. file' do
61
63
  config, options = S33r.load_config(@yaml_file)
62
- options[:email_to].should.equal Testing::EMAIL
64
+ options[:email_to].should == Testing::EMAIL
63
65
  # Make sure the 'options' section has not been included in the general config..
64
66
  config.keys.should.not.include :options
65
67
  end
66
68
 
67
69
  specify 'should generate correct canonical strings' do
68
70
  generate_canonical_string(@for_request_method, @for_request_path,
69
- @for_request_headers).should.equal @correct_canonical_string
71
+ @for_request_headers).should == @correct_canonical_string
70
72
  end
71
73
 
72
74
  specify 'should generate correct signatures' do
73
75
  generate_signature(Testing::SECRET_ACCESS_KEY,
74
- @correct_canonical_string).should.equal @correct_signature
76
+ @correct_canonical_string).should == @correct_signature
75
77
  end
76
78
 
77
79
  specify 'should generate correct auth headers' do
78
80
  generate_auth_header_value(@for_request_method, @for_request_path, @for_request_headers,
79
- Testing::ACCESS_KEY, Testing::SECRET_ACCESS_KEY).should.equal @correct_auth_header
81
+ Testing::ACCESS_KEY, Testing::SECRET_ACCESS_KEY).should == @correct_auth_header
80
82
  end
81
83
 
82
84
  specify 'should not generate auth header if bad HTTP method passed' do
@@ -95,8 +97,8 @@ context 'S33r utility' do
95
97
  fixed_headers = default_headers(@for_incomplete_headers, :date => now,
96
98
  :content_type => 'text/html')
97
99
 
98
- fixed_headers['Date'].should.equal now.httpdate
99
- fixed_headers['Content-Type'].should.equal 'text/html'
100
+ fixed_headers['Date'].should == now.httpdate
101
+ fixed_headers['Content-Type'].should == 'text/html'
100
102
  end
101
103
 
102
104
  specify 'should generate correct x-amz-meta- headers from a hash' do
@@ -104,8 +106,8 @@ context 'S33r utility' do
104
106
  headers = metadata_headers(meta)
105
107
  headers.should.include 'x-amz-meta-myname'
106
108
  headers.should.include 'x-amz-meta-myage'
107
- headers['x-amz-meta-myname'].should.equal 'elliot'
108
- headers['x-amz-meta-myage'].should.equal '36'
109
+ headers['x-amz-meta-myname'].should == 'elliot'
110
+ headers['x-amz-meta-myage'].should == '36'
109
111
  end
110
112
 
111
113
  specify 'should not generate canned ACL header if invalid canned ACL supplied' do
@@ -117,28 +119,28 @@ context 'S33r utility' do
117
119
  new_headers = canned_acl_header('private')
118
120
  new_headers.should.have(1).keys
119
121
  new_headers.keys.should.include 'x-amz-acl'
120
- new_headers['x-amz-acl'].should.equal 'private'
122
+ new_headers['x-amz-acl'].should == 'private'
121
123
  end
122
124
 
123
125
  specify 'should set sensible defaults for missing Content-Type and Date headers' do
124
126
  fixed_headers = default_headers(@for_incomplete_headers)
125
- fixed_headers['Content-Type'].should.equal ''
127
+ fixed_headers['Content-Type'].should == ''
126
128
  fixed_headers.include?('Date').should.not.be nil
127
129
  end
128
130
 
129
131
  specify 'should default to text/plain mimetype for unknown file types' do
130
- guess_mime_type('hello.madeup').should.equal('text/plain')
132
+ guess_mime_type('hello.madeup').should ==('text/plain')
131
133
  end
132
134
 
133
135
  specify 'should generate correct Content-Disposition, Content-Type and Content-Transfer-Encoding headers' do
134
136
  headers = content_headers('text/plain', 'download.jpg', true)
135
- headers['Content-Type'].should.equal 'text/plain'
136
- headers['Content-Disposition'].should.equal "attachment; filename=download.jpg"
137
+ headers['Content-Type'].should == 'text/plain'
138
+ headers['Content-Disposition'].should == "attachment; filename=download.jpg"
137
139
 
138
140
  headers = content_headers('image/jpeg', '/home/you/me.jpg', true)
139
- headers['Content-Type'].should.equal 'image/jpeg'
140
- headers['Content-Transfer-Encoding'].should.equal 'binary'
141
- headers['Content-Disposition'].should.equal "attachment; filename=me.jpg"
141
+ headers['Content-Type'].should == 'image/jpeg'
142
+ headers['Content-Transfer-Encoding'].should == 'binary'
143
+ headers['Content-Disposition'].should == "attachment; filename=me.jpg"
142
144
  end
143
145
 
144
146
  specify 'should recognise invalid bucket names' do
@@ -149,75 +151,75 @@ context 'S33r utility' do
149
151
  end
150
152
 
151
153
  specify 'should return empty string if generating querystring with no key/value pairs' do
152
- generate_querystring({}).should_equal ''
154
+ generate_querystring({}).should == ''
153
155
  end
154
156
 
155
157
  specify 'should correctly format querystring key/value pairs' do
156
- generate_querystring({'message' => 'Hello world', 'id' => 1, 'page' => '[2,4]'}).should_equal \
158
+ generate_querystring({'message' => 'Hello world', 'id' => 1, 'page' => '[2,4]'}).should == \
157
159
  'message=Hello+world&id=1&page=%5B2%2C4%5D'
158
160
  end
159
161
 
160
162
  specify 'should allow symbols as names for querystring variables when generating querystrings' do
161
- generate_querystring({ :prefix => '/home/ell' }).should.equal('prefix=%2Fhome%2Fell')
163
+ generate_querystring({ :prefix => '/home/ell' }).should ==('prefix=%2Fhome%2Fell')
162
164
  end
163
165
 
164
166
  specify 'should convert integers to strings when generating querystrings' do
165
- generate_querystring({ 'max-keys' => 400 }).should.equal('max-keys=400')
167
+ generate_querystring({ 'max-keys' => 400 }).should ==('max-keys=400')
166
168
  end
167
169
 
168
170
  specify 'should generate URLs with authentication parameters' do
169
171
  s3_authenticated_url(Testing::ACCESS_KEY, Testing::SECRET_ACCESS_KEY, :bucket => 'quotes', \
170
- :key => 'nelson', :expires => 1141889120).should.equal @correct_authenticated_url
172
+ :key => 'nelson', :expires => 1141889120).should == @correct_authenticated_url
171
173
  end
172
174
 
173
175
  specify 'should be able to pass credentials as an option to the basic URL generator' do
174
176
  s3_url(:access => Testing::ACCESS_KEY, :secret => Testing::SECRET_ACCESS_KEY, \
175
177
  :authenticated => true, :bucket => 'quotes', :key => 'nelson', \
176
- :expires => 1141889120).should.equal @correct_authenticated_url
178
+ :expires => 1141889120).should == @correct_authenticated_url
177
179
  end
178
180
 
179
181
  specify 'should generate correct public URLs' do
180
- s3_public_url(:bucket => 'quotes', :key => 'nelson').should.equal @correct_public_url
182
+ s3_public_url(:bucket => 'quotes', :key => 'nelson').should == @correct_public_url
181
183
  end
182
184
 
183
185
  specify 'should correctly append querystring variables' do
184
- s3_url(:bucket => 'quotes', :querystring => {'max-keys' => 400, 'prefix' => '/home'}).should.equal \
186
+ s3_url(:bucket => 'quotes', :querystring => {'max-keys' => 400, 'prefix' => '/home'}).should == \
185
187
  @correct_public_url_with_qstring
186
188
  end
187
189
 
188
190
  specify 'should generate HTTPS URLs' do
189
- s3_public_url(:bucket => 'quotes', :key => 'nelson', :use_ssl => true).should.equal @correct_public_ssl_url
191
+ s3_public_url(:bucket => 'quotes', :key => 'nelson', :use_ssl => true).should == @correct_public_ssl_url
190
192
  end
191
193
 
192
194
  specify 'should generate public URLs with bucket name as subdomain' do
193
- s3_public_url(:bucket => 'quotes', :key => 'nelson', :subdomain => true).should.equal \
195
+ s3_public_url(:bucket => 'quotes', :key => 'nelson', :subdomain => true).should == \
194
196
  @correct_public_url_with_subdomain
195
- s3_public_url(:bucket => 'quotes', :key => 'nelson', :subdomain => true, :use_ssl => true).should.equal \
197
+ s3_public_url(:bucket => 'quotes', :key => 'nelson', :subdomain => true, :use_ssl => true).should == \
196
198
  @correct_public_url_with_ssl_and_subdomain
197
199
  end
198
200
 
199
201
  specify 'should generate URLs for buckets without keys' do
200
- s3_public_url(:bucket => 'quotes').should.equal @correct_public_url_without_key
202
+ s3_public_url(:bucket => 'quotes').should == @correct_public_url_without_key
201
203
  end
202
204
 
203
205
  specify 'should generate logging URLs' do
204
- s3_url(:bucket => 'quotes', :logging => true).should.equal @correct_logging_url
206
+ s3_url(:bucket => 'quotes', :logging => true).should == @correct_logging_url
205
207
  end
206
208
 
207
209
  specify 'should generate ACL URLs' do
208
- s3_url(:bucket => 'quotes', :acl => true).should.equal @correct_acl_url
209
- s3_url(:bucket => 'quotes', :key => 'nelson', :acl => true).should.equal @correct_acl_url_with_key
210
+ s3_url(:bucket => 'quotes', :acl => true).should == @correct_acl_url
211
+ s3_url(:bucket => 'quotes', :key => 'nelson', :acl => true).should == @correct_acl_url_with_key
210
212
  end
211
213
 
212
214
  specify 'should turn off subdomain if authenticated URL' do
213
215
  s3_url(:access => Testing::ACCESS_KEY, :secret => Testing::SECRET_ACCESS_KEY, \
214
216
  :authenticated => true, :bucket => 'quotes', :key => 'nelson', :subdomain => true, \
215
- :expires => 1141889120).should.equal @correct_authenticated_url
217
+ :expires => 1141889120).should == @correct_authenticated_url
216
218
  end
217
219
 
218
220
  specify 'should turn off subdomain if generating SSL URL' do
219
221
  s3_url(:bucket => 'quotes', :key => 'nelson', :use_ssl => true, \
220
- :subdomain => true).should.equal @correct_public_ssl_url
222
+ :subdomain => true).should == @correct_public_ssl_url
221
223
  end
222
224
 
223
225
  specify 'should produce correct default expiry time if none specified, or time 50 years \
@@ -231,14 +233,14 @@ context 'S33r utility' do
231
233
  # Default to DEFAULT_EXPIRY_SECS from now
232
234
  expected_expiry = Time.now.to_i + DEFAULT_EXPIRY_SECS
233
235
  expires = S33r.parse_expiry
234
- expires.should.equal expected_expiry
236
+ expires.should == expected_expiry
235
237
  expires.should_be_kind_of Integer
236
238
 
237
239
  # If :far_flung_future is passed, default to 20 years from now.
238
240
  expected_expiry = Time.now.to_i +
239
241
  (60 * 60 * 24 * 365.25 * 20).to_i
240
242
  expires = S33r.parse_expiry(:far_flung_future)
241
- expires.should.equal expected_expiry
243
+ expires.should == expected_expiry
242
244
  expires.should_be_kind_of Integer
243
245
 
244
246
  class Time
@@ -251,14 +253,19 @@ context 'S33r utility' do
251
253
  datetime_str = '9th January 2007 13:33'
252
254
  expected_expiry = Time.parse(datetime_str).to_i
253
255
  expires = S33r.parse_expiry(datetime_str)
254
- expires.should.equal expected_expiry
256
+ expires.should == expected_expiry
255
257
  expires.should_be_kind_of Integer
256
258
  end
257
259
 
258
260
  specify 'should provide a method for converting string keys of a hash into symbols' do
259
261
  h = {'access' => Testing::ACCESS_KEY, 'secret' => Testing::SECRET_ACCESS_KEY}
260
262
  symbolised = S33r.keys_to_symbols(h)
261
- symbolised.should.equal({:access => Testing::ACCESS_KEY, :secret => Testing::SECRET_ACCESS_KEY})
263
+ symbolised.should ==({:access => Testing::ACCESS_KEY, :secret => Testing::SECRET_ACCESS_KEY})
264
+ end
265
+
266
+ specify 'can optionally escape keys passed in paths' do
267
+ s3_url(:bucket => 'quotes', :key => 'some key', :escape => true).should == @url_with_escaped_key
268
+ s3_url(:bucket => 'quotes', :key => 'some key').should == @url_with_unescaped_key
262
269
  end
263
270
 
264
271
  end