Created
June 11, 2016 22:10
-
-
Save JoshCheek/158718fdb3ecca00739f1d95b8e4aa28 to your computer and use it in GitHub Desktop.
Mini Sinatra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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