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.
- data/examples/fores33r/app/controllers/browser_controller.rb +2 -1
- data/examples/fores33r/app/views/browser/_create_bucket.rhtml +2 -2
- data/examples/fores33r/app/views/browser/_upload.rhtml +2 -2
- data/examples/fores33r/config/environment.rb +2 -2
- data/examples/fores33r/config/routes.rb +11 -5
- data/lib/s33r.rb +13 -3
- data/lib/s33r/client.rb +3 -1
- data/lib/s33r/{builder.rb → orderly_xml_markup.rb} +3 -1
- data/lib/s33r/utility.rb +7 -2
- data/test/cases/spec_acl.rb +11 -11
- data/test/cases/spec_bucket_listing.rb +12 -12
- data/test/cases/spec_logging.rb +3 -3
- data/test/cases/spec_s3_object.rb +10 -10
- data/test/cases/spec_utility.rb +46 -39
- data/test/cases/spec_xml.rb +3 -3
- data/test/test_setup.rb +6 -1
- metadata +85 -88
- data/examples/fores33r/log/development.log +0 -3032
- data/examples/fores33r/log/mongrel.log +0 -59
- data/examples/fores33r/tmp/sessions/ruby_sess.75445a6f4154aa9d +0 -0
- data/examples/fores33r/tmp/sessions/ruby_sess.f55f1b0adcf2e2d8 +0 -0
@@ -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
|
-
|
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
|
-
|
6
|
+
<% end %>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
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
|
-
|
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
|
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
|
-
|
17
|
-
map.connect '/
|
18
|
-
|
19
|
-
map.connect '/
|
20
|
-
|
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
|
-
|
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
|
-
|
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', '
|
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
|
-
|
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
|
data/test/cases/spec_acl.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
39
|
-
@bucket_listing.prefix.should
|
40
|
-
@bucket_listing.marker.should
|
41
|
-
@bucket_listing.max_keys.should
|
42
|
-
@bucket_listing.is_truncated.should
|
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
|
49
|
-
@bucket_listing.prefix.should
|
50
|
-
@bucket_listing.marker.should
|
51
|
-
@bucket_listing.max_keys.should
|
52
|
-
@bucket_listing.delimiter.should
|
53
|
-
@bucket_listing.is_truncated.should
|
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
|
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
|
data/test/cases/spec_logging.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
29
|
-
@s3obj.etag.should
|
30
|
-
@s3obj.size.should
|
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
|
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
|
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
|
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
|
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
|
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
|
72
|
+
@s3obj2.url(:subdomain => true).should == @correct_public_url_with_subdomain
|
73
73
|
end
|
74
74
|
end
|
data/test/cases/spec_utility.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
99
|
-
fixed_headers['Content-Type'].should
|
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
|
108
|
-
headers['x-amz-meta-myage'].should
|
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
|
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
|
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
|
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
|
136
|
-
headers['Content-Disposition'].should
|
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
|
140
|
-
headers['Content-Transfer-Encoding'].should
|
141
|
-
headers['Content-Disposition'].should
|
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({}).
|
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]'}).
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
209
|
-
s3_url(:bucket => 'quotes', :key => 'nelson', :acl => true).should
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|