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" | require "./spec_helper" | ||||||
| 
 | 
 | ||||||
| class CustomTestHandler < HTTP::Handler | class CustomTestHandler < Kemal::Handler | ||||||
|   def call(env) |   def call(env) | ||||||
|     env.response << "Kemal" |     env.response << "Kemal" | ||||||
|     call_next env |     call_next env | ||||||
|   end |   end | ||||||
| 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 | describe "Handler" do | ||||||
|   it "adds custom handler before before_*" do |   it "adds custom handler before before_*" do | ||||||
|     filter_middleware = Kemal::Middleware::Filter.new |     filter_middleware = Kemal::Middleware::Filter.new | ||||||
|  | @ -27,4 +67,57 @@ describe "Handler" do | ||||||
|     client_response.status_code.should eq(200) |     client_response.status_code.should eq(200) | ||||||
|     client_response.body.should eq("Kemal is so Great") |     client_response.body.should eq("Kemal is so Great") | ||||||
|   end |   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 | end | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| require "http" | require "http" | ||||||
| require "multipart" | require "multipart" | ||||||
| require "./kemal/*" | require "./kemal/*" | ||||||
|  | require "./kemal/ext/*" | ||||||
| require "./kemal/helpers/*" | require "./kemal/helpers/*" | ||||||
| require "./kemal/middleware/*" | 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