mirror of
				https://gitea.invidious.io/iv-org/shard-kemal.git
				synced 2024-08-15 00:53:36 +00:00 
			
		
		
		
	Started reimplementing router
This commit is contained in:
		
							parent
							
								
									38089ab84e
								
							
						
					
					
						commit
						0b4a36953f
					
				
					 6 changed files with 40 additions and 67 deletions
				
			
		|  | @ -2,24 +2,24 @@ require "./spec_helper" | ||||||
| 
 | 
 | ||||||
| describe "Route" do | describe "Route" do | ||||||
|   describe "match?" do |   describe "match?" do | ||||||
|     it "doesn't match because of route" do |     # it "doesn't match because of route" do | ||||||
|       route = Route.new("GET", "/foo/bar") { "" } |     #   route = Route.new("GET", "/foo/bar") { "" } | ||||||
|       request = HTTP::Request.new("GET", "/world?message=coco") |     #   request = HTTP::Request.new("GET", "/world?message=coco") | ||||||
|       route.match?(request).should be_nil |     #   route.match?(request).should be_nil | ||||||
|     end |     # end | ||||||
| 
 |     # | ||||||
|     it "doesn't match because of method" do |     # it "doesn't match because of method" do | ||||||
|       route = Route.new("GET", "/foo/bar") { "" } |     #   route = Route.new("GET", "/foo/bar") { "" } | ||||||
|       request = HTTP::Request.new("POST", "/foo/bar") |     #   request = HTTP::Request.new("POST", "/foo/bar") | ||||||
|       route.match?(request).should be_nil |     #   route.match?(request).should be_nil | ||||||
|     end |     # end | ||||||
| 
 |     # | ||||||
|     it "matches" do |     # it "matches" do | ||||||
|       route = Route.new("GET", "/foo/:one/path/:two") { "" } |     #   route = Route.new("GET", "/foo/:one/path/:two") { "" } | ||||||
|       request = HTTP::Request.new("GET", "/foo/uno/path/dos") |     #   request = HTTP::Request.new("GET", "/foo/uno/path/dos") | ||||||
|       match = route.match?(request) |     #   match = route.match?(request) | ||||||
|       match.should eq true |     #   match.should eq true | ||||||
|     end |     # end | ||||||
| 
 | 
 | ||||||
|     it "matches the correct route" do |     it "matches the correct route" do | ||||||
|       kemal = Kemal::Handler.new |       kemal = Kemal::Handler.new | ||||||
|  |  | ||||||
|  | @ -3,10 +3,10 @@ | ||||||
| class Kemal::Context | class Kemal::Context | ||||||
|   getter request |   getter request | ||||||
|   getter response |   getter response | ||||||
|   getter params |   getter route | ||||||
|   getter content_type |   getter content_type | ||||||
| 
 | 
 | ||||||
|   def initialize(@request, @params) |   def initialize(@request, @route) | ||||||
|     @response = Kemal::Response.new |     @response = Kemal::Response.new | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  | @ -22,6 +22,10 @@ class Kemal::Context | ||||||
|     @response.content_type |     @response.content_type | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def params | ||||||
|  |     Kemal::ParamParser.new(@route, @request).parse | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   delegate headers, @request |   delegate headers, @request | ||||||
|   delegate status_code, :"status_code=", :"content_type=", @response |   delegate status_code, :"status_code=", :"content_type=", @response | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| require "http/server" | require "http/server" | ||||||
| require "uri" |  | ||||||
| 
 | 
 | ||||||
| # 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. | ||||||
|  | @ -24,11 +23,11 @@ class Kemal::Handler < HTTP::Handler | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def process_request(request) |   def process_request(request) | ||||||
|  |     url = request.path.not_nil! | ||||||
|     @routes.each do |route| |     @routes.each do |route| | ||||||
|       match = route.match?(request) |       url.match(route.pattern as Regex) do |url_params| | ||||||
|       if match |         request.url_params = url_params | ||||||
|         params = Kemal::ParamParser.new(route, request).parse |         context = Context.new(request, route) | ||||||
|         context = Context.new(request, params) |  | ||||||
|         begin |         begin | ||||||
|           body = route.handler.call(context).to_s |           body = route.handler.call(context).to_s | ||||||
|           return HTTP::Response.new(context.status_code, body, context.response_headers) |           return HTTP::Response.new(context.status_code, body, context.response_headers) | ||||||
|  |  | ||||||
|  | @ -11,17 +11,15 @@ class Kemal::ParamParser | ||||||
|   APPLICATION_JSON = "application/json" |   APPLICATION_JSON = "application/json" | ||||||
| 
 | 
 | ||||||
