Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Apr 18th, 2012  |  syntax: None  |  size: 6.40 KB  |  hits: 11  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.     def create_slot
  2.       bucket = Bucket.find_root(params[:captures].first)
  3.       begin
  4.         slot = bucket.find_slot(params[:captures].last)
  5.         only_can_write slot unless slot.nil?
  6.       rescue NoSuchKey
  7.         only_can_write bucket
  8.       end
  9.    
  10.       raise MissingContentLength unless env['CONTENT_LENGTH']
  11.  
  12.       if params.has_key?('acl')
  13.         slot = bucket.find_slot(params[:captures].last)
  14.         slot.grant(requested_acl(slot))
  15.         headers 'ETag' => slot.etag, 'Content-Length' => 0.to_s
  16.         body ""
  17.       elsif env['HTTP_X_AMZ_COPY_SOURCE'].to_s =~ /\/?(.+?)%2F(.+)/
  18.         source_bucket_name = $1
  19.         source_oid = $2
  20.         source_oid = source_oid.gsub("%2F","\/")
  21.  
  22.         source_slot = Bucket.find_root(source_bucket_name).find_slot(source_oid)
  23.         @meta = source_slot.meta unless !env['HTTP_X_AMZ_METADATA_DIRECTIVE'].nil? && env['HTTP_X_AMZ_METADATA_DIRECTIVE'].upcase == "REPLACE"
  24.         only_can_read source_slot
  25.  
  26.         unless env['HTTP_X_AMZ_COPY_SOURCE_IF_MATCH'].blank?
  27.           raise PreconditionFailed if source_slot.obj.etag != env['HTTP_X_AMZ_COPY_SOURCE_IF_MATCH']
  28.         end
  29.         unless env['HTTP_X_AMZ_COPY_SOURCE_IF_NONE_MATCH'].blank?
  30.           raise PreconditionFailed if source_slot.obj.etag == env['HTTP_X_AMZ_COPY_SOURCE_IF_NONE_MATCH']
  31.         end
  32.         unless env['HTTP_X_AMZ_COPY_SOURCE_IF_UNMODIFIED_SINCE'].blank?
  33.           raise PreconditionFailed if Time.httpdate(env['HTTP_X_AMZ_COPY_SOURCE_IF_UNMODIFIED_SINCE']) > source_slot.updated_at
  34.         end
  35.         unless env['HTTP_X_AMZ_COPY_SOURCE_IF_MODIFIED_SINCE'].blank?
  36.           raise PreconditionFailed if Time.httpdate(env['HTTP_X_AMZ_COPY_SOURCE_IF_MODIFIED_SINCE']) < source_slot.updated_at
  37.         end
  38.  
  39.         temp_path = File.join(STORAGE_PATH, source_slot.obj.path)
  40.         fileinfo = source_slot.obj
  41.         fileinfo.etag='""' if params[:captures].last[-8,8] == '$folder$'
  42.         fileinfo.path = File.join(params[:captures].first, rand(10000).to_s(36) + '_' + File.basename(temp_path))
  43.         fileinfo.path.succ! while File.exists?(File.join(STORAGE_PATH, fileinfo.path))
  44.         file_path = File.join(STORAGE_PATH, fileinfo.path)
  45.       else
  46.         temp_path = env['rack.input'][:path] rescue nil
  47.         readlen = 0
  48.         md5 = MD5.new
  49.  
  50.         Tempfile.open(File.basename(params[:captures].last)) do |tmpf|
  51.           temp_path ||= tmpf.path
  52.           tmpf.binmode
  53.           while part = env['rack.input'].read(BUFSIZE)
  54.             readlen += part.size
  55.             md5 << part
  56.             tmpf << part unless env['rack.input'].is_a?(Tempfile)
  57.           end
  58.         end
  59.  
  60.         fileinfo = FileInfo.new
  61.         fileinfo.mime_type = env['CONTENT_TYPE'] || "binary/octet-stream"
  62.         fileinfo.disposition = env['CONTENT_DISPOSITION']
  63.         fileinfo.size = readlen
  64.         fileinfo.md5 = Base64.encode64(md5.digest).strip
  65.         fileinfo.etag = '"' + md5.hexdigest + '"'
  66.         fileinfo.etag='""' if params[:captures].last[-8,8] == '$folder$'
  67.  
  68.         raise IncompleteBody if env['CONTENT_LENGTH'].to_i != readlen
  69.         if env['HTTP_CONTENT_MD5']
  70.           b64cs = /[0-9a-zA-Z+\/]/
  71.             re = /
  72.             ^
  73.           (?:#{b64cs}{4})*       # any four legal chars
  74.             (?:#{b64cs}{2}        # right-padded by up to two =s
  75.              (?:#{b64cs}|=){2})?
  76.              $
  77.           /ox
  78.  
  79.           raise InvalidDigest unless env['HTTP_CONTENT_MD5'] =~ re
  80.           raise BadDigest unless fileinfo.md5 == env['HTTP_CONTENT_MD5']
  81.         end
  82.       end
  83.  
  84.       mdata = {}
  85.  
  86.       slot = nil
  87.       meta = @meta.nil? || @meta.empty? ? {} : {}.merge(@meta)
  88.       owner_id = @user ? @user.id : bucket.owner_id
  89.  
  90.       begin
  91.         slot = bucket.find_slot(params[:captures].last)
  92.         if slot.versioning_enabled?
  93.           nslot = slot.clone()
  94.           slot.update_attributes(:deleted => true)
  95.           slot = nslot
  96.         end
  97.         if source_slot.nil?
  98.           fileinfo.path = slot.obj.path
  99.           file_path = File.join(STORAGE_PATH,fileinfo.path)
  100.           FileUtils.mv(temp_path, file_path,{ :force => true })
  101.         else
  102.           FileUtils.cp(temp_path, file_path)
  103.         end
  104.         slot.update_attributes(:owner_id => owner_id, :meta => meta, :obj => fileinfo, :size => fileinfo.size)
  105.       rescue NoSuchKey
  106.         if source_slot.nil?
  107.           fileinfo.path = File.join(params[:captures].first, rand(10000).to_s(36) + '_' + File.basename(temp_path))
  108.           fileinfo.path.succ! while File.exists?(File.join(STORAGE_PATH, fileinfo.path))
  109.           file_path = File.join(STORAGE_PATH,fileinfo.path)
  110.           FileUtils.mkdir_p(File.dirname(file_path))
  111.           FileUtils.mv(temp_path, file_path)
  112.         else
  113.           FileUtils.cp(temp_path, file_path)
  114.         end
  115.         slot = Slot.create(:name => params[:captures].last, :owner_id => owner_id, :meta => meta, :obj => fileinfo, :size => fileinfo.size)
  116.         bucket.add_child(slot)
  117.       end
  118.       slot.grant(requested_acl(slot))
  119.  
  120.       h = { 'Content-Length' => 0.to_s, 'ETag' => slot.etag }
  121.       if slot.versioning_enabled?
  122.         begin
  123.           slot.git_repository.add(File.basename(fileinfo.path))
  124.           tmp = slot.git_repository.commit("Added #{slot.name} to the Git repository.")
  125.           slot.git_update
  126.           slot.update_attributes(:version => slot.git_object.objectish)
  127.           h.merge!({ 'x-amz-version-id' => slot.git_object.objectish })
  128.         rescue Git::GitExecuteError => error_message
  129.           puts "[#{Time.now}] GIT: #{error_message}"
  130.         end
  131.       end
  132.  
  133.       if env['HTTP_X_AMZ_COPY_SOURCE'].blank?
  134.         redirect_url = (params[:success_action_redirect] || params[:redirect])
  135.         redirect redirect_url unless redirect_url.blank?
  136.         status params[:success_action_status].to_i if params[:success_action_status]
  137.         headers h
  138.         puts "----------------#{h.inspect}---------"
  139.         body ""
  140.       else
  141.         h['Content-Length'] = nil
  142.         headers h
  143.         xml do |x|
  144.           x.CopyObjectResult do
  145.             x.LastModified slot.updated_at.xmlschema
  146.             x.Etag slot.etag
  147.           end
  148.         end
  149.       end
  150.     end
  151.  
  152.     # delete slot
  153.     delete %r{^/(.+?)/(.+)$} do
  154.       bucket = Bucket.find_root(params[:captures].first)
  155.       only_can_write bucket
  156.  
  157.       begin
  158.         @slot = bucket.find_slot(params[:captures].last)
  159.         if @slot.versioning_enabled?
  160.           begin
  161.             @slot.git_repository.remove(File.basename(@slot.obj.path))
  162.             @slot.git_repository.commit("Removed #{@slot.name} from the Git repository.")
  163.             @slot.git_update
  164.           rescue Git::GitExecuteError => error_message
  165.             puts "[#{Time.now}] GIT: #{error_message}"
  166.           end
  167.         end
  168.  
  169.         @slot.remove_from_filesystem
  170.         @slot.destroy
  171.         status 204
  172.         body ""
  173.       rescue NoSuchKey
  174.         status 204
  175.         body ""
  176.       end
  177.     end
  178.  
  179.     error do
  180.       error = Builder::XmlMarkup.new
  181.       error.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
  182.  
  183.       error.Error do
  184.         error.Code request.env['sinatra.error'].code
  185.         error.Message request.env['sinatra.error'].message
  186.         error.Resource env['PATH_INFO']
  187.         error.RequestId @request_id
  188.       end
  189.  
  190.       status request.env['sinatra.error'].status.nil? ? 500 : request.env['sinatra.error'].status
  191.       content_type 'application/xml'
  192.       body error.target!
  193.       run_callback_for :error => request.env['sinatra.error'].code
  194.     end