Skip to content

Instantly share code, notes, and snippets.

@yannick
Created October 23, 2017 12:48
Show Gist options
  • Select an option

  • Save yannick/1bedfe34ebcab386cbce4a247cf05e5d to your computer and use it in GitHub Desktop.

Select an option

Save yannick/1bedfe34ebcab386cbce4a247cf05e5d to your computer and use it in GitHub Desktop.
## currently mostly a fruity fish soup for h2o
module Ayu
#Resource, currently non stackable
class Resource
HTTPMethods = %i(get post put delete head options trace connect).uniq
class << self
def http_methods
@http_methods ||= Array.new
end
end
HTTPMethods.each { |http_method|
define_singleton_method(http_method) { |&blk|
bmname = :"__#{http_method}"
define_method(bmname, &blk)
define_method(http_method) { |*args|
response = send(bmname, *args)
case response
when Array #, Rack::Response
resp
else
response = response.to_s
[200, {'Content-Type' => 'text/plain'}, [response]] #TODO: check if h2o adds Content-Length
end
}
}
define_method(http_method) { |*args| default_http_method(*args) }
}
# Every resource, on being instantiated, is given the Rack env.
def initialize(env, app = nil, params = nil)
@env, @app, @params = env, app, params
end
#bounce back to h2o
def default_http_method(*args)
[399,{},[]]
end
end
class App
Errors = {
400 => [400, {'Content-Type' => 'text/plain'}, ["400 Bad Request.\n"]],
404 => [404, {'Content-Type' => 'text/plain'}, ["404 Not Found\n"]],
501 => [501, {'Content-Type' => 'text/plain'},["501 Not Implemented.\n"]],
399 => [399,{}, []], #bounce to h2o
}
Routes = R3::Tree.new(100)
# Method name cache. Maps HTTP methods to object methods.
# not 100% sure if this is really faster compared to .downcase.to_sym
HttpMethods = Hash.new { |h,k| h[k] = k.downcase.to_sym }
# Prefill MNCache above with the likely culprits:
%w(GET PUT POST DELETE OPTIONS HEAD TRACE CONNECT PATCH).each{ |m| HttpMethods[m] }
def self.resource(path, res = nil, &blk)
Routes.add(path, R3::ANY, res )
end
def initialize
Routes.compile
end
# Rack handlerß
# TODO: define behaviour if method is not defined or no handler is found.
# either bounce back to h2o or return an item from Errors
def call env, req_path = nil
rm = HttpMethods[env['REQUEST_METHOD']]
return(Errors[501]) unless rm
params, handler = Routes.match env['PATH_INFO']
return Errors[399] unless handler
res = handler.new(env, self, params)
res.send(rm)
end
end #App
end #module
{"msg": "FAILOMATICS"}
listen:
port: 8080
num-threads: 1
hosts:
"*":
paths:
/:
mruby.handler-file: sample.rb
file.file: error.json
require 'ayu'
class MyApp < Ayu::App
class UserResource < Ayu::Resource
get do
{msg: "hello world from ayu!", params: @params, env: @env }.to_json
end
end
resource('/users/{user_id}', UserResource)
end
MyApp.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment