class Nephos::Router

The {Router} provides an interface between the {Controller} and the client queries.

Constants

ROUTES

Public Class Methods

add(what, verb) click to toggle source
# File lib/nephos-server/router/load.rb, line 5
def self.add(what, verb)
  Nephos::Router::ROUTES << what.merge(verb: verb)
  display = "[#{verb}] #{what[:url]} \t ---> \t #{what[:controller]}##{what[:method]}"
  puts display unless what[:silent]
  return display
end
add_params!(what) click to toggle source

@param what [Hash]

# File lib/nephos-server/router/load.rb, line 13
def self.add_params!(what)
  params = what[:url].split('/').map do |p|
    p.match(/:\w+/) ? {p: "[^\/]+", name: p} : {p: p, name: nil}
  end
  url = params.map{|e| e[:p]}.join("/+")
  url = "/" if url.empty?
  what[:match] = what[:postfix] != false ? /^(?<url>#{url})(?<extension>\.\w+)?\/*$/ : /^(?<url>#{url})\/*$/
  # remove : in :param, and / in /param
  what[:params] = params.map{|e| e[:name] && e[:name][1..-1]}[1..-1] || []
end
check!(what) click to toggle source
# File lib/nephos-server/router/load.rb, line 78
def self.check!(what)
  check_keys! what
  instance = check_controller! what
  check_method! what, instance
end
check_controller!(what) click to toggle source

@param what [Hash]

Check if:

  • the what parameter contains a :controller

  • this controller exists

  • if the controller is a child of the {Controller} class

  • if the controller is instanciable

# File lib/nephos-server/router/load.rb, line 51
def self.check_controller! what
  begin
    controller = Module.const_get(what[:controller])
  rescue => err
    raise InvalidRouteController, "Controller \"#{what[:controller]}\" doesn't exists"
  end
  if not controller.ancestors.include? Nephos::Controller
    raise InvalidRouteController, "Class \"#{what[:controller]}\" is not a Nephos::Controller"
  end
  begin
    instance = controller.new(Rack::Request.new({}), {params: []})
  rescue => err
    raise InvalidRouteController, "Cannot initialize controller"
  end
  return instance
end
check_keys!(what) click to toggle source

@param what [Hash]

Check if the what parameter contains the needed keys

  • :url

  • :controller

  • :method

# File lib/nephos-server/router/load.rb, line 30
def self.check_keys! what
  raise InvalidRouteUrl, "Missing URL" unless what.keys.include? :url
  if what.keys.include? :to
    match = what[:to].match(/(?<controller>\w+)\#(?<method>\w+)/)
    raise InvalidRouteTo, "Invalid Controller#Method" unless match
    what[:controller] = match["controller"]
    what[:method] = match["method"]
    what.delete :to
  else
    raise InvalidRouteController, "Missing Controller" unless what.keys.include? :controller
    raise InvalidRouteMethod, "Missing Method" unless what.keys.include? :method
  end
end
check_method!(what, instance) click to toggle source

@param what [Hash] @param instance [Controller]

Check if the param instance has a method named what

# File lib/nephos-server/router/load.rb, line 72
def self.check_method! what, instance
  if not instance.respond_to? what[:method]
    raise InvalidRouteMethod, "No method named \"#{what[:method]}\""
  end
end
new(opt={}) click to toggle source

@param opt [Hash] it contains optional parameters, via the keys (Symbol only)

- :silent : if true, then there will be no puts on the stdin when a request is routed.
  Else, or by default, there will be information printed on stdin
# File lib/nephos-server/router/main.rb, line 17
def initialize(opt={})
  @responder = Responder.new
  @silent = !!opt[:silent]
end

Public Instance Methods

error_404(req) click to toggle source
# File lib/nephos-server/router/main.rb, line 55
def error_404(req)
  STDERR.puts "Error 404" if $verbose == "output"
  out = error_custom(req, 404, "404 not found \"#{req.path}\"")
  out.body[0].gsub!("INJECT_REQ_PATH", req.path)
  return out
end
error_custom(req, code, default=nil) click to toggle source
# File lib/nephos-server/router/main.rb, line 46
def error_custom(req, code, default=nil)
  STDERR.puts "Error #{code}" if $verbose == "output"
  if File.exist? "app/#{code}.html"
    @responder.render(status: code, html: File.read("app/#{code}.html"))
  else
    render_error(req, code, default || "Error: #{req.status}")
  end
end
execute(req) click to toggle source

Interface which handle the client query (stored in env), create a new {Controller} instance, and call the render on it

# File lib/nephos-server/router/main.rb, line 71
def execute(req)
  #env = req.env
  puts "#{req.env["REMOTE_ADDR"]} [#{req.request_method}] \t ---> \t #{req.path}" unless @silent
  call = find_route(req)
  # require 'pry'
  # binding.pry
  return error_404(req) if call.nil?
  begin
    return render_controller(req, call)
  rescue => err
    STDERR.puts "Error: #{err.message}" unless @silent
    STDERR.puts err.backtrace unless @silent
    return error_custom(req, 500, "#{err.message}\n---Backtrace---\n#{err.backtrace.join("\n")}\n")
  end
end
find_route(req) click to toggle source

@param path [Array]

Find the right route to use from the url

# File lib/nephos-server/router/main.rb, line 65
def find_route req
  return ROUTES.find{|e| e[:match] =~ req.path and e[:verb] == req.request_method}
end
render_controller(req, call) click to toggle source

render the return of a call to Controller.new.method. Controller and method are stored on call via the keys :controller and :method

# File lib/nephos-server/router/main.rb, line 24
def render_controller req, call
  out = @responder.render_from_controller(req, call)
  STDERR.puts "<--- #{out.body}" if $verbose == "output"
  return out
end
render_error(req, code, err=nil) click to toggle source
# File lib/nephos-server/router/main.rb, line 30
def render_error(req, code, err=nil)
  STDERR.puts "Error #{code}" if $verbose == "output"
  if Nephos.env == "production"
    return @responder.render(status: code)
  elsif err
    msg = err
    if msg.is_a? Exception
      msg = err.message + "\n"
      msg += "--- Backtrace ---\n" + err.backtrace.join("\n") + "\n"
    end
    return @responder.render(status: code, content: "Error: #{code}\n#{msg}")
  else
    return @responder.render(status: code)
  end
end