mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
finish most of the other s3 mocks
This commit is contained in:
parent
5a156e5a0b
commit
175e5802f7
11 changed files with 270 additions and 141 deletions
|
@ -1,40 +1,86 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
unless Fog.mocking?
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
# Copy an object from one S3 bucket to another
|
||||
#
|
||||
# ==== Parameters
|
||||
# * source_bucket_name<~String> - Name of source bucket
|
||||
# * source_object_name<~String> - Name of source object
|
||||
# * target_bucket_name<~String> - Name of bucket to create copy in
|
||||
# * target_object_name<~String> - Name for new copy of object
|
||||
# * options<~Hash>:
|
||||
# * 'x-amz-metadata-directive'<~String> - Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE']
|
||||
# * 'x-amz-copy_source-if-match'<~String> - Copies object if its etag matches this value
|
||||
# * 'x-amz-copy_source-if-modified_since'<~Time> - Copies object it it has been modified since this time
|
||||
# * 'x-amz-copy_source-if-none-match'<~String> - Copies object if its etag does not match this value
|
||||
# * 'x-amz-copy_source-if-unmodified-since'<~Time> - Copies object it it has not been modified since this time
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'ETag'<~String> - etag of new object
|
||||
# * 'LastModified'<~Time> - date object was last modified
|
||||
#
|
||||
# TODO: allow specifying new metadata (support all/some of put_object?)
|
||||
def copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {})
|
||||
headers = { 'x-amz-copy-source' => "/#{source_bucket_name}/#{source_object_name}" }.merge!(options)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => headers,
|
||||
:host => "#{target_bucket_name}.#{@host}",
|
||||
:method => 'PUT',
|
||||
:parser => Fog::Parsers::AWS::S3::CopyObject.new,
|
||||
:path => target_object_name
|
||||
})
|
||||
end
|
||||
|
||||
# Copy an object from one S3 bucket to another
|
||||
#
|
||||
# ==== Parameters
|
||||
# * source_bucket_name<~String> - Name of source bucket
|
||||
# * source_object_name<~String> - Name of source object
|
||||
# * destination_bucket_name<~String> - Name of bucket to create copy in
|
||||
# * destination_object_name<~String> - Name for new copy of object
|
||||
# * options<~Hash>:
|
||||
# * 'x-amz-metadata-directive'<~String> - Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE']
|
||||
# * 'x-amz-copy_source-if-match'<~String> - Copies object if its etag matches this value
|
||||
# * 'x-amz-copy_source-if-modified_since'<~Time> - Copies object it it has been modified since this time
|
||||
# * 'x-amz-copy_source-if-none-match'<~String> - Copies object if its etag does not match this value
|
||||
# * 'x-amz-copy_source-if-unmodified-since'<~Time> - Copies object it it has not been modified since this time
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'ETag'<~String> - etag of new object
|
||||
# * 'LastModified'<~Time> - date object was last modified
|
||||
#
|
||||
# TODO: allow specifying new metadata (support all/some of put_object?)
|
||||
def copy_object(source_bucket_name, source_object_name, destination_bucket_name, destination_object_name, options = {})
|
||||
headers = { 'x-amz-copy-source' => "/#{source_bucket_name}/#{source_object_name}" }.merge!(options)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => headers,
|
||||
:host => "#{destination_bucket_name}.#{@host}",
|
||||
:method => 'PUT',
|
||||
:parser => Fog::Parsers::AWS::S3::CopyObject.new,
|
||||
:path => destination_object_name
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
def copy_object(source_bucket_name, source_object_name, target_bucket_name, target_object_name, options = {})
|
||||
response = Fog::Response.new
|
||||
source_bucket_status = get_bucket(source_bucket_name).status
|
||||
target_bucket_status = get_bucket(target_bucket_name).status
|
||||
source_object_status = get_object(source_bucket_name, source_object_name).status
|
||||
|
||||
if source_bucket_status != 200
|
||||
response.status = source_bucket_status
|
||||
elsif target_bucket_status != 200
|
||||
response.status = target_bucket_status
|
||||
elsif source_bucket_status != 200
|
||||
response.status = source_bucket_status
|
||||
else
|
||||
response.status = 200
|
||||
end
|
||||
|
||||
if response.status == 200
|
||||
source_bucket = @data['Buckets'].select {|bucket| bucket['Name'] == source_bucket_name}.first
|
||||
source_object = source_bucket['Contents'].select {|object| object['Key'] == source_object_name}.first
|
||||
target_bucket = @data['Buckets'].select {|bucket| bucket['Name'] == target_bucket_name}.first
|
||||
target_object = source_object.dup
|
||||
target_object['Name'] = target_object_name
|
||||
target_bucket['Contents'] << target_object
|
||||
response.body = {
|
||||
'ETag' => target_object['ETag'],
|
||||
'LastModified' => Time.parse(target_object['LastModified'])
|
||||
}
|
||||
end
|
||||
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -70,7 +70,9 @@ else
|
|||
response.body = {
|
||||
'IsTruncated' => false,
|
||||
'Contents' => bucket['Contents'].map do |object|
|
||||
object.reject {|key, value| !['ETag', 'Key', 'LastModified', 'Owner', 'StorageClass'].include?(key)}
|
||||
data = object.reject {|key, value| !['ETag', 'Key', 'LastModified', 'Owner', 'StorageClass'].include?(key)}
|
||||
data['LastModified'] = Time.parse(data['LastModified'])
|
||||
data
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,27 +1,54 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
unless Fog.mocking?
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
# Get configured payer for an S3 bucket
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - name of bucket to get payer for
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'Payer'<~String> - Specifies who pays for download and requests
|
||||
def get_request_payment(bucket_name)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => {},
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'GET',
|
||||
:parser => Fog::Parsers::AWS::S3::GetRequestPayment.new,
|
||||
:query => 'requestPayment'
|
||||
})
|
||||
end
|
||||
|
||||
# Get configured payer for an S3 bucket
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - name of bucket to get payer for
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~Hash>:
|
||||
# * 'Payer'<~String> - Specifies who pays for download and requests
|
||||
def get_request_payment(bucket_name)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => {},
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'GET',
|
||||
:parser => Fog::Parsers::AWS::S3::GetRequestPayment.new,
|
||||
:query => 'requestPayment'
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
def get_request_payment(bucket_name)
|
||||
response = Fog::Response.new
|
||||
bucket_status = get_bucket(bucket_name).status
|
||||
if bucket_status == 200
|
||||
response.status = 200
|
||||
bucket = @data['Buckets'].select {|bucket| bucket['Name'] == bucket_name}.first
|
||||
response.body = { 'Payer' => bucket['Payer'] }
|
||||
else
|
||||
response.status = bucket_status
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,41 +1,61 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
unless Fog.mocking?
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
# Get headers for an object from S3
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - Name of bucket to read from
|
||||
# * object_name<~String> - Name of object to read
|
||||
# * options<~Hash>:
|
||||
# * 'If-Match'<~String> - Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed).
|
||||
# * 'If-Modified-Since'<~Time> - Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified).
|
||||
# * 'If-None-Match'<~String> - Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified)
|
||||
# * 'If-Unmodified-Since'<~Time> - Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed).
|
||||
# * 'Range'<~String> - Range of object to download
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~String> - Contents of object
|
||||
# * headers<~Hash>:
|
||||
# * 'Content-Length'<~String> - Size of object contents
|
||||
# * 'Content-Type'<~String> - MIME type of object
|
||||
# * 'ETag'<~String> - Etag of object
|
||||
# * 'Last-Modified'<~String> - Last modified timestamp for object
|
||||
def head_object(bucket_name, object_name, options={})
|
||||
headers = {}
|
||||
headers['If-Modified-Since'] = options['If-Modified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
||||
headers['If-Unmodified-Since'] = options['If-Unmodified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
||||
headers.merge!(options)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => headers,
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'HEAD',
|
||||
:path => object_name
|
||||
})
|
||||
end
|
||||
|
||||
# Get headers for an object from S3
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - Name of bucket to read from
|
||||
# * object_name<~String> - Name of object to read
|
||||
# * options<~Hash>:
|
||||
# * 'If-Match'<~String> - Returns object only if its etag matches this value, otherwise returns 412 (Precondition Failed).
|
||||
# * 'If-Modified-Since'<~Time> - Returns object only if it has been modified since this time, otherwise returns 304 (Not Modified).
|
||||
# * 'If-None-Match'<~String> - Returns object only if its etag differs from this value, otherwise returns 304 (Not Modified)
|
||||
# * 'If-Unmodified-Since'<~Time> - Returns object only if it has not been modified since this time, otherwise returns 412 (Precodition Failed).
|
||||
# * 'Range'<~String> - Range of object to download
|
||||
#
|
||||
# ==== Returns
|
||||
# * response<~Fog::AWS::Response>:
|
||||
# * body<~String> - Contents of object
|
||||
# * headers<~Hash>:
|
||||
# * 'Content-Length'<~String> - Size of object contents
|
||||
# * 'Content-Type'<~String> - MIME type of object
|
||||
# * 'ETag'<~String> - Etag of object
|
||||
# * 'Last-Modified'<~String> - Last modified timestamp for object
|
||||
def head_object(bucket_name, object_name, options={})
|
||||
headers = {}
|
||||
headers['If-Modified-Since'] = options['If-Modified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
||||
headers['If-Unmodified-Since'] = options['If-Unmodified-Since'].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") if options['If-Modified-Since']
|
||||
headers.merge!(options)
|
||||
request({
|
||||
:expects => 200,
|
||||
:headers => headers,
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'HEAD',
|
||||
:path => object_name
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
def head_object(bucket_name, object_name, options = {})
|
||||
response = get_object(bucket_name, object_name, options)
|
||||
response.body = nil
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -50,7 +50,8 @@ else
|
|||
@data['Buckets'] << {
|
||||
'Name' => bucket_name,
|
||||
'Contents' => [],
|
||||
'CreationDate' => Time.now
|
||||
'CreationDate' => Time.now,
|
||||
'Payer' => 'BucketOwner'
|
||||
}
|
||||
response
|
||||
end
|
||||
|
|
|
@ -1,29 +1,57 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
unless Fog.mocking?
|
||||
|
||||
# Change who pays for requests to an S3 bucket
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - name of bucket to modify
|
||||
# * payer<~String> - valid values are BucketOwner or Requester
|
||||
def put_request_payment(bucket_name, payer)
|
||||
data =
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
# Change who pays for requests to an S3 bucket
|
||||
#
|
||||
# ==== Parameters
|
||||
# * bucket_name<~String> - name of bucket to modify
|
||||
# * payer<~String> - valid values are BucketOwner or Requester
|
||||
def put_request_payment(bucket_name, payer)
|
||||
data =
|
||||
<<-DATA
|
||||
<RequestPaymentConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
||||
<Payer>#{payer}</Payer>
|
||||
</RequestPaymentConfiguration>
|
||||
DATA
|
||||
request({
|
||||
:body => data,
|
||||
:expects => 200,
|
||||
:headers => {},
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'PUT',
|
||||
:query => "requestPayment"
|
||||
})
|
||||
end
|
||||
request({
|
||||
:body => data,
|
||||
:expects => 200,
|
||||
:headers => {},
|
||||
:host => "#{bucket_name}.#{@host}",
|
||||
:method => 'PUT',
|
||||
:query => "requestPayment"
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class S3
|
||||
|
||||
def put_request_payment(bucket_name, payer)
|
||||
response = Fog::Response.new
|
||||
bucket_status = get_bucket(bucket_name).status
|
||||
if bucket_status == 200
|
||||
response.status = 200
|
||||
bucket = @data['Buckets'].select {|bucket| bucket['Name'] == bucket_name}.first
|
||||
bucket['Payer'] = payer
|
||||
else
|
||||
response.status = bucket_status
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -3,21 +3,22 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|||
describe 'S3.copy_object' do
|
||||
|
||||
before(:all) do
|
||||
s3.put_bucket('fogcopyobjectsource')
|
||||
@s3 = s3
|
||||
@s3.put_bucket('fogcopyobjectsource')
|
||||
file = File.open(File.dirname(__FILE__) + '/../../lorem.txt', 'r')
|
||||
s3.put_object('fogcopyobjectsource', 'fog_copy_object_source', file)
|
||||
s3.put_bucket('fogcopyobjectdestination')
|
||||
@s3.put_object('fogcopyobjectsource', 'fog_copy_object_source', file)
|
||||
@s3.put_bucket('fogcopyobjectdestination')
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
s3.delete_object('fogcopyobjectdestination', 'fog_copy_object_destination')
|
||||
s3.delete_bucket('fogcopyobjectdestination')
|
||||
s3.delete_object('fogcopyobjectsource', 'fog_copy_object_source')
|
||||
s3.delete_bucket('fogcopyobjectsource')
|
||||
@s3.delete_object('fogcopyobjectdestination', 'fog_copy_object_destination')
|
||||
@s3.delete_bucket('fogcopyobjectdestination')
|
||||
@s3.delete_object('fogcopyobjectsource', 'fog_copy_object_source')
|
||||
@s3.delete_bucket('fogcopyobjectsource')
|
||||
end
|
||||
|
||||
it 'should return proper attributes' do
|
||||
actual = s3.copy_object(
|
||||
actual = @s3.copy_object(
|
||||
'fogcopyobjectsource', 'fog_copy_object_source',
|
||||
'fogcopyobjectdestination', 'fog_copy_object_destination'
|
||||
)
|
||||
|
|
|
@ -3,18 +3,19 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|||
describe 'S3.get_bucket' do
|
||||
|
||||
before(:all) do
|
||||
s3.put_bucket('foggetbucket')
|
||||
@s3 = s3
|
||||
@s3.put_bucket('foggetbucket')
|
||||
file = File.open(File.dirname(__FILE__) + '/../../lorem.txt', 'r')
|
||||
s3.put_object('foggetbucket', 'fog_get_bucket', file)
|
||||
@s3.put_object('foggetbucket', 'fog_get_bucket', file)
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
s3.delete_object('foggetbucket', 'fog_get_bucket')
|
||||
s3.delete_bucket('foggetbucket')
|
||||
@s3.delete_object('foggetbucket', 'fog_get_bucket')
|
||||
@s3.delete_bucket('foggetbucket')
|
||||
end
|
||||
|
||||
it 'should return proper attributes' do
|
||||
actual = s3.get_bucket('foggetbucket')
|
||||
actual = @s3.get_bucket('foggetbucket')
|
||||
actual.body['IsTruncated'].should == false
|
||||
actual.body['Marker'].should be_a(String)
|
||||
actual.body['MaxKeys'].should be_an(Integer)
|
||||
|
|
|
@ -3,15 +3,16 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|||
describe 'S3.get_request_payment' do
|
||||
|
||||
before(:all) do
|
||||
s3.put_bucket('foggetrequestpayment')
|
||||
@s3 = s3
|
||||
@s3.put_bucket('foggetrequestpayment')
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
s3.delete_bucket('foggetrequestpayment')
|
||||
@s3.delete_bucket('foggetrequestpayment')
|
||||
end
|
||||
|
||||
it 'should return proper attributes' do
|
||||
actual = s3.get_request_payment('foggetrequestpayment')
|
||||
actual = @s3.get_request_payment('foggetrequestpayment')
|
||||
actual.status.should == 200
|
||||
actual.body['Payer'].should == 'BucketOwner'
|
||||
end
|
||||
|
|
|
@ -3,18 +3,19 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|||
describe 'S3.head_object' do
|
||||
|
||||
before(:all) do
|
||||
s3.put_bucket('fogheadobject')
|
||||
@s3 = s3
|
||||
@s3.put_bucket('fogheadobject')
|
||||
file = File.open(File.dirname(__FILE__) + '/../../lorem.txt', 'r')
|
||||
s3.put_object('fogheadobject', 'fog_head_object', file)
|
||||
@s3.put_object('fogheadobject', 'fog_head_object', file)
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
s3.delete_object('fogheadobject', 'fog_head_object')
|
||||
s3.delete_bucket('fogheadobject')
|
||||
@s3.delete_object('fogheadobject', 'fog_head_object')
|
||||
@s3.delete_bucket('fogheadobject')
|
||||
end
|
||||
|
||||
it 'should return proper attributes' do
|
||||
actual = s3.head_object('fogheadobject', 'fog_head_object')
|
||||
actual = @s3.head_object('fogheadobject', 'fog_head_object')
|
||||
actual.status.should == 200
|
||||
file = File.open(File.dirname(__FILE__) + '/../../lorem.txt', 'r')
|
||||
data = file.read
|
||||
|
|
|
@ -3,15 +3,16 @@ require File.dirname(__FILE__) + '/../../spec_helper'
|
|||
describe 'S3.put_request_payment' do
|
||||
|
||||
before(:all) do
|
||||
s3.put_bucket('fogputrequestpayment')
|
||||
@s3 = s3
|
||||
@s3.put_bucket('fogputrequestpayment')
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
s3.delete_bucket('fogputrequestpayment')
|
||||
@s3.delete_bucket('fogputrequestpayment')
|
||||
end
|
||||
|
||||
it 'should return proper attributes' do
|
||||
actual = s3.put_request_payment('fogputrequestpayment', 'Requester')
|
||||
actual = @s3.put_request_payment('fogputrequestpayment', 'Requester')
|
||||
actual.status.should == 200
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue