Class: HttpRouter
- Inherits:
-
Object
- Object
- HttpRouter
- Defined in:
- lib/http_router/version.rb,
lib/http_router.rb,
lib/http_router/glob.rb,
lib/http_router/node.rb,
lib/http_router/path.rb,
lib/http_router/rack.rb,
lib/http_router/root.rb,
lib/http_router/parts.rb,
lib/http_router/route.rb,
lib/http_router/static.rb,
lib/http_router/variable.rb,
lib/http_router/interface/sinatra.rb,
lib/http_router/optional_compiler.rb
Overview
:nodoc
Defined Under Namespace
Modules: Interface, Rack Classes: ArbitraryNode, Glob, Node, OptionalCompiler, Parts, Path, RequestNode, Root, Route, Static, Variable
Constant Summary collapse
- UngeneratableRouteException =
Raised when a Route is not able to be generated.
Class.new(RuntimeError)
- MissingParameterException =
Raised when a Route is not able to be generated due to a missing parameter.
Class.new(RuntimeError)
- InvalidRouteException =
Raised when a Route is generated that isn’t valid.
Class.new(RuntimeError)
- TooManyParametersException =
Raised when a Route is not able to be generated due to too many parameters being passed in.
Class.new(RuntimeError)
- AlreadyCompiledException =
Raised when an already inserted Route has more conditions added.
Class.new(RuntimeError)
- AmbiguousRouteException =
Raised when an ambiguous Route is added. For example, this will be raised if you attempt to add “/foo(/:bar)(/:baz)”.
Class.new(RuntimeError)
- UnsupportedRequestConditionError =
Raised when a request condition is added that is not recognized.
Class.new(RuntimeError)
- AmbiguousVariableException =
Raised when there is a potential conflict of variable names within your Route.
Class.new(RuntimeError)
- VERSION =
'0.5.1'
Instance Attribute Summary collapse
-
#named_routes ⇒ Object
readonly
Returns the value of attribute named_routes.
-
#request_methods_specified ⇒ Object
readonly
Returns the value of attribute request_methods_specified.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#routes ⇒ Object
readonly
Returns the value of attribute routes.
-
#url_mount ⇒ Object
Returns the value of attribute url_mount.
-
#variable_names ⇒ Object
readonly
Returns the value of attribute variable_names.
Class Method Summary collapse
Instance Method Summary collapse
-
#add(path, options = nil) ⇒ Object
Adds a path to be recognized.
-
#add_route(route) ⇒ Object
Adds a route to be recognized.
- #append_querystring(uri, params) ⇒ Object
- #arbitrary_node(*args) ⇒ Object
-
#call(env) ⇒ Object
Rack compatible #call.
-
#clone(klass = self.class) ⇒ Object
Creates a deep-copy of the router.
-
#default(app) ⇒ Object
Assigns the default application.
-
#delete(path, options = nil) ⇒ Object
Adds a path that only responds to the request method
DELETE
. -
#get(path, options = nil) ⇒ Object
Adds a path that only responds to the request method
GET
. -
#glob(*args) ⇒ Object
Returns a new glob.
-
#ignore_trailing_slash? ⇒ Boolean
Ignore trailing slash feature enabled? See #initialize for details.
-
#initialize(*args, &block) ⇒ HttpRouter
constructor
Creates a new HttpRouter.
-
#node(*args) ⇒ Object
Returns a new node.
-
#post(path, options = nil) ⇒ Object
Adds a path that only responds to the request method
POST
. -
#put(path, options = nil) ⇒ Object
Adds a path that only responds to the request method
PUT
. - #recognize(env) ⇒ Object
-
#redirect_trailing_slash? ⇒ Boolean
Redirect trailing slash feature enabled? See #initialize for details.
-
#request_node(*args) ⇒ Object
Returns a new request node.
-
#reset! ⇒ Object
Resets the router to a clean state.
-
#route(*args) ⇒ Object
Returns a new route.
- #split(path) ⇒ Object
-
#url(route, *args) ⇒ Object
Generate a URL for a specified route.
- #url_with_params(route, *args) ⇒ Object
-
#variable(*args) ⇒ Object
Returns a new variable.
Constructor Details
#initialize(*args, &block) ⇒ HttpRouter
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
.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/http_router.rb', line 44 def initialize(*args, &block) default_app, = args.first.is_a?(Hash) ? [nil, args.first] : [args.first, args[1]] @options = @default_app = default_app || && [:default_app] || proc{|env| ::Rack::Response.new("Not Found", 404).finish } @ignore_trailing_slash = && .key?(:ignore_trailing_slash) ? [:ignore_trailing_slash] : true @redirect_trailing_slash = && .key?(:redirect_trailing_slash) ? [:redirect_trailing_slash] : false @init_block = block @handle_unavailable_route = Proc.new{ raise UngeneratableRouteException } reset! instance_eval(&block) if block end |
Instance Attribute Details
#named_routes ⇒ Object (readonly)
Returns the value of attribute named_routes.
34 35 36 |
# File 'lib/http_router.rb', line 34 def named_routes @named_routes end |
#request_methods_specified ⇒ Object (readonly)
Returns the value of attribute request_methods_specified.
34 35 36 |
# File 'lib/http_router.rb', line 34 def request_methods_specified @request_methods_specified end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
34 35 36 |
# File 'lib/http_router.rb', line 34 def root @root end |
#routes ⇒ Object (readonly)
Returns the value of attribute routes.
34 35 36 |
# File 'lib/http_router.rb', line 34 def routes @routes end |
#url_mount ⇒ Object
Returns the value of attribute url_mount.
35 36 37 |
# File 'lib/http_router.rb', line 35 def url_mount @url_mount end |
#variable_names ⇒ Object (readonly)
Returns the value of attribute variable_names.
34 35 36 |
# File 'lib/http_router.rb', line 34 def variable_names @variable_names end |
Class Method Details
.uri_escape!(s) ⇒ Object
235 236 237 |
# File 'lib/http_router.rb', line 235 def self.uri_escape!(s) s.to_s.gsub!(/([^:\/?\[\]\-_~\.!\$&'\(\)\*\+,;=@a-zA-Z0-9]+)/n) { "%#{$1.unpack('H2'*$1.size).join('%').upcase}" } end |
.uri_unescape!(s) ⇒ Object
239 240 241 |
# File 'lib/http_router.rb', line 239 def self.uri_unescape!(s) s.to_s.gsub!(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') } end |
Instance Method Details
#add(path, options = nil) ⇒ Object
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.
The second argument, options, is an optional hash that can 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.
95 96 97 |
# File 'lib/http_router.rb', line 95 def add(path, = nil) add_route route(path.dup).() end |
#add_route(route) ⇒ Object
Adds a route to be recognized. This must be a HttpRouter::Route object. Returns the route just added.
100 101 102 103 |
# File 'lib/http_router.rb', line 100 def add_route(route) @routes << route route end |
#append_querystring(uri, params) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/http_router.rb', line 243 def append_querystring(uri, params) if params && !params.empty? uri_size = uri.size params.each do |k,v| case v when Array v.each { |v_part| uri << '&' << ::Rack::Utils.escape(k.to_s) << '%5B%5D=' << ::Rack::Utils.escape(v_part.to_s) } else uri << '&' << ::Rack::Utils.escape(k.to_s) << '=' << ::Rack::Utils.escape(v.to_s) end end uri[uri_size] = ?? end uri end |
#arbitrary_node(*args) ⇒ Object
194 195 196 |
# File 'lib/http_router.rb', line 194 def arbitrary_node(*args) ArbitraryNode.new(self, *args) end |
#call(env) ⇒ Object
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
. The HttpRouter::Response object will be available under the key router.response
if a response is available.
169 170 171 172 173 174 175 176 177 178 |
# File 'lib/http_router.rb', line 169 def call(env) request = ::Rack::Request.new(env) if redirect_trailing_slash? && (request.head? || request.get?) && request.path_info[-1] == ?/ response = ::Rack::Response.new response.redirect(request.path_info[0, request.path_info.size - 1], 302) response.finish else @root.call(request) || @default_app.call(request.env) end end |
#clone(klass = self.class) ⇒ Object
Creates a deep-copy of the router.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/http_router.rb', line 214 def clone(klass = self.class) cloned_router = klass.new(@default_app, @options) @routes.each do |route| new_route = route.clone(cloned_router) cloned_router.add_route(new_route).compile new_route.name(route.named) if route.named if route.dest begin new_route.to route.dest.clone rescue new_route.to route.dest end end end cloned_router end |
#default(app) ⇒ Object
Assigns the default application.
76 77 78 |
# File 'lib/http_router.rb', line 76 def default(app) @default_app = app end |
#delete(path, options = nil) ⇒ Object
Adds a path that only responds to the request method DELETE
.
Returns the route object.
129 130 131 |
# File 'lib/http_router.rb', line 129 def delete(path, = nil) add(path, ).delete end |
#get(path, options = nil) ⇒ Object
Adds a path that only responds to the request method GET
.
Returns the route object.
108 109 110 |
# File 'lib/http_router.rb', line 108 def get(path, = nil) add(path, ).get end |
#glob(*args) ⇒ Object
Returns a new glob
204 205 206 |
# File 'lib/http_router.rb', line 204 def glob(*args) Glob.new(self, *args) end |
#ignore_trailing_slash? ⇒ Boolean
Ignore trailing slash feature enabled? See #initialize for details.
57 58 59 |
# File 'lib/http_router.rb', line 57 def ignore_trailing_slash? @ignore_trailing_slash end |
#node(*args) ⇒ Object
Returns a new node
185 186 187 |
# File 'lib/http_router.rb', line 185 def node(*args) Node.new(self, *args) end |
#post(path, options = nil) ⇒ Object
Adds a path that only responds to the request method POST
.
Returns the route object.
115 116 117 |
# File 'lib/http_router.rb', line 115 def post(path, = nil) add(path, ).post end |
#put(path, options = nil) ⇒ Object
Adds a path that only responds to the request method PUT
.
Returns the route object.
122 123 124 |
# File 'lib/http_router.rb', line 122 def put(path, = nil) add(path, ).put end |
#recognize(env) ⇒ Object
180 181 182 |
# File 'lib/http_router.rb', line 180 def recognize(env) @root.recognize(env) end |
#redirect_trailing_slash? ⇒ Boolean
Redirect trailing slash feature enabled? See #initialize for details.
62 63 64 |
# File 'lib/http_router.rb', line 62 def redirect_trailing_slash? @redirect_trailing_slash end |
#request_node(*args) ⇒ Object
Returns a new request node
190 191 192 |
# File 'lib/http_router.rb', line 190 def request_node(*args) RequestNode.new(self, *args) end |
#reset! ⇒ Object
Resets the router to a clean state.
67 68 69 70 71 72 73 |
# File 'lib/http_router.rb', line 67 def reset! @root = Root.new(self) @request_methods_specified = Set.new @routes = [] @named_routes = {} @variable_names = Set.new end |
#route(*args) ⇒ Object
Returns a new route
209 210 211 |
# File 'lib/http_router.rb', line 209 def route(*args) Route.new(self, *args) end |
#split(path) ⇒ Object
231 232 233 |
# File 'lib/http_router.rb', line 231 def split(path) Parts.new(path) end |
#url(route, *args) ⇒ Object
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).compile
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"
147 148 149 150 151 152 153 154 |
# File 'lib/http_router.rb', line 147 def url(route, *args) case route when Symbol then url(@named_routes[route], *args) when Route then route.url(*args) when nil then @handle_unavailable_route.call(:url, *args) else end end |
#url_with_params(route, *args) ⇒ Object
156 157 158 159 160 161 162 163 |
# File 'lib/http_router.rb', line 156 def url_with_params(route, *args) case route when Symbol then url_with_params(@named_routes[route], *args) when Route then route.url_with_params(*args) when nil then @handle_unavailable_route.call(:url_with_params, *args) else end end |