lib/usher/interface/rack_interface.rb in usher-0.5.4 vs lib/usher/interface/rack_interface.rb in usher-0.5.5
- old
+ new
@@ -1,80 +1,99 @@
require 'rack'
class Usher
module Interface
class RackInterface
-
+
attr_reader :router
-
+ attr_accessor :app
+
+ DEFAULT_APPLICATION = lambda do |env|
+ Rack::Response.new("No route found", 404).finish
+ end
+
class Builder < Rack::Builder
-
+
def initialize(&block)
@usher = Usher::Interface::RackInterface.new
super
end
-
+
def map(path, options = nil, &block)
@usher.add(path, options).to(&block)
@ins << @usher unless @ins.last == @usher
end
-
+
end
-
- def initialize(&blk)
+
+ def initialize(app = nil, &blk)
+ @app = app || DEFAULT_APPLICATION
@router = Usher.new(:request_methods => [:request_method, :host, :port, :scheme], :generator => Usher::Util::Generators::URL.new)
instance_eval(&blk) if blk
end
-
+
def dup
new_one = super
original = self
new_one.instance_eval do
@router = router.dup
end
new_one
end
-
+
def add(path, options = nil)
@router.add_route(path, options)
- end
-
+ end
+
def parent_route=(route)
@router.parent_route = route
end
-
+
def parent_route
@router.parent_route
end
def reset!
@router.reset!
end
def call(env)
- env['usher.params'] ||= {}
response = @router.recognize(request = Rack::Request.new(env), request.path_info)
- if response.nil?
- body = "No route found"
- headers = {"Content-Type" => "text/plain", "Content-Length" => body.length.to_s}
- [404, headers, [body]]
- else
- params = response.path.route.default_values || {}
- response.params.each{ |hk| params[hk.first] = hk.last}
-
- # consume the path_info to the script_name response.remaining_path
- env["SCRIPT_NAME"] << response.matched_path || ""
- env["PATH_INFO"] = response.remaining_path || ""
-
- env['usher.params'].merge!(params)
-
- response.path.route.destination.call(env)
- end
+ after_match(env, response) if response
+ determine_respondant(response).call(env)
end
def generate(route, params = nil, options = nil)
@usher.generator.generate(route, params, options)
end
+ # Allows a hook to be placed for sub classes to make use of between matching
+ # and calling the application
+ #
+ # @api plugin
+ def after_match(env, response)
+ env['usher.params'] ||= {}
+ params = response.path.route.default_values || {}
+ response.params.each{|hk| params[hk.first] = hk.last}
+ env['usher.params'].merge!(params)
+
+ # consume the path_info to the script_name response.remaining_path
+ env["SCRIPT_NAME"] << response.matched_path || ""
+ env["PATH_INFO"] = response.remaining_path || ""
+ end
+
+ # Determines which application to respond with.
+ #
+ # Within the request when determine respondant is called
+ # If there is a matching route to an application, that
+ # application is called, Otherwise the middleware application is called.
+ #
+ # @api private
+ def determine_respondant(response)
+ return app if response.nil?
+ respondant = response.path.route.destination
+ respondant = app unless respondant.respond_to?(:call)
+ respondant
+ end
end
end
end