Implement radix algorithm for routing (thanks to beryl)
This commit is contained in:
parent
2cc4c17c80
commit
7d0d5add84
4 changed files with 31 additions and 8 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -1,2 +1,8 @@
|
|||
.crystal
|
||||
/libs/
|
||||
/.crystal/
|
||||
/.shards/
|
||||
*.log
|
||||
|
||||
# Libraries don't need dependency lock
|
||||
# Dependencies will be locked in application that uses them
|
||||
/shard.lock
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
name: kemal
|
||||
version: 0.7.0
|
||||
|
||||
dependencies:
|
||||
beryl:
|
||||
github: luislavena/beryl
|
||||
|
||||
author:
|
||||
- Serdar Dogruyol <dogruyolserdar@gmail.com>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require "http/server"
|
||||
require "beryl/beryl/routing/tree"
|
||||
|
||||
# Kemal::Handler is the main handler which handles all the HTTP requests. Routing, parsing, rendering e.g
|
||||
# are done in this handler.
|
||||
|
@ -7,7 +8,7 @@ class Kemal::Handler < HTTP::Handler
|
|||
INSTANCE = new
|
||||
|
||||
def initialize
|
||||
@routes = [] of Route
|
||||
@tree = Beryl::Routing::Tree.new
|
||||
end
|
||||
|
||||
def call(request)
|
||||
|
@ -16,15 +17,18 @@ class Kemal::Handler < HTTP::Handler
|
|||
end
|
||||
|
||||
def add_route(method, path, &handler : Kemal::Context -> _)
|
||||
@routes << Route.new(method, path, &handler)
|
||||
add_to_radix_tree method, path, Route.new(method, path, &handler)
|
||||
|
||||
# Registering HEAD route for defined GET routes.
|
||||
@routes << Route.new("HEAD", path, &handler) if method == "GET"
|
||||
add_to_radix_tree("HEAD", path, Route.new("HEAD", path, &handler)) if method == "GET"
|
||||
end
|
||||
|
||||
def process_request(request)
|
||||
url = request.path.not_nil!
|
||||
@routes.each do |route|
|
||||
Kemal::Route.check_for_method_override!(request)
|
||||
lookup = @tree.find radix_path(request.override_method, request.path)
|
||||
if lookup.found?
|
||||
route = lookup.payload as Route
|
||||
if route.match?(request)
|
||||
context = Context.new(request, route)
|
||||
begin
|
||||
|
@ -39,4 +43,13 @@ class Kemal::Handler < HTTP::Handler
|
|||
# Render 404 unless a route matches
|
||||
return render_404
|
||||
end
|
||||
|
||||
private def radix_path(method, path)
|
||||
"#{method} #{path}"
|
||||
end
|
||||
|
||||
private def add_to_radix_tree(method, path, route)
|
||||
node = radix_path method, path
|
||||
@tree.add node, route
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ class Kemal::Route
|
|||
end
|
||||
|
||||
def match?(request)
|
||||
check_for_method_override!(request)
|
||||
self.class.check_for_method_override!(request)
|
||||
return nil unless request.override_method == @method
|
||||
return true if request.path.not_nil!.includes?(':') && request.path.not_nil! == @path
|
||||
request.path.not_nil!.match(@compiled_regex) do |url_params|
|
||||
|
@ -20,7 +20,7 @@ class Kemal::Route
|
|||
end
|
||||
|
||||
# Checks if request params contain _method param to override request incoming method
|
||||
def check_for_method_override!(request)
|
||||
def self.check_for_method_override!(request)
|
||||
request.override_method = request.method
|
||||
if request.method == "POST"
|
||||
params = Kemal::ParamParser.new(self, request).parse_request
|
||||
|
@ -31,7 +31,7 @@ class Kemal::Route
|
|||
end
|
||||
|
||||
# Checks if method contained in _method param is valid one
|
||||
def override_method_valid?(override_method)
|
||||
def self.override_method_valid?(override_method)
|
||||
return false unless override_method.is_a?(String)
|
||||
override_method = override_method.upcase
|
||||
return (override_method == "PUT" || override_method == "PATCH" || override_method == "DELETE")
|
||||
|
|
Loading…
Reference in a new issue