class
Kemal::RouteHandler
- Kemal::RouteHandler
- Reference
- Object
Included Modules
- HTTP::Handler
Defined in:
kemal/route_handler.crConstant Summary
-
INSTANCE =
new
Constructors
Instance Method Summary
-
#add_route(method : String, path : String, &handler : HTTP::Server::Context -> _)
Adds a given route to routing tree.
-
#allowed_methods(path : String) : Array(String)
Returns every HTTP method registered for path, in
Allowheader order, or an empty array when nothing is routed there. - #cached_routes : Kemal::LRUCache(String, Radix::Result(Kemal::Route))
-
#cached_routes=(cache : LRUCache(String, Radix::Result(Route)))
Setter is synchronized for thread-safety when specs reset the cache.
- #call(context : HTTP::Server::Context)
-
#lookup_route(verb : String, path : String)
Looks up the route from the Radix::Tree for the first time and caches to improve performance.
- #routes : Radix::Tree(Kemal::Route)
-
#routes=(routes : Radix::Tree(Route))
Rebuilds the verb index
#allowed_methodsprobes with, so a tree handed over wholesale advertises the routes it already carries instead of none.
Constructor Detail
Instance Method Detail
Adds a given route to routing tree.
Returns every HTTP method registered for path, in Allow header order,
or an empty array when nothing is routed there.
The radix tree is keyed by /METHOD/path, so there is no way to ask it
which methods a path carries - each routable verb has to be looked up in
turn. HEAD is reported wherever GET is, matching the HEAD -> GET
fallback in #lookup_route.
Deliberately bypasses the route cache: this only runs for a request that already failed to match, and priming the LRU with one entry per verb would let mismatched requests evict the routes actually being served.
Only verbs the application actually registered are probed, so an app
serving GET and POST pays two tree lookups here rather than one per
routable verb - this is the path scanner traffic takes. The index is
maintained by #add_route and rebuilt from the tree by #routes=, which
are the two supported ways routes get in. A route pushed straight into the
tree through the #routes getter bypasses both; that path degrades to the
pre-405 answer of 404 rather than reporting a wrong Allow.
A ws route is reported as GET: the opening handshake is a GET
(RFC 6455 ยง4.1), so a path carrying one does support the method. It gets
no HEAD - the upgrade is the only thing served there, and
Kemal::WebSocketHandler answers nothing else. The probe sits outside the
@registered_methods shortcut above because that index only tracks HTTP
routes, so a WebSocket-only app would otherwise report nothing at all. It
is skipped once an HTTP route has already put GET in the list.
It adds one lookup in a separate, WebSocket-only tree to every miss:
measured at ~40ns on top of the ~490ns a two-verb probe already costs
(Crystal 1.21, --release, Apple M-series), and unchanged whether or not
the app registers any ws routes.
Setter is synchronized for thread-safety when specs reset the cache.
Looks up the route from the Radix::Tree for the first time and caches to improve performance. Cache access is synchronized so multiple fibers can call this concurrently.
Rebuilds the verb index #allowed_methods probes with, so a tree handed
over wholesale advertises the routes it already carries instead of none.