module Olelo::Routing

Attributes

env[R]
original_params[R]
params[R]
request[R]
response[R]

Public Class Methods

included(base) click to toggle source
# File lib/olelo/routing.rb, line 3
def self.included(base)
  base.extend(ClassMethods)
end

Public Instance Methods

call(env) click to toggle source

Process rack request

This method duplicates the object and calls {#call!} on it.

@api public @param [Hash] env Rack environment @return [Array] Rack return value @see rack.rubyforge.org/doc/SPEC.html

# File lib/olelo/routing.rb, line 17
def call(env)
  dup.call!(env)
end
call!(env) click to toggle source

Process rack request

@api public @param [Hash] env Rack environment @return [Array] Rack return value

# File lib/olelo/routing.rb, line 26
def call!(env)
  @env      = env
  @request  = Rack::Request.new(env)
  @response = Rack::Response.new
  @params = @original_params = @request.params.with_indifferent_access
  @original_params.freeze

  catch(:forward) do
    perform!
    status, header, body = response.finish
    return [status, header, request.head? ? [] : body]
  end

  @app ? @app.call(env) : error!(NotFound.new(@request.path_info))
end
forward() click to toggle source

Forward to next application on the rack stack

@return [void] @api public

# File lib/olelo/routing.rb, line 77
def forward
  throw :forward
end
halt(*response) click to toggle source

Halt routing with response

Possible responses:

* String or Object with #each
* Symbol
* [Symbol, String or Object with #each]

@param [Symbol, String, each] *response @return [void] @api public

# File lib/olelo/routing.rb, line 52
def halt(*response)
  throw :halt, response.length == 1 ? response.first : response
end
pass() click to toggle source

Pass to next matching route

@return [void] @api public

# File lib/olelo/routing.rb, line 69
def pass
  throw :pass
end
redirect(uri) click to toggle source

Redirect to uri

@param uri Target uri @return [void] @api public

# File lib/olelo/routing.rb, line 61
def redirect(uri)
  throw :redirect, uri
end

Private Instance Methods

error!(error) click to toggle source
# File lib/olelo/routing.rb, line 83
def error!(error)
  response.status = Rack::Utils.status_code(error.try(:status) || :internal_server_error)
  handle_error(error)
end
perform!() click to toggle source
# File lib/olelo/routing.rb, line 88
def perform!
  result = catch(:halt) do
    uri = catch(:redirect) do
      with_hooks(:routing) { route! }
    end
    response.redirect uri
    nil
  end

  case result
  when nil, false
  when String
    response.body = [result]
  when Fixnum, Symbol
    response.status = Rack::Utils.status_code(result)
  when Array
    if Symbol === result.first || Fixnum === result.first
      response.status = Rack::Utils.status_code(result.shift)
      response.body = result.pop
      response.headers.merge!(result.first) if result.first
    else
      response.body = result
    end
  else
    if result.respond_to?(:each)
      response.body = result
    else
      raise TypeError, "#{result.inspect} not supported"
    end
  end
end
route!() click to toggle source
# File lib/olelo/routing.rb, line 120
def route!
  path = unescape(request.path_info)
  method = request.request_method
  self.class.router[method].find(path) do |name, params, function|
    @params = @original_params.merge(params)
    catch(:pass) do
      with_hooks(:action, method.downcase.to_sym, name) do
        halt function.bind(self).call
      end
    end
  end if self.class.router[method]
  raise NotFound, path
rescue ::Exception => error
  halt error!(error)
end