diff --git a/lib/aws/s3/base.rb b/lib/aws/s3/base.rb
index 63abafa..8531140 100644
--- a/lib/aws/s3/base.rb
+++ b/lib/aws/s3/base.rb
@@ -43,6 +43,13 @@ module AWS #:nodoc:
module S3
constant :DEFAULT_HOST, 's3.amazonaws.com'
+ # See: http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RequestEndpoints.html
+ ENDPOINTS = {
+ :us => 's3-us-west-1.amazonaws.com',
+ :asia => 's3-ap-southeast-1.amazonaws.com',
+ :europe => 's3-eu-west-1.amazonaws.com'
+ }
+
# AWS::S3::Base is the abstract super class of all classes who make requests against S3, such as the built in
# Service, Bucket and S3Object classes. It provides methods for making requests, inferring or setting response classes,
# processing request options, and accessing attributes from S3's response data.
diff --git a/lib/aws/s3/connection.rb b/lib/aws/s3/connection.rb
index 85dee2d..b4528e4 100644
--- a/lib/aws/s3/connection.rb
+++ b/lib/aws/s3/connection.rb
@@ -183,6 +183,9 @@ module ClassMethods
#
# * :server - The server to make requests to. You can use this to specify your bucket in the subdomain,
# or your own domain's cname if you are using virtual hosted buckets. Defaults to s3.amazonaws.com.
+ # * :region - The region from which to take the default server. You can use this to ovverride the default
+ # server if you used a regional bucket from :europe, :asia or :us. This can't be used
+ # together with the :server setting. Defaults to nil.
# * :port - The port to the requests should be made on. Defaults to 80 or 443 if the :use_ssl
# argument is set.
# * :use_ssl - Whether requests should be made over SSL. If set to true, the :port argument
@@ -251,12 +254,12 @@ def default_connection
end
class Options < Hash #:nodoc:
- VALID_OPTIONS = [:access_key_id, :secret_access_key, :server, :port, :use_ssl, :persistent, :proxy].freeze
+ VALID_OPTIONS = [:access_key_id, :secret_access_key, :server, :region, :port, :use_ssl, :persistent, :proxy].freeze
def initialize(options = {})
super()
validate(options)
- replace(:server => DEFAULT_HOST, :port => (options[:use_ssl] ? 443 : 80))
+ replace(:server => options[:region] ? ENDPOINTS[options[:region]] : DEFAULT_HOST, :port => (options[:use_ssl] ? 443 : 80))
merge!(options)
end
@@ -273,6 +276,8 @@ def validate(options)
invalid_options = options.keys - VALID_OPTIONS
raise InvalidConnectionOption.new(invalid_options) unless invalid_options.empty?
raise ArgumentError, "Missing proxy settings. Must specify at least :host." if options[:proxy] && !options[:proxy][:host]
+ raise ArgumentError, "Ambiguous server/region option: please don't use :server and :region options together." if options[:server] && options[:region]
+ raise ArgumentError, "Bad region: please use one of #{ENDPOINTS.keys.map(&:inspect).join(', ')}." if options[:region] && !ENDPOINTS.key?(options[:region])
end
end
end
diff --git a/test/connection_test.rb b/test/connection_test.rb
index 52919d0..e0fc971 100644
--- a/test/connection_test.rb
+++ b/test/connection_test.rb
@@ -212,6 +212,23 @@ def test_recognizing_that_the_settings_want_to_connect_through_a_proxy
assert options.connecting_through_proxy?
end
+ def test_server_and_region_settings_cant_live_together
+ assert_raises(ArgumentError) do
+ generate_options(:region => :europe, :server => "example.org")
+ end
+ end
+
+ def test_server_setting_is_extracted_from_region
+ options = generate_options(:region => :europe)
+ assert_equal ENDPOINTS[:europe], options[:server]
+ end
+
+ def test_region_is_a_valid_s3_endpoint
+ assert_raises(ArgumentError) do
+ generate_options(:region => :antartica)
+ end
+ end
+
private
def assert_key_transfered(key, value, options)
assert_equal value, options[key]