Object
Raised when a Route is compiled twice
Raised an invalid request value is used
Raised when a url is not able to be generated for the given parameters
Raised when a Route is not able to be generated due to a missing parameter.
Raised when there are extra parameters passed in to url
Creates a new HttpRouter. Can be called with either HttpRouter.new(proc{|env| ... }, { .. options .. }) or with the first argument omitted. If there is a proc first, then it’s used as the default app in the case of a non-match. Supported options are
:default_app – Default application used if there is a non-match on call. Defaults to 404 generator.
:ignore_trailing_slash – Ignore a trailing / when attempting to match. Defaults to true.
:redirect_trailing_slash – On trailing /, redirect to the same path without the /. Defaults to false.
:known_methods – Array of http methods tested for 405s.
# File lib/http_router.rb, line 38 def initialize(*args, &blk) default_app, options = args.first.is_a?(Hash) ? [nil, args.first] : [args.first, args[1]] @options = options @default_app = default_app || options && options[:default_app] || proc{|env| ::Rack::Response.new("Not Found", 404, {'X-Cascade' => 'pass'}).finish } @ignore_trailing_slash = options && options.key?(:ignore_trailing_slash) ? options[:ignore_trailing_slash] : true @redirect_trailing_slash = options && options.key?(:redirect_trailing_slash) ? options[:redirect_trailing_slash] : false @known_methods = Set.new(options && options[:known_methods] || []) reset! instance_eval(&blk) if blk end
Adds a path to be recognized.
To assign a part of the path to a specific variable, use :variable_name within the route. For example, add('/path/:id') would match /path/test, with the variable :id having the value "test".
You can receive mulitple parts into a single variable by using the glob syntax. For example, add('/path/*id') would match /path/123/456/789, with the variable :id having the value ["123", "456", "789"].
As well, paths can end with two optional parts, * and /?. If it ends with a *, it will match partially, returning the part of the path unmatched in the PATH_INFO value of the env. The part matched to will be returned in the SCRIPT_NAME. If it ends with /?, then a trailing / on the path will be optionally matched for that specific route. As trailing /‘s are ignored by default, you probably don’t actually want to use this option that frequently.
Routes can also contain optional parts. There are surrounded with ( )‘s. If you need to match on a bracket in the route itself, you can escape the parentheses with a backslash.
As well, options can be passed in that modify the route in further ways. See HttpRouter::Route#with_options for details. Typically, you want to add further options to the route by calling additional methods on it. See HttpRouter::Route for further details.
Returns the route object.
# File lib/http_router.rb, line 64 def add(*args, &app) opts = args.last.is_a?(Hash) ? args.pop : {} path = args.first route = add_route((Regexp === path ? RegexRoute : Route).new(self, path, opts)) route.to(app) if app route end
# File lib/http_router.rb, line 72 def add_route(route) @routes << route route end
Rack compatible call. If matching route is found, and dest value responds to call, processing will pass to the matched route. Otherwise, the default application will be called. The router will be available in the env under the key router. And parameters matched will be available under the key router.params.
# File lib/http_router.rb, line 116 def call(env, perform_call = true) rack_request = ::Rack::Request.new(env) request = Request.new(rack_request.path_info, rack_request, perform_call) response = catch(:success) { @root[request] } if perform_call response or no_response(env) else request.matches.empty? ? nil : request.matches end end
Creates a deep-copy of the router.
# File lib/http_router.rb, line 182 def clone(klass = self.class) cloned_router = klass.new(@options) @routes.each do |route| new_route = route.clone(cloned_router) cloned_router.add_route(new_route) new_route.name(route.named) if route.named begin new_route.to route.dest.clone rescue new_route.to route.dest end end cloned_router end
Assigns the default application.
# File lib/http_router.rb, line 134 def default(app) @default_app = app end
Adds a path that only responds to the request method DELETE.
Returns the route object.
# File lib/http_router.rb, line 95 def delete(path, opts = {}, &app); add_with_request_method(path, :delete, opts, &app); end
Adds a path that only responds to the request method GET.
Returns the route object.
# File lib/http_router.rb, line 80 def get(path, opts = {}, &app); add_with_request_method(path, :get, opts, &app); end
Adds a path that only responds to the request method HEAD.
Returns the route object.
# File lib/http_router.rb, line 90 def head(path, opts = {}, &app); add_with_request_method(path, :head, opts, &app); end
Ignore trailing slash feature enabled? See initialize for details.
# File lib/http_router.rb, line 172 def ignore_trailing_slash? @ignore_trailing_slash end
# File lib/http_router.rb, line 224 def inspect head = to_s "#{to_s}\n#{'=' * head.size}\n#{@root.inspect}" end
# File lib/http_router.rb, line 207 def no_response(env) supported_methods = @known_methods.select do |m| next if m == env['REQUEST_METHOD'] test_env = ::Rack::Request.new(env.clone) test_env.env['REQUEST_METHOD'] = m test_env.env['_HTTP_ROUTER_405_TESTING_ACCEPTANCE'] = true test_request = Request.new(test_env.path_info, test_env, 405) @root[test_request] !test_request.matches.empty? end supported_methods.empty? ? @default_app.call(env) : [405, {'Allow' => supported_methods.sort.join(", ")}, []] end
Adds a path that only responds to the request method OPTIONS.
Returns the route object.
# File lib/http_router.rb, line 105 def options(path, opts = {}, &app); add_with_request_method(path, :options, opts, &app); end
This method defines what sort of responses are considered “passes”, and thus, route processing will continue. Override it to implement custom passing.
# File lib/http_router.rb, line 167 def pass_on_response(response) response[1]['X-Cascade'] == 'pass' end
Adds a path that only responds to the request method POST.
Returns the route object.
# File lib/http_router.rb, line 85 def post(path, opts = {}, &app); add_with_request_method(path, :post, opts, &app); end
This method is invoked when a Path object gets called with an env. Override it to implement custom path processing.
# File lib/http_router.rb, line 161 def process_destination_path(path, env) path.route.dest.call(env) end
Adds a path that only responds to the request method PUT.
Returns the route object.
# File lib/http_router.rb, line 100 def put(path, opts = {}, &app); add_with_request_method(path, :put, opts, &app); end
Performs recoginition without actually calling the application and returns an array of all matching routes or nil if no match was found.
# File lib/http_router.rb, line 109 def recognize(env) call(env, false) end
Redirect trailing slash feature enabled? See initialize for details.
# File lib/http_router.rb, line 177 def redirect_trailing_slash? @redirect_trailing_slash end
Resets the router to a clean state.
# File lib/http_router.rb, line 128 def reset! @routes, @named_routes, @root = [], Hash.new{|h,k| h[k] = []}, Node::Root.new(self) @default_app = Proc.new{ |env| ::Rack::Response.new("Your request couldn't be found", 404).finish } end
# File lib/http_router.rb, line 197 def rewrite_partial_path_info(env, request) env['PATH_INFO'] = "/#{request.path.join('/')}" env['SCRIPT_NAME'] += request.rack_request.path_info[0, request.rack_request.path_info.size - env['PATH_INFO'].size] end
# File lib/http_router.rb, line 202 def rewrite_path_info(env, request) env['SCRIPT_NAME'] += request.rack_request.path_info env['PATH_INFO'] = '' end
# File lib/http_router.rb, line 220 def to_s "#<HttpRouter:0x#{object_id.to_s(16)} number of routes (#{routes.size}) ignore_trailing_slash? (#{ignore_trailing_slash?}) redirect_trailing_slash? (#{redirect_trailing_slash?}) known_methods (#{known_methods.to_a.join(', ')})>" end
Generate a URL for a specified route. This will accept a list of variable values plus any other variable names named as a hash. This first value must be either the Route object or the name of the route.
Example:
router = HttpRouter.new router.add('/:foo.:format').name(:test).to{|env| [200, {}, []]} router.url(:test, 123, 'html') # ==> "/123.html" router.url(:test, 123, :format => 'html') # ==> "/123.html" router.url(:test, :foo => 123, :format => 'html') # ==> "/123.html" router.url(:test, :foo => 123, :format => 'html', :fun => 'inthesun') # ==> "/123.html?fun=inthesun"
# File lib/http_router.rb, line 152 def url(route, *args) case route when Symbol then @named_routes.key?(route) && @named_routes[route].each{|r| url = r.url(*args); return url if url} when Route then return route.url(*args) end raise(InvalidRouteException) end
Generated with the Darkfish Rdoc Generator 2.