require 'digest' require 'json' require 'rack' require 'storage' class DataStorageServer MAX_BYTES=4096 def initialize(storage: Storage.new) @storage = storage end def get(path) oid = id_from(path) return not_found unless @storage.key?(oid) ok(body: @storage[oid]) end def put(io) data = io.read(MAX_BYTES) return bad_request unless data return bad_request unless io.eof? oid = Digest::SHA256.hexdigest(data) @storage[oid] = data render(status: '201', body: JSON.generate({ size: data.size, oid: oid })) end def destroy(path) oid = id_from(path) return not_found unless @storage.key?(oid) @storage.delete(oid) ok end def call(env) case env['REQUEST_METHOD'] when 'GET' get(env['PATH_INFO']) when 'PUT' put(env['rack.input']) when 'DELETE' destroy(env['PATH_INFO']) else not_found end end private def id_from(path) path.split('/')[-1] end def not_found render(status: '404') end def bad_request render(status: '400') end def ok(status: '200', headers: {}, body: nil) render(status: status, headers: headers, body: body) end def render(status:, headers: {}, body: nil) [status, headers, [body].compact] end end