Skip to content

Commit

Permalink
Implement support for the COPY operation on a slot/object.
Browse files Browse the repository at this point in the history
  • Loading branch information
Justin Greer authored and mattjamieson committed Oct 23, 2009
1 parent 1f67c3e commit b26647b
Showing 1 changed file with 51 additions and 35 deletions.
86 changes: 51 additions & 35 deletions lib/parkplace/s3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,45 +143,61 @@ def put(bucket_name, oid)
only_can_write bucket
raise MissingContentLength unless @env.HTTP_CONTENT_LENGTH

temp_path = @in.path rescue nil
readlen = 0
md5 = MD5.new
Tempfile.open(File.basename(oid)) do |tmpf|
temp_path ||= tmpf.path
tmpf.binmode
while part = @in.read(BUFSIZE)
readlen += part.size
md5 << part
tmpf << part unless @in.is_a?(Tempfile)
end
end
if @env.HTTP_X_AMZ_COPY_SOURCE.to_s =~ /\/(.+?)\/(.+)/
source_bucket_name = $1
source_oid = $2

source_slot = ParkPlace::Models::Bucket.find_root(source_bucket_name).find_slot(source_oid)
only_can_read source_slot

fileinfo = FileInfo.new
[:mime_type, :disposition, :size, :md5].each { |a| fileinfo.send("#{a}=", source_slot.obj.send(a)) }
fileinfo.path = File.join(bucket_name, File.basename(source_slot.obj.path))
fileinfo.path.succ! while File.exists?(File.join(STORAGE_PATH, fileinfo.path))
file_path = File.join(STORAGE_PATH, fileinfo.path)
FileUtils.mkdir_p(File.dirname(file_path))
FileUtils.cp(File.join(STORAGE_PATH, source_slot.obj.path), file_path)
else
temp_path = @in.path rescue nil
readlen = 0
md5 = MD5.new
Tempfile.open(File.basename(oid)) do |tmpf|
temp_path ||= tmpf.path
tmpf.binmode
while part = @in.read(BUFSIZE)
readlen += part.size
md5 << part
tmpf << part unless @in.is_a?(Tempfile)
end
end

fileinfo = FileInfo.new
fileinfo.mime_type = @env.HTTP_CONTENT_TYPE || "binary/octet-stream"
fileinfo.disposition = @env.HTTP_CONTENT_DISPOSITION
fileinfo.size = readlen
fileinfo.md5 = Base64.encode64(md5.digest).strip
fileinfo = FileInfo.new
fileinfo.mime_type = @env.HTTP_CONTENT_TYPE || "binary/octet-stream"
fileinfo.disposition = @env.HTTP_CONTENT_DISPOSITION
fileinfo.size = readlen
fileinfo.md5 = Base64.encode64(md5.digest).strip

raise IncompleteBody if @env.HTTP_CONTENT_LENGTH.to_i != readlen
if @env.HTTP_CONTENT_MD5
b64cs = /[0-9a-zA-Z+\/]/
re = /
^
(?:#{b64cs}{4})* # any four legal chars
(?:#{b64cs}{2} # right-padded by up to two =s
(?:#{b64cs}|=){2})?
$
/ox
raise IncompleteBody if @env.HTTP_CONTENT_LENGTH.to_i != readlen
if @env.HTTP_CONTENT_MD5
b64cs = /[0-9a-zA-Z+\/]/
re = /
^
(?:#{b64cs}{4})* # any four legal chars
(?:#{b64cs}{2} # right-padded by up to two =s
(?:#{b64cs}|=){2})?
$
/ox

raise InvalidDigest unless @env.HTTP_CONTENT_MD5 =~ re
raise BadDigest unless fileinfo.md5 == @env.HTTP_CONTENT_MD5
end
raise InvalidDigest unless @env.HTTP_CONTENT_MD5 =~ re
raise BadDigest unless fileinfo.md5 == @env.HTTP_CONTENT_MD5
end

fileinfo.path = File.join(bucket_name, File.basename(temp_path))
fileinfo.path.succ! while File.exists?(File.join(STORAGE_PATH, fileinfo.path))
file_path = File.join(STORAGE_PATH, fileinfo.path)
FileUtils.mkdir_p(File.dirname(file_path))
FileUtils.mv(temp_path, file_path)
fileinfo.path = File.join(bucket_name, File.basename(temp_path))
fileinfo.path.succ! while File.exists?(File.join(STORAGE_PATH, fileinfo.path))
file_path = File.join(STORAGE_PATH, fileinfo.path)
FileUtils.mkdir_p(File.dirname(file_path))
FileUtils.mv(temp_path, file_path)
end

slot = nil
meta = @meta.empty? ? nil : {}.merge(@meta)
Expand Down

0 comments on commit b26647b

Please sign in to comment.