Class: Strelka::Router::Default

Inherits:
Strelka::Router show all
Extended by:
Loggability
Includes:
Constants, Strelka::ResponseHelpers
Defined in:
lib/strelka/router/default.rb

Overview

Simple (dumb?) request router for Strelka::App-based applications.

Direct Known Subclasses

Exclusive

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Strelka::ResponseHelpers

finish_with

Methods included from AbstractClass

extended, included, #inherited, #pure_virtual

Constructor Details

#initialize(routes = [], options = {}) ⇒ Default

Create a new router that will route requests according to the specified routes. Each route is a tuple of the form:

[
<http_verb>,    # The HTTP verb as a Symbol (e.g., :GET, :POST, etc.)
<path_array>,   # An Array of the parts of the path, as Strings and Regexps.
<route>,        # A hash of routing data built by the Routing plugin
]


25
26
27
28
29
30
31
# File 'lib/strelka/router/default.rb', line 25

def initialize( routes=[], options={} )
  @routes = Hash.new {|hash, path| hash[path] = {} }

  routes.each {|r| self.add_route( *r ) }

  super
end

Instance Attribute Details

#routesObject (readonly)

A Hash, keyed by Regexps, that contains the routing logic



39
40
41
# File 'lib/strelka/router/default.rb', line 39

def routes
  @routes
end

Instance Method Details

#add_route(verb, path, route) ⇒ Object

Add a route for the specified verb, path, and options that will return action when a request matches them.



44
45
46
47
48
49
# File 'lib/strelka/router/default.rb', line 44

def add_route( verb, path, route )
  re = Regexp.compile( '^' + path.join('/') )

  # Add the route keyed by path regex and HTTP verb
  self.routes[ re ][ verb ] = route
end

#not_allowed_response(allowed_verbs) ⇒ Object

Build an HTTP Allowed header out of the allowed_verbs and throw a 405 response.



89
90
91
92
93
# File 'lib/strelka/router/default.rb', line 89

def not_allowed_response( allowed_verbs )
  allowed_verbs << :HEAD if allowed_verbs.include?( :GET )
  allowed_hdr = allowed_verbs.map {|verb| verb.to_s.upcase }.join( ', ' )
  finish_with( HTTP::METHOD_NOT_ALLOWED, 'Method not allowed.', allow: allowed_hdr )
end

#route_request(request) ⇒ Object

Determine the most-specific route for the specified request and return the UnboundMethod object of the App that should handle it.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/strelka/router/default.rb', line 54

def route_request( request )
  route = nil
  path  = request.app_path || ''
  verb  = request.verb

  path.slice!( 0, 1 ) if path.start_with?( '/' ) # Strip the leading '/'
  self.log.debug "Looking for routes for: %p %p" % [ verb, path ]
  match = self.find_longest_match( self.routes.keys, path ) or return nil
  self.log.debug "  longest match result: %p" % [ match ]
  routekey = match.regexp

  # Pick the appropriate route based on the HTTP verb of the request. HEAD requests
  # use the GET route. If there isn't a defined route for the request's verb
  # send a 405 (Method Not Allowed) response
  verb       = :GET if verb == :HEAD
  verbroutes = self.routes[ routekey ]
  route      = verbroutes[ verb ] or not_allowed_response( verbroutes.keys )

  # Inject the parameters that are part of the route path (/foo/:id) into
  # the parameters hash. They'll be the named match-groups in the matching
  # Regex.
  route_params = match.names.each_with_object({}) do |name, hash|
    hash[ name ] = match[ name ]
  end

  # Add routing information to the request, and merge parameters if there are any
  request.params.merge!( route_params ) unless route_params.empty?

  # Return the routing data that should be used
  return route
end