lib/fakes3/server.rb in fakes3-1.2.0 vs lib/fakes3/server.rb in fakes3-1.2.1

- old
+ new

@@ -2,13 +2,15 @@ require 'webrick' require 'webrick/https' require 'openssl' require 'securerandom' require 'cgi' +require 'uri' require 'fakes3/util' require 'fakes3/file_store' require 'fakes3/xml_adapter' +require 'fakes3/xml_parser' require 'fakes3/bucket_query' require 'fakes3/unsupported_operation' require 'fakes3/errors' require 'ipaddr' @@ -24,10 +26,11 @@ GET_ACL = "GET_ACL" SET_ACL = "SET_ACL" MOVE = "MOVE" DELETE_OBJECT = "DELETE_OBJECT" DELETE_BUCKET = "DELETE_BUCKET" + DELETE_OBJECTS = "DELETE_OBJECTS" attr_accessor :bucket, :object, :type, :src_bucket, :src_object, :method, :webrick_request, :path, :is_path_style, :query, :http_verb @@ -96,10 +99,11 @@ real_obj = @store.get_object(s_req.bucket, s_req.object, request) if !real_obj response.status = 404 response.body = XmlAdapter.error_no_such_key(s_req.object) response['Content-Type'] = "application/xml" + response['Access-Control-Allow-Origin'] = '*' return end if_none_match = request["If-None-Match"] if if_none_match == "\"#{real_obj.md5}\"" or if_none_match == "*" @@ -122,12 +126,11 @@ if real_obj.content_encoding response.header['X-Content-Encoding'] = real_obj.content_encoding response.header['Content-Encoding'] = real_obj.content_encoding end - response['Content-Disposition'] = real_obj.content_disposition if real_obj.content_disposition - stat = File::Stat.new(real_obj.io.path) + response['Content-Disposition'] = real_obj.content_disposition ? real_obj.content_disposition : 'attachment' response['Last-Modified'] = Time.iso8601(real_obj.modified_date).httpdate response.header['ETag'] = "\"#{real_obj.md5}\"" response['Accept-Ranges'] = "bytes" response['Last-Ranges'] = "bytes" @@ -135,10 +138,11 @@ real_obj.custom_metadata.each do |header, value| response.header['x-amz-meta-' + header] = value end + stat = File::Stat.new(real_obj.io.path) content_length = stat.size # Added Range Query support range = request.header["range"].first if range @@ -166,10 +170,14 @@ response.body = "" real_obj.io.close else response.body = real_obj.io end + + if real_obj.cache_control + response['Cache-Control'] = real_obj.cache_control + end end end def do_PUT(request, response) s_req = normalize_request(request) @@ -238,10 +246,14 @@ response.status = 200 end def do_POST(request,response) + if request.query_string === 'delete' + return do_DELETE(request, response) + end + s_req = normalize_request(request) key = request.query['key'] query = CGI::parse(request.request_uri.query || "") if query.has_key?('uploads') @@ -317,10 +329,14 @@ def do_DELETE(request, response) s_req = normalize_request(request) case s_req.type + when Request::DELETE_OBJECTS + bucket_obj = @store.get_bucket(s_req.bucket) + keys = XmlParser.delete_objects(s_req.webrick_request) + @store.delete_objects(bucket_obj,keys,s_req.webrick_request) when Request::DELETE_OBJECT bucket_obj = @store.get_bucket(s_req.bucket) @store.delete_object(bucket_obj,s_req.object,s_req.webrick_request) when Request::DELETE_BUCKET @store.delete_bucket(s_req.bucket) @@ -330,11 +346,10 @@ response.body = "" end def do_OPTIONS(request, response) super - response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Methods'] = 'PUT, POST, HEAD, GET, OPTIONS' response['Access-Control-Allow-Headers'] = 'Accept, Content-Type, Authorization, Content-Length, ETag, X-CSRF-Token, Content-Disposition' response['Access-Control-Expose-Headers'] = 'ETag' end @@ -354,14 +369,17 @@ else elems = path.split("/") end if elems.size == 0 - raise UnsupportedOperation + s_req.type = Request::DELETE_OBJECTS + s_req.query = query + s_req.webrick_request = webrick_req elsif elems.size == 1 - s_req.type = Request::DELETE_BUCKET + s_req.type = webrick_req.query_string == 'delete' ? Request::DELETE_OBJECTS : Request::DELETE_BUCKET s_req.query = query + s_req.webrick_request = webrick_req else s_req.type = Request::DELETE_OBJECT object = elems[1,elems.size].join('/') s_req.object = object end @@ -430,11 +448,12 @@ # TODO: also parse the x-amz-copy-source-range:bytes=first-last header # for multipart copy copy_source = webrick_req.header["x-amz-copy-source"] if copy_source and copy_source.size == 1 - src_elems = copy_source.first.split("/") + copy_source = URI.unescape copy_source.first + src_elems = copy_source.split("/") root_offset = src_elems[0] == "" ? 1 : 0 s_req.src_bucket = src_elems[root_offset] s_req.src_object = src_elems[1 + root_offset,src_elems.size].join("/") s_req.type = Request::COPY end @@ -480,10 +499,14 @@ when 'GET','HEAD' normalize_get(webrick_req,s_req) when 'DELETE' normalize_delete(webrick_req,s_req) when 'POST' - normalize_post(webrick_req,s_req) + if webrick_req.query_string != 'delete' + normalize_post(webrick_req,s_req) + else + normalize_delete(webrick_req,s_req) + end else raise "Unknown Request" end validate_request(s_req)