mirror of
				https://gitea.invidious.io/iv-org/shard-kemal.git
				synced 2024-08-15 00:53:36 +00:00 
			
		
		
		
	Only / Exclude Paths in Middleware (#245)
Add only / exclude paths in Middlewares
This commit is contained in:
		
							parent
							
								
									7688bd13a5
								
							
						
					
					
						commit
						ec11698ab1
					
				
					 3 changed files with 159 additions and 1 deletions
				
			
		|  | @ -1,12 +1,52 @@ | |||
| require "./spec_helper" | ||||
| 
 | ||||
| class CustomTestHandler < HTTP::Handler | ||||
| class CustomTestHandler < Kemal::Handler | ||||
|   def call(env) | ||||
|     env.response << "Kemal" | ||||
|     call_next env | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| class OnlyHandler < Kemal::Handler | ||||
|   only ["/only"] | ||||
| 
 | ||||
|   def call(env) | ||||
|     return call_next(env) unless only_match?(env) | ||||
|     env.response.print "Only" | ||||
|     call_next env | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| class ExcludeHandler < Kemal::Handler | ||||
|   exclude ["/exclude"] | ||||
| 
 | ||||
|   def call(env) | ||||
|     return call_next(env) if exclude_match?(env) | ||||
|     env.response.print "Exclude" | ||||
|     call_next env | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| class PostOnlyHandler < Kemal::Handler | ||||
|   only ["/only", "/route1", "/route2"], "POST" | ||||
| 
 | ||||
|   def call(env) | ||||
|     return call_next(env) unless only_match?(env) | ||||
|     env.response.print "Only" | ||||
|     call_next env | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| class PostExcludeHandler < Kemal::Handler | ||||
|   exclude ["/exclude"], "POST" | ||||
| 
 | ||||
|   def call(env) | ||||
|     return call_next(env) if exclude_match?(env) | ||||
|     env.response.print "Exclude" | ||||
|     call_next env | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| describe "Handler" do | ||||
|   it "adds custom handler before before_*" do | ||||
|     filter_middleware = Kemal::Middleware::Filter.new | ||||
|  | @ -27,4 +67,57 @@ describe "Handler" do | |||
|     client_response.status_code.should eq(200) | ||||
|     client_response.body.should eq("Kemal is so Great") | ||||
|   end | ||||
| 
 | ||||
|   it "runs specified only_routes in middleware" do | ||||
|     get "/only" do |env| | ||||
|       "Get" | ||||
|     end | ||||
|     add_handler OnlyHandler.new | ||||
|     request = HTTP::Request.new("GET", "/only") | ||||
|     client_response = call_request_on_app(request) | ||||
|     client_response.body.should eq "OnlyGet" | ||||
|   end | ||||
| 
 | ||||
|   it "doesn't run specified exclude_routes in middleware" do | ||||
|     get "/" do |env| | ||||
|       "Get" | ||||
|     end | ||||
|     get "/exclude" do | ||||
|       "Exclude" | ||||
|     end | ||||
|     add_handler ExcludeHandler.new | ||||
|     request = HTTP::Request.new("GET", "/") | ||||
|     client_response = call_request_on_app(request) | ||||
|     client_response.body.should eq "ExcludeGet" | ||||
|   end | ||||
| 
 | ||||
|   it "runs specified only_routes with method in middleware" do | ||||
|     post "/only" do | ||||
|       "Post" | ||||
|     end | ||||
|     get "/only" do | ||||
|       "Get" | ||||
|     end | ||||
|     add_handler PostOnlyHandler.new | ||||
|     request = HTTP::Request.new("POST", "/only") | ||||
|     client_response = call_request_on_app(request) | ||||
|     client_response.body.should eq "OnlyPost" | ||||
|   end | ||||
| 
 | ||||
|   it "doesn't run specified exclude_routes with method in middleware" do | ||||
|     post "/exclude" do | ||||
|       "Post" | ||||
|     end | ||||
|     post "/only" do | ||||
|       "Post" | ||||
|     end | ||||
|     add_handler PostOnlyHandler.new | ||||
|     request = HTTP::Request.new("POST", "/only") | ||||
|     client_response = call_request_on_app(request) | ||||
|     client_response.body.should eq "OnlyPost" | ||||
|     add_handler PostExcludeHandler.new | ||||
|     request = HTTP::Request.new("POST", "/only") | ||||
|     client_response = call_request_on_app(request) | ||||
|     client_response.body.should eq "OnlyExcludePost" | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| require "http" | ||||
| require "multipart" | ||||
| require "./kemal/*" | ||||
| require "./kemal/ext/*" | ||||
| require "./kemal/helpers/*" | ||||
| require "./kemal/middleware/*" | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										64
									
								
								src/kemal/ext/handler.cr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/kemal/ext/handler.cr
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,64 @@ | |||
| class Kemal::Handler < HTTP::Handler | ||||
|   @@only_routes_tree = Radix::Tree(String).new | ||||
|   @@exclude_routes_tree = Radix::Tree(String).new | ||||
| 
 | ||||
|   macro only(paths, method = "GET") | ||||
|     class_name = {{@type.name}} | ||||
|     {{paths}}.each do |path| | ||||
|       @@only_routes_tree.add "#{class_name}/#{{{method}}.downcase}#{path}", "/#{{{method}}.downcase}#{path}" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   macro exclude(paths, method = "GET") | ||||
|     class_name = {{@type.name}} | ||||
|     {{paths}}.each do |path| | ||||
|       @@exclude_routes_tree.add "#{class_name}/#{{{method}}.downcase}#{path}", "/#{{{method}}.downcase}#{path}" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def call(env) | ||||
|     call_next(env) | ||||
|   end | ||||
| 
 | ||||
|   # Processes the path based on `only` paths which is a `Array(String)`. | ||||
|   # If the path is not found on `only` conditions the handler will continue processing. | ||||
|   # If the path is found in `only` conditions it'll stop processing and will pass the request | ||||
|   # to next handler. | ||||
|   # | ||||
|   # However this is not done automatically. All handlers must inherit from `Kemal::Handler`. | ||||
|   # | ||||
|   #     OnlyHandler < Kemal::Handler | ||||
|   #       only ["/"] | ||||
|   # | ||||
|   #       def call(env) | ||||
|   #         return call_next(env) unless only_match?(env) | ||||
|   #         puts "If the path is / i will be doing some processing here." | ||||
|   #       end | ||||
|   #     end | ||||
|   def only_match?(env) | ||||
|     @@only_routes_tree.find(radix_path(env.request.method, env.request.path)).found? | ||||
|   end | ||||
| 
 | ||||
|   # Processes the path based on `exclude` paths which is a `Array(String)`. | ||||
|   # If the path is not found on `exclude` conditions the handler will continue processing. | ||||
|   # If the path is found in `exclude` conditions it'll stop processing and will pass the request | ||||
|   # to next handler. | ||||
|   # | ||||
|   # However this is not done automatically. All handlers must inherit from `Kemal::Handler`. | ||||
|   # | ||||
|   #     ExcludeHandler < Kemal::Handler | ||||
|   #       exclude ["/"] | ||||
|   # | ||||
|   #       def call(env) | ||||
|   #         return call_next(env) if exclude_match?(env) | ||||
|   #         puts "If the path is not / i will be doing some processing here." | ||||
|   #       end | ||||
|   #     end | ||||
|   def exclude_match?(env) | ||||
|     @@exclude_routes_tree.find(radix_path(env.request.method, env.request.path)).found? | ||||
|   end | ||||
| 
 | ||||
|   private def radix_path(method : String, path) | ||||
|     "#{self.class}/#{method.downcase}#{path}" | ||||
|   end | ||||
| end | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue