Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.rake_tasks
site/public/index.html
pkg/
.bundle
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source "http://rubygems.org"

gemspec
25 changes: 25 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
PATH
remote: .
specs:
aws-s3 (0.6.3)
builder
mime-types
xml-simple

GEM
remote: http://rubygems.org/
specs:
builder (2.1.2)
flexmock (0.8.11)
mime-types (1.16)
xml-simple (1.0.12)

PLATFORMS
ruby

DEPENDENCIES
aws-s3!
builder
flexmock
mime-types
xml-simple
1 change: 1 addition & 0 deletions aws-s3.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Gem::Specification.new do |s|
s.add_dependency 'xml-simple'
s.add_dependency 'builder'
s.add_dependency 'mime-types'
s.add_development_dependency 'flexmock'
s.rdoc_options = ['--title', "AWS::S3 -- Support for Amazon S3's REST api",
'--main', 'README',
'--line-numbers', '--inline-source']
Expand Down
11 changes: 9 additions & 2 deletions lib/aws/s3/bucket.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,14 @@ class << self
# in the section called 'Setting access levels'.
def create(name, options = {})
validate_name!(name)
put("/#{name}", options).success?
# workaround: PUT to create bucket should raise error (as specified in the AWS API docs) when trying to create existing bucket
begin
find(name)
raise AWS::S3::BucketAlreadyExists.new
rescue AWS::S3::NoSuchBucket
# bucket does not exist, so allow create PUT to go through
put("/#{name}", options).success?
end
end

# Fetches the bucket named <tt>name</tt>.
Expand Down Expand Up @@ -316,4 +323,4 @@ def reload!(options = {})
end
end
end
end
end
13 changes: 12 additions & 1 deletion lib/aws/s3/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def initialize(message, response)
class InternalError < ResponseError
end

class NoSuchBucket < ResponseError
end

class NoSuchKey < ResponseError
end

Expand Down Expand Up @@ -90,6 +93,14 @@ def initialize(invalid_names)
super(message)
end
end

# Raised if a bucket already exists with the specified name
class BucketAlreadyExists < ResponseError
def initialize
message = "The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again."
super(message, {:body => message, :code => 409})
end
end

# Raised if the current bucket can not be inferred when not explicitly specifying the target bucket in the calling
# method's arguments.
Expand Down Expand Up @@ -130,4 +141,4 @@ def initialize(klass)

#:startdoc:
end
end
end
18 changes: 17 additions & 1 deletion test/bucket_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ def test_bucket_name_validation
assert_raises(InvalidBucketName) { validate_name[invalid_name] }
end
end

def test_bucket_create_with_unique_name
bucket_name = 'foo'
flexmock(Bucket).should_receive(:find).with(bucket_name).and_raise(AWS::S3::NoSuchBucket.new('foobar', {:body => "foobar", :code => 404}))
flexmock(Bucket).should_receive(:put).with('/foo', any).and_return(flexmock(:success? => true))
assert Bucket.create(bucket_name)
end

# API says that create should error with a BucketAlreadyExists if name already is taken
def test_bucket_create_with_existing_name
bucket_name = 'foo'
flexmock(Bucket).should_receive(:find).with(bucket_name).and_return(flexmock(Bucket))
assert_raise AWS::S3::BucketAlreadyExists do
Bucket.create(bucket_name)
end
end

def test_empty_bucket
mock_connection_for(Bucket, :returns => {:body => Fixtures::Buckets.empty_bucket, :code => 200})
Expand Down Expand Up @@ -71,4 +87,4 @@ def test_bucket_name_should_have_leading_slash_prepended_only_once_when_forcing_
flexmock(Base).should_receive(:delete).with(expected_bucket_path).once.and_return(mock_response)
Bucket.delete(bucket_name, :force => true)
end
end
end