|   def initialize(@route, @request) |   def initialize(@route, @request) | ||||||
|     @route_components = route.components |  | ||||||
|     @request_components = request.path.not_nil!.split "/" |  | ||||||
|     @params = {} of String => AllParamTypes |     @params = {} of String => AllParamTypes | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def parse |   def parse | ||||||
|     parse_components |  | ||||||
|     parse_request |     parse_request | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def parse_request |   def parse_request | ||||||
|  |     parse_url_params | ||||||
|     parse_query |     parse_query | ||||||
|     parse_body |     parse_body | ||||||
|     parse_json |     parse_json | ||||||
|  | @ -37,6 +35,10 @@ class Kemal::ParamParser | ||||||
|     parse_part(@request.query) |     parse_part(@request.query) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def parse_url_params | ||||||
|  |     parse_part(@request.url_params.to_s) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   # Parses JSON request body if Content-Type is `application/json`. |   # Parses JSON request body if Content-Type is `application/json`. | ||||||
|   # If request body is a JSON Hash then all the params are parsed and added into `params`. |   # If request body is a JSON Hash then all the params are parsed and added into `params`. | ||||||
|   # If request body is a JSON Array it's added into `params` as `_json` and can be accessed |   # If request body is a JSON Array it's added into `params` as `_json` and can be accessed | ||||||
|  | @ -45,7 +47,6 @@ class Kemal::ParamParser | ||||||
|     return unless @request.body && @request.headers["Content-Type"]? == APPLICATION_JSON |     return unless @request.body && @request.headers["Content-Type"]? == APPLICATION_JSON | ||||||
| 
 | 
 | ||||||
|     body = @request.body as String |     body = @request.body as String | ||||||
| 
 |  | ||||||
|     case json = JSON.parse(body).raw |     case json = JSON.parse(body).raw | ||||||
|     when Hash |     when Hash | ||||||
|       json.each do |k, v| |       json.each do |k, v| | ||||||
|  | @ -63,13 +64,4 @@ class Kemal::ParamParser | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def parse_components |  | ||||||
|     @route_components.zip(@request_components) do |route_component, req_component| |  | ||||||
|       if route_component.starts_with? ':' |  | ||||||
|         @params[route_component[1..-1]] = req_component |  | ||||||
|       else |  | ||||||
|         return nil unless route_component == req_component |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| # Opening HTTP::Request to add override_method property | # Opening HTTP::Request to add override_method property | ||||||
| class HTTP::Request | class HTTP::Request | ||||||
|   property override_method |   property override_method | ||||||
|  |   property url_params | ||||||
| end | end | ||||||
|  |  | ||||||
|  | @ -3,40 +3,17 @@ | ||||||
| # what action to be done if the route is matched. | # what action to be done if the route is matched. | ||||||
| class Kemal::Route | class Kemal::Route | ||||||
|   getter handler |   getter handler | ||||||
|   getter components |   getter pattern | ||||||
| 
 | 
 | ||||||
|   def initialize(@method, path, &@handler : Kemal::Context -> _) |   def initialize(@method, path, &@handler : Kemal::Context -> _) | ||||||
|     @components = path.split "/" |     @pattern = pattern_to_regex path | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def match?(request) |   private def pattern_to_regex(pattern) | ||||||
|     check_for_method_override!(request) |     pattern = pattern.gsub(/\:(?<param>\w+)/) do |_, match| | ||||||
|     return nil unless request.override_method == @method |       "(?<#{match["param"]}>.*)" | ||||||
|     components = request.path.not_nil!.split "/" |  | ||||||
|     return nil unless components.size == @components.size |  | ||||||
|     @components.zip(components) do |route_component, req_component| |  | ||||||
|       unless route_component.starts_with? ':' |  | ||||||
|         return nil unless route_component == req_component |  | ||||||
|     end |     end | ||||||
|     end |     Regex.new "^#{pattern}/?$" | ||||||
|     true |  | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   # Checks if request params contain _method param to override request incoming method |  | ||||||
|   def check_for_method_override!(request) |  | ||||||
|     request.override_method = request.method |  | ||||||
|     if request.method == "POST" |  | ||||||
|       params = Kemal::ParamParser.new(self, request).parse_request |  | ||||||
|       if params.has_key?("_method") && self.override_method_valid?(params["_method"]) |  | ||||||
|         request.override_method = params["_method"] |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| 
 |  | ||||||
|   # Checks if method contained in _method param is valid one |  | ||||||
|   def 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") |  | ||||||
|   end |  | ||||||
| end | end | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue