Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Fix metadata file handle leak in get_object #61

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pkg/*
.bundle
tmp
test_root
Gemfile.lock
14 changes: 8 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ GEM
mime-types
xml-simple
builder (3.2.2)
mime-types (1.25)
rake (10.1.0)
rest-client (1.6.7)
mime-types (>= 1.16)
mime-types (2.3)
netrc (0.7.7)
rake (10.3.2)
rest-client (1.7.2)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
right_aws (3.1.0)
right_http_connection (>= 1.2.5)
right_http_connection (1.4.0)
thor (0.18.1)
xml-simple (1.1.2)
thor (0.19.1)
xml-simple (1.1.4)

PLATFORMS
ruby
Expand Down
39 changes: 29 additions & 10 deletions lib/fakes3/file_store.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def initialize(root)
@buckets << bucket_obj
@bucket_hash[bucket_name] = bucket_obj
end
FileUtils.mkdir_p(File.join(@root,"policies"))
end

# Pass a rate limit in bytes per second
Expand Down Expand Up @@ -60,6 +61,7 @@ def create_bucket(bucket)
@buckets << bucket_obj
@bucket_hash[bucket] = bucket_obj
end
File.open(File.join(@root,"policies",bucket),'w') { |file| file.write("") }
bucket_obj
end

Expand All @@ -68,22 +70,25 @@ def delete_bucket(bucket_name)
raise NoSuchBucket if !bucket
raise BucketNotEmpty if bucket.objects.count > 0
FileUtils.rm_r(get_bucket_folder(bucket))
File.delete(File.join(@root,"policies",bucket_name))
@bucket_hash.delete(bucket_name)
end

def get_object(bucket,object_name, request)
begin
real_obj = S3Object.new
obj_root = File.join(@root,bucket,object_name,SHUCK_METADATA_DIR)
metadata = YAML.load(File.open(File.join(obj_root,"metadata"),'rb'))
real_obj.name = object_name
real_obj.md5 = metadata[:md5]
real_obj.content_type = metadata.fetch(:content_type) { "application/octet-stream" }
#real_obj.io = File.open(File.join(obj_root,"content"),'rb')
real_obj.io = RateLimitableFile.open(File.join(obj_root,"content"),'rb')
real_obj.size = metadata.fetch(:size) { 0 }
real_obj.creation_date = File.ctime(obj_root).utc.iso8601()
real_obj.modified_date = metadata.fetch(:modified_date) { File.mtime(File.join(obj_root,"content")).utc.iso8601() }
File.open(File.join(obj_root,"metadata"),'rb') do |metadata_file|
metadata = YAML.load(metadata_file)
real_obj.name = object_name
real_obj.md5 = metadata[:md5]
real_obj.content_type = metadata.fetch(:content_type) { "application/octet-stream" }
#real_obj.io = File.open(File.join(obj_root,"content"),'rb')
real_obj.io = RateLimitableFile.open(File.join(obj_root,"content"),'rb')
real_obj.size = metadata.fetch(:size) { 0 }
real_obj.creation_date = File.ctime(obj_root).utc.iso8601()
real_obj.modified_date = metadata.fetch(:modified_date) { File.mtime(File.join(obj_root,"content")).utc.iso8601() }
end
return real_obj
rescue
puts $!
Expand Down Expand Up @@ -162,7 +167,7 @@ def store_object(bucket,object_name,request)
# TODO put a tmpfile here first and mv it over at the end

match=request.content_type.match(/^multipart\/form-data; boundary=(.+)/)
boundary = match[1] if match
boundary = match[1] if match
if boundary
boundary = WEBrick::HTTPUtils::dequote(boundary)
filedata = WEBrick::HTTPUtils::parse_form_data(request.body, boundary)
Expand Down Expand Up @@ -211,6 +216,20 @@ def delete_object(bucket,object_name,request)
end
end

def get_policy(bucket)
begin
policyname = File.join(@root,"policies",bucket)
return File.read(policyname)
end
end

def put_policy(bucket,policy)
begin
policyname = File.join(@root,"policies",bucket)
File.open(policyname,'w') { |file| file.write(policy) }
end
end

def create_metadata(content,request)
metadata = {}
metadata[:md5] = Digest::MD5.file(content).hexdigest
Expand Down
23 changes: 20 additions & 3 deletions lib/fakes3/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Request
MOVE = "MOVE"
DELETE_OBJECT = "DELETE_OBJECT"
DELETE_BUCKET = "DELETE_BUCKET"
PUT_POLICY = "PUT_POLICY"
GET_POLICY = "GET_POLICY"

attr_accessor :bucket,:object,:type,:src_bucket,
:src_object,:method,:webrick_request,
Expand Down Expand Up @@ -126,6 +128,11 @@ def do_GET(request, response)
else
response.body = real_obj.io
end
when 'GET_POLICY'
response.status = 200
response['Content-Type'] = "application/xml"
response.body = @store.get_policy(s_req.bucket)
response['Content-Length'] = response.body.length
end
end

Expand All @@ -151,6 +158,8 @@ def do_PUT(request,response)
response.header['ETag'] = "\"#{real_obj.md5}\""
when Request::CREATE_BUCKET
@store.create_bucket(s_req.bucket)
when Request::PUT_POLICY
@store.put_policy(s_req.bucket, request.body)
end
end

Expand Down Expand Up @@ -258,8 +267,12 @@ def normalize_get(webrick_req,s_req)
end

if elems.size < 2
s_req.type = Request::LS_BUCKET
s_req.query = query
if webrick_req.query_string == "policy"
s_req.type = Request::GET_POLICY
else
s_req.type = Request::LS_BUCKET
s_req.query = query
end
else
if query["acl"] == ""
s_req.type = Request::GET_ACL
Expand All @@ -284,7 +297,11 @@ def normalize_put(webrick_req,s_req)
elems = path[1,path_len].split("/")
s_req.bucket = elems[0]
if elems.size == 1
s_req.type = Request::CREATE_BUCKET
if webrick_req.query_string == "policy"
s_req.type = Request::PUT_POLICY
else
s_req.type = Request::CREATE_BUCKET
end
else
if webrick_req.request_line =~ /\?acl/
s_req.type = Request::SET_ACL
Expand Down