diff --git a/lib/fog/aws/requests/s3/get_bucket.rb b/lib/fog/aws/requests/s3/get_bucket.rb index 0a0f2bee7..b92e069dc 100644 --- a/lib/fog/aws/requests/s3/get_bucket.rb +++ b/lib/fog/aws/requests/s3/get_bucket.rb @@ -59,25 +59,33 @@ else module AWS class S3 + # FIXME: implement delimiter def get_bucket(bucket_name, options = {}) response = Fog::Response.new if bucket = Fog::AWS::S3.data[:buckets][bucket_name] response.status = 200 response.body = { - 'Contents' => bucket[:objects].values.map do |object| - data = object.reject {|key, value| !['ETag', 'Key', 'LastModified', 'Owner', 'Size', 'StorageClass'].include?(key)} - data.merge!({ - 'LastModified' => Time.parse(data['LastModified']), - 'Size' => data['Size'].to_i - }) + 'Contents' => bucket[:objects].values.sort {|x,y| x['Key'] <=> y['Key']}.reject do |object| + (options['prefix'] && object['Key'][0...options['prefix'].length] != options['prefix']) || + (options['marker'] && object['Key'] <= options['marker']) + end.map do |object| + data = object.reject {|key, value| !['ETag', 'Key', 'LastModified', 'Owner', 'Size', 'StorageClass'].include?(key)} + data.merge!({ + 'LastModified' => Time.parse(data['LastModified']), + 'Size' => data['Size'].to_i + }) data end, 'IsTruncated' => false, - 'Marker' => options['Marker'] || '', - 'MaxKeys' => options['MaxKeys'] || 1000, + 'Marker' => options['marker'] || '', + 'MaxKeys' => options['max-keys'] || 1000, 'Name' => bucket['Name'], - 'Prefix' => options['Prefix'] || '' + 'Prefix' => options['prefix'] || '' } + if options['max-keys'] && options['max-keys'] < response.body['Contents'].length + response.body['IsTruncated'] = true + response.body['Contents'] = response.body['Contents'][0...options['max-keys']] + end else response.status = 404 raise(Fog::Errors.status_error(200, 404, response)) diff --git a/spec/aws/requests/s3/get_bucket_spec.rb b/spec/aws/requests/s3/get_bucket_spec.rb index 386e3e78b..e82c971a6 100644 --- a/spec/aws/requests/s3/get_bucket_spec.rb +++ b/spec/aws/requests/s3/get_bucket_spec.rb @@ -5,11 +5,14 @@ describe 'S3.get_bucket' do before(:all) do 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_object', file) + file = File.open(File.dirname(__FILE__) + '/../../../lorem.txt', 'r') + s3.put_object('foggetbucket', 'fog_other_object', file) end after(:all) do - s3.delete_object('foggetbucket', 'fog_get_bucket') + s3.delete_object('foggetbucket', 'fog_object') + s3.delete_object('foggetbucket', 'fog_other_object') s3.delete_bucket('foggetbucket') end @@ -21,9 +24,10 @@ describe 'S3.get_bucket' do actual.body['Name'].should be_a(String) actual.body['Prefix'].should be_a(String) actual.body['Contents'].should be_an(Array) + actual.body['Contents'].length.should == 2 object = actual.body['Contents'].first object['ETag'].should be_a(String) - object['Key'].should == 'fog_get_bucket' + object['Key'].should == 'fog_object' object['LastModified'].should be_a(Time) owner = object['Owner'] owner['DisplayName'].should be_a(String) @@ -32,17 +36,58 @@ describe 'S3.get_bucket' do object['StorageClass'].should be_a(String) end - it 'should accept options' do - actual = s3.get_bucket('foggetbucket', 'prefix' => 'fog_') + it 'should accept marker option' do + actual = s3.get_bucket('foggetbucket', 'marker' => 'fog_object') actual.body['IsTruncated'].should == false actual.body['Marker'].should be_a(String) actual.body['MaxKeys'].should be_an(Integer) actual.body['Name'].should be_a(String) actual.body['Prefix'].should be_a(String) actual.body['Contents'].should be_an(Array) + actual.body['Contents'].length.should == 1 object = actual.body['Contents'].first object['ETag'].should be_a(String) - object['Key'].should == 'fog_get_bucket' + object['Key'].should == 'fog_other_object' + object['LastModified'].should be_a(Time) + owner = object['Owner'] + owner['DisplayName'].should be_a(String) + owner['ID'].should be_a(String) + object['Size'].should be_an(Integer) + object['StorageClass'].should be_a(String) + end + + it 'should respect max-keys option' do + actual = s3.get_bucket('foggetbucket', 'max-keys' => 1) + actual.body['IsTruncated'].should == true + actual.body['Marker'].should be_a(String) + actual.body['MaxKeys'].should be_an(Integer) + actual.body['Name'].should be_a(String) + actual.body['Prefix'].should be_a(String) + actual.body['Contents'].should be_an(Array) + actual.body['Contents'].length.should == 1 + object = actual.body['Contents'].first + object['ETag'].should be_a(String) + object['Key'].should == 'fog_object' + object['LastModified'].should be_a(Time) + owner = object['Owner'] + owner['DisplayName'].should be_a(String) + owner['ID'].should be_a(String) + object['Size'].should be_an(Integer) + object['StorageClass'].should be_a(String) + end + + it 'should accept prefix option' do + actual = s3.get_bucket('foggetbucket', 'prefix' => 'fog_ob') + actual.body['IsTruncated'].should == false + actual.body['Marker'].should be_a(String) + actual.body['MaxKeys'].should be_an(Integer) + actual.body['Name'].should be_a(String) + actual.body['Prefix'].should be_a(String) + actual.body['Contents'].should be_an(Array) + actual.body['Contents'].length.should == 1 + object = actual.body['Contents'].first + object['ETag'].should be_a(String) + object['Key'].should == 'fog_object' object['LastModified'].should be_a(Time) owner = object['Owner'] owner['DisplayName'].should be_a(String)