Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created June 11, 2016 22:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/158718fdb3ecca00739f1d95b8e4aa28 to your computer and use it in GitHub Desktop.
Save JoshCheek/158718fdb3ecca00739f1d95b8e4aa28 to your computer and use it in GitHub Desktop.
Mini Sinatra
# Started to write a mini Sinatra for a thing
# then just realized I should use Sinatra, so I stopped doing it
# but figured it might be interesting enough to keep around
class WebFramework
class Request
attr_accessor :env, :status_code, :headers, :body
def initialize(env)
self.env = env
end
def method
env['REQUEST_METHOD']
end
def path
env['PATH_INFO']
end
def params
@params ||= begin
if env['CONTENT_TYPE'] != "application/x-www-form-urlencoded"
{} # ignoring query params for now
else
body = env['rack.input'].read
Rack::Utils.parse_query(body)
end
end
end
end
end
class WebFramework
class Response
attr_reader :headers, :body
attr_accessor :status_code
def initialize
@headers = {'Content-Type' => 'text/html'}
self.status_code = 200
self.body = ''
end
def body=(body)
headers['Content-Length'] = body.length
@body = body
end
def to_rack
[status_code, headers, [body]]
end
end
end
class WebFramework
class HandlerContext
def self.call(request, response=Response.new, &block)
context = new(request, response)
response.body = context.instance_eval(&block) if block
response.to_rack
end
attr_accessor :request, :response
def initialize(request, response)
self.request = request
self.response = response
end
def params
request.params
end
end
end
class WebFramework
attr_accessor :handlers, :handle_request_class, :handler_missing
def initialize(&definition)
self.handlers = {}
self.handle_request_class = Class.new(HandlerContext)
self.handler_missing = Proc.new do
response.status_code = 404
'<h1>Not Found</h1>'
end
instance_eval &definition if definition
end
def call(env)
request = Request.new env
handler = handlers.fetch [request.method, request.path], handler_missing
handle_request_class.call request, &handler
end
def get(path, &handler)
declare_handler 'GET', path, handler
end
def post(path, &handler)
declare_handler 'POST', path, handler
end
def declare_handler(method, path, handler)
handlers[[method, path]] = handler
end
def helpers(&block)
handle_request_class.class_eval(&block)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment