mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
[aws|storage] Handle S3 object deletions in the face of versioning.
This commit is contained in:
parent
f9de06b603
commit
f2b61321bb
5 changed files with 38 additions and 9 deletions
|
@ -36,7 +36,20 @@ module Fog
|
||||||
response = Excon::Response.new
|
response = Excon::Response.new
|
||||||
if bucket = self.data[:buckets][bucket_name]
|
if bucket = self.data[:buckets][bucket_name]
|
||||||
response.status = 204
|
response.status = 204
|
||||||
|
|
||||||
|
if bucket[:versioning]
|
||||||
|
delete_marker = {
|
||||||
|
:delete_marker => true,
|
||||||
|
'Key' => object_name,
|
||||||
|
'VersionId' => Fog::Mock.random_base64(32),
|
||||||
|
'Last-Modified' => Fog::Time.now.to_date_header
|
||||||
|
}
|
||||||
|
|
||||||
|
bucket[:objects][object_name] ||= []
|
||||||
|
bucket[:objects][object_name] << delete_marker
|
||||||
|
else
|
||||||
bucket[:objects].delete(object_name)
|
bucket[:objects].delete(object_name)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
response.status = 404
|
response.status = 404
|
||||||
raise(Excon::Errors.status_error({:expects => 204}, response))
|
raise(Excon::Errors.status_error({:expects => 204}, response))
|
||||||
|
|
|
@ -73,7 +73,8 @@ module Fog
|
||||||
(prefix && object['Key'][0...prefix.length] != prefix) ||
|
(prefix && object['Key'][0...prefix.length] != prefix) ||
|
||||||
(marker && object['Key'] <= marker) ||
|
(marker && object['Key'] <= marker) ||
|
||||||
(delimiter && object['Key'][(prefix ? prefix.length : 0)..-1].include?(delimiter) \
|
(delimiter && object['Key'][(prefix ? prefix.length : 0)..-1].include?(delimiter) \
|
||||||
&& common_prefixes << object['Key'].sub(/^(#{prefix}[^#{delimiter}]+.).*/, '\1'))
|
&& common_prefixes << object['Key'].sub(/^(#{prefix}[^#{delimiter}]+.).*/, '\1')) ||
|
||||||
|
object.has_key?(:delete_marker)
|
||||||
end.map do |object|
|
end.map do |object|
|
||||||
data = object.reject {|key, value| !['ETag', 'Key', 'StorageClass'].include?(key)}
|
data = object.reject {|key, value| !['ETag', 'Key', 'StorageClass'].include?(key)}
|
||||||
data.merge!({
|
data.merge!({
|
||||||
|
|
|
@ -87,14 +87,23 @@ module Fog
|
||||||
(delimiter && object['Key'][(prefix ? prefix.length : 0)..-1].include?(delimiter) \
|
(delimiter && object['Key'][(prefix ? prefix.length : 0)..-1].include?(delimiter) \
|
||||||
&& common_prefixes << object['Key'].sub(/^(#{prefix}[^#{delimiter}]+.).*/, '\1'))
|
&& common_prefixes << object['Key'].sub(/^(#{prefix}[^#{delimiter}]+.).*/, '\1'))
|
||||||
end.map do |object|
|
end.map do |object|
|
||||||
data = { 'Version' => {} }
|
if object.has_key?(:delete_marker)
|
||||||
data['Version'] = object.reject {|key, value| !['ETag', 'Key', 'StorageClass', 'VersionId'].include?(key)}
|
tag_name = 'DeleteMarker'
|
||||||
data['Version'].merge!({
|
extracted_attrs = ['Key', 'VersionId']
|
||||||
|
else
|
||||||
|
tag_name = 'Version'
|
||||||
|
extracted_attrs = ['ETag', 'Key', 'StorageClass', 'VersionId']
|
||||||
|
end
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data[tag_name] = object.reject { |key, value| !extracted_attrs.include?(key) }
|
||||||
|
data[tag_name].merge!({
|
||||||
'LastModified' => Time.parse(object['Last-Modified']),
|
'LastModified' => Time.parse(object['Last-Modified']),
|
||||||
'Owner' => bucket['Owner'],
|
'Owner' => bucket['Owner'],
|
||||||
'Size' => object['Content-Length'].to_i,
|
|
||||||
'IsLatest' => object == bucket[:objects][object['Key']].last
|
'IsLatest' => object == bucket[:objects][object['Key']].last
|
||||||
})
|
})
|
||||||
|
|
||||||
|
data[tag_name]['Size'] = object['Content-Length'].to_i if tag_name == 'Version'
|
||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,8 @@ module Fog
|
||||||
end
|
end
|
||||||
response = Excon::Response.new
|
response = Excon::Response.new
|
||||||
if (bucket = self.data[:buckets][bucket_name])
|
if (bucket = self.data[:buckets][bucket_name])
|
||||||
if (object = bucket[:objects][object_name].last)
|
object = bucket[:objects][object_name].last if bucket[:objects].has_key?(object_name)
|
||||||
|
if (object && !object[:delete_marker])
|
||||||
if options['If-Match'] && options['If-Match'] != object['ETag']
|
if options['If-Match'] && options['If-Match'] != object['ETag']
|
||||||
response.status = 412
|
response.status = 412
|
||||||
elsif options['If-Modified-Since'] && options['If-Modified-Since'] > Time.parse(object['Last-Modified'])
|
elsif options['If-Modified-Since'] && options['If-Modified-Since'] > Time.parse(object['Last-Modified'])
|
||||||
|
|
|
@ -81,8 +81,13 @@ module Fog
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if bucket[:versioning]
|
||||||
bucket[:objects][object_name] ||= []
|
bucket[:objects][object_name] ||= []
|
||||||
bucket[:objects][object_name] << object
|
bucket[:objects][object_name] << object
|
||||||
|
else
|
||||||
|
bucket[:objects][object_name] = [object]
|
||||||
|
end
|
||||||
|
|
||||||
response.headers = {
|
response.headers = {
|
||||||
'Content-Length' => object['Content-Length'],
|
'Content-Length' => object['Content-Length'],
|
||||||
'Content-Type' => object['Content-Type'],
|
'Content-Type' => object['Content-Type'],
|
||||||
|
|
Loading…
Add table
Reference in a new issue