class Shaf::Router
Attributes
controllers[R]
Public Class Methods
default_controller()
click to toggle source
This controller will be used when no other can handle the request (E.g. returning 404 Not Found)
# File lib/shaf/router.rb, line 38 def default_controller @default_controller ||= nil end
mount(controller, default: false)
click to toggle source
# File lib/shaf/router.rb, line 25 def mount(controller, default: false) @default_controller = controller if default @controllers ||= [] @controllers << controller end
new(app)
click to toggle source
# File lib/shaf/router.rb, line 60 def initialize(app) @app = app end
routes()
click to toggle source
# File lib/shaf/router.rb, line 31 def routes init_routes unless defined? @routes @routes end
Private Class Methods
init_routes()
click to toggle source
# File lib/shaf/router.rb, line 46 def init_routes @routes = Hash.new do |hash, key| hash[key] = Hash.new { |h, k| h[k] = Set.new } end controllers.each { |controller| init_routes_for(controller) } end
init_routes_for(controller)
click to toggle source
# File lib/shaf/router.rb, line 53 def init_routes_for(controller) controller.routes.each do |method, controller_routes| routes[method][controller] += controller_routes.map(&:first) end end
Public Instance Methods
call(env)
click to toggle source
# File lib/shaf/router.rb, line 64 def call(env) http_method, path = http_details(env) result = nil controllers_for(http_method, path) do |controller| result = controller.call(env) break unless cascade? result end result end
Private Instance Methods
add_cache(controller, http_method, path)
click to toggle source
# File lib/shaf/router.rb, line 149 def add_cache(controller, http_method, path) return unless controller key = cache_key(http_method, path) cache[key] << controller end
cache()
click to toggle source
# File lib/shaf/router.rb, line 145 def cache @cache ||= Hash.new { |hash, key| hash[key] = Set.new } end
cache_key(http_method, path)
click to toggle source
# File lib/shaf/router.rb, line 161 def cache_key(http_method, path) path[1..-1].split('/').inject("#{http_method}_") do |key, segment| segment = ':id' if segment =~ /\A\d+\z/ "#{key}/#{segment}" end end
cascade?(result)
click to toggle source
# File lib/shaf/router.rb, line 141 def cascade?(result) result.dig(1, 'X-Cascade') == 'pass' end
controllers_for(http_method, path) { |ctrlr| ... }
click to toggle source
# File lib/shaf/router.rb, line 83 def controllers_for(http_method, path) find_cached(http_method, path).each { |ctrlr| yield ctrlr } if controller = find(http_method, path) yield controller end find_all(http_method, path).each do |ctrlr| yield ctrlr unless ctrlr == controller end supported_methods = supported_methods_for(path) if !supported_methods.empty? && !supported_methods.include?(http_method) yield MethodNotAllowedResponder.new(supported_methods) end yield default_controller end
default_controller()
click to toggle source
# File lib/shaf/router.rb, line 102 def default_controller self.class.default_controller || @app || raise('No default controller') end
find(http_method, path)
click to toggle source
# File lib/shaf/router.rb, line 110 def find(http_method, path) routes[http_method].each do |controller, patterns| next unless patterns.any? { |pattern| pattern.match(path) } add_cache(controller, http_method, path) return controller end nil end
find_all(http_method, path)
click to toggle source
# File lib/shaf/router.rb, line 120 def find_all(http_method, path) Set.new.tap do |controllers| routes[http_method].each do |ctrlr, patterns| next unless patterns.any? { |pattern| pattern.match(path) } add_cache(ctrlr, http_method, path) controllers << ctrlr end end end
find_cached(http_method, path)
click to toggle source
# File lib/shaf/router.rb, line 156 def find_cached(http_method, path) key = cache_key(http_method, path) cache[key] end
http_details(env)
click to toggle source
# File lib/shaf/router.rb, line 79 def http_details(env) [env['REQUEST_METHOD'], env['PATH_INFO']] end
routes()
click to toggle source
# File lib/shaf/router.rb, line 106 def routes self.class.routes end
supported_methods_for(path)
click to toggle source
# File lib/shaf/router.rb, line 130 def supported_methods_for(path) methods = Set.new routes.each do |http_method, controllers| controllers.each do |_, patterns| next unless patterns.any? { |pattern| pattern.match(path) } methods << http_method end end methods.to_a end