存储桶中的Ruby访问文件夹的aws-sdk

时间:2012-10-16 06:16:50

标签: ruby-on-rails ruby amazon-s3

我在Amazon S3上有一个存储桶,其中包含文件夹。我试图通过以下方式通过 aws-sdk gem访问它:

s3 = AWS::S3.new(
    :access_key_id => "KEY",
    :secret_access_key => "SECRET"
)

bucket = s3.buckets["my_bucket/my_folder"]
bucket.do_stuff....

我收到以下错误:

您尝试访问的存储区必须使用指定的端点进行寻址。请将以后的所有请求发送到此端点。

任何想法我可能做错了什么?

5 个答案:

答案 0 :(得分:23)

可能是S3存储桶正在尝试使用它位于US-EAST(默认位置)之外,所以这应该可以帮到你:

s3 = AWS::S3.new(
    :access_key_id => "KEY",
    :secret_access_key => "SECRET"
    :s3_endpoint => 's3-eu-west-1.amazonaws.com'
)

following list

中选择您的S3 enpdpoint
US Standard *                           s3.amazonaws.com(default)
US West (Oregon) Region                 s3-us-west-2.amazonaws.com
US West (Northern California) Region    s3-us-west-1.amazonaws.com
EU (Ireland) Region                     s3-eu-west-1.amazonaws.com
Asia Pacific (Singapore) Region         s3-ap-southeast-1.amazonaws.com
Asia Pacific (Tokyo) Region             s3-ap-northeast-1.amazonaws.com
South America (Sao Paulo) Region        s3-sa-east-1.amazonaws.com

在对象访问方面,存储桶名称为 my_bucket ,但 my_folder 应该是对象的一部分。

答案 1 :(得分:6)

您需要为存储桶(创建存储区)配置特定于区域的端点。你可以这样做:

AWS.config(:s3_endpoint => '...')
s3 = AWS::S3.new

s3 = AWS::S3.new(:s3_endpoint => '...')

将来可以使用DNS可比较的存储桶名称(也可以避免存储桶名称中的点)来避免这种情况。如果存储桶名称是有效的子域,则可以在不配置区域特定端点的情况下寻址存储桶。请考虑以下事项:

http:://bucket-name.s3.amazonaws.com/path/to/object.txt

将存储桶命名为“bucket-name”,对象键为“path / to / object.txt”。此存储桶可以存在于任何区域,但您可以使用“默认”区域访问它。当存储桶名称与dns不兼容时,网址如下所示:

http://s3.amazon.com/bucket/name/path/to/object.txt

在上面的示例中,存储桶是“存储桶/名称”,与dns不兼容。它成为路径的一部分,现在必须用区域特定端点替换s3.amazon.com(如果未在经典区域中创建存储桶)。

正如其他人提到的,路径应该是对象密钥的一部分,而不是存储桶名称。这允许您通过公共前缀对对象进行分组。 '/'用作虚拟文件夹(仅限惯例)。

# print the key of every object with the given prefix
s3.buckets['bucket-name'].objects.with_prefix('path/to/').each do |object|
  puts object.key
end

答案 2 :(得分:1)

has_attached_file :photo,
  storage: :s3,
  styles: { medium: "300x300>", thumb: "100x100>" },
  s3_credentials: "#{Rails.root}/config/aws.yml",
  bucket: "bucket-name",
  s3_host_name: "s3-ap-southeast-1.amazonaws.com",
  url: ":s3_domain_url",
  path: 'books/:id/photo/:style_:basename.:extension'

为我工作:)

答案 3 :(得分:1)

Godsaur的答案基本上是正确的。但是,它似乎已经过时了,也许对于SDK版本1?

这适用于版本2:

s3 = Aws::S3::Client.new(endpoint:'https://s3-ap-southeast-1.amazonaws.com')

请参阅docs

答案 4 :(得分:0)

万一有人在寻找这个,这就是根据https://github.com/aws/aws-sdk-ruby

的工作方式
creds = JSON.load(File.read('secrets.json'))
Aws.config[:credentials] = Aws::Credentials.new(creds['AccessKeyId'], creds['SecretAccessKey'])
Aws.config[:region] = 'us-east-1'

client = Aws::S3::Client.new(
    region: Aws.config[:region],
    credentials: Aws.config[:credentials]
)

File.open('/local_directory/picture.jpg', 'rb') do |file|
  client.put_object(bucket: 'bucket', key: 'folder_inside_bucket/picture.jpg', body: file)
end