mirror of
https://gitea.invidious.io/iv-org/shard-kemal.git
synced 2024-08-15 00:53:36 +00:00
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
|
*.log
|
||||||
|
|
||||||
|
# Libraries don't need dependency lock
|
||||||
|
# Dependencies will be locked in application that uses them
|
||||||
|
/shard.lock
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
name: kemal
|
name: kemal
|
||||||
version: 0.7.0
|
version: 0.7.0
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
beryl:
|
||||||
|
github: luislavena/beryl
|
||||||
|
|
||||||
author:
|
author:
|
||||||
- Serdar Dogruyol <dogruyolserdar@gmail.com>
|
- Serdar Dogruyol <dogruyolserdar@gmail.com>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
require "http/server"
|
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
|
# Kemal::Handler is the main handler which handles all the HTTP requests. Routing, parsing, rendering e.g
|
||||||
# are done in this handler.
|
# are done in this handler.
|
||||||
|
@ -7,7 +8,7 @@ class Kemal::Handler < HTTP::Handler
|
||||||
INSTANCE = new
|
INSTANCE = new
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@routes = [] of Route
|
@tree = Beryl::Routing::Tree.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(request)
|
def call(request)
|
||||||
|
@ -16,15 +17,18 @@ class Kemal::Handler < HTTP::Handler
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_route(method, path, &handler : Kemal::Context -> _)
|
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.
|
# 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
|
end
|
||||||
|
|
||||||
def process_request(request)
|
def process_request(request)
|
||||||
url = request.path.not_nil!
|
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)
|
if route.match?(request)
|
||||||
context = Context.new(request, route)
|
context = Context.new(request, route)
|
||||||
begin
|
begin
|
||||||
|
@ -39,4 +43,13 @@ class Kemal::Handler < HTTP::Handler
|
||||||
# Render 404 unless a route matches
|
# Render 404 unless a route matches
|
||||||
return render_404
|
return render_404
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Kemal::Route
|
||||||
end
|
end
|
||||||
|
|
||||||
def match?(request)
|
def match?(request)
|
||||||
check_for_method_override!(request)
|
self.class.check_for_method_override!(request)
|
||||||
return nil unless request.override_method == @method
|
return nil unless request.override_method == @method
|
||||||
return true if request.path.not_nil!.includes?(':') && request.path.not_nil! == @path
|
return true if request.path.not_nil!.includes?(':') && request.path.not_nil! == @path
|
||||||
request.path.not_nil!.match(@compiled_regex) do |url_params|
|
request.path.not_nil!.match(@compiled_regex) do |url_params|
|
||||||
|
@ -20,7 +20,7 @@ class Kemal::Route
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if request params contain _method param to override request incoming method
|
# 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
|
request.override_method = request.method
|
||||||
if request.method == "POST"
|
if request.method == "POST"
|
||||||
params = Kemal::ParamParser.new(self, request).parse_request
|
params = Kemal::ParamParser.new(self, request).parse_request
|
||||||
|
@ -31,7 +31,7 @@ class Kemal::Route
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks if method contained in _method param is valid one
|
# 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)
|
return false unless override_method.is_a?(String)
|
||||||
override_method = override_method.upcase
|
override_method = override_method.upcase
|
||||||
return (override_method == "PUT" || override_method == "PATCH" || override_method == "DELETE")
|
return (override_method == "PUT" || override_method == "PATCH" || override_method == "DELETE")
|
||||||
|
|
Loading…
Reference in a new issue