Browse Source
			 
			
			caddyhttp: Implement handler abort; new 'abort' directive (close  #3871 ) (#3983 ) 
 
* caddyhttp: Implement handler abort; new 'abort' directive (close  #3871 )
* Move abort directive ordering; clean up redirects
Seems logical for the end-all of handlers to go at the... end.
The Connection header no longer needs to be set there, since Close is
true, and the static_response handler now does that. 
			
			
				 
		
			
				
					
						Matt Holt 
					
					5 years ago 
							GitHub 
							
						 
					
				 
				
			 
		 
		
			
				
					GPG Key ID:  
		
		
		
	
		
			
				 4 changed files  with 
27 additions  and 
4 deletions 
			 
			
		 
		
			
				
					
					
					  
					caddyconfig/httpcaddyfile/builtins.go 
				 
			
				
					
					
					  
					caddyconfig/httpcaddyfile/directives.go 
				 
			
				
					
					
					  
					modules/caddyhttp/autohttps.go 
				 
			
				
					
					
					  
					modules/caddyhttp/staticresp.go 
				 
			
		 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					
						
						
							
								 
						
						
					 
				
				@ -40,6 +40,7 @@ func init() { 
			
		
	
		
			
				
						RegisterHandlerDirective ( "root" ,  parseRoot )  
			
		
	
		
			
				
						RegisterHandlerDirective ( "redir" ,  parseRedir )  
			
		
	
		
			
				
						RegisterHandlerDirective ( "respond" ,  parseRespond )  
			
		
	
		
			
				
						RegisterHandlerDirective ( "abort" ,  parseAbort )  
			
		
	
		
			
				
						RegisterHandlerDirective ( "route" ,  parseRoute )  
			
		
	
		
			
				
						RegisterHandlerDirective ( "handle" ,  parseHandle )  
			
		
	
		
			
				
						RegisterDirective ( "handle_errors" ,  parseHandleErrors )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -502,6 +503,15 @@ func parseRespond(h Helper) (caddyhttp.MiddlewareHandler, error) { 
			
		
	
		
			
				
						return  sr ,  nil  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// parseAbort parses the abort directive.
  
			
		
	
		
			
				
					func  parseAbort ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
			
		
	
		
			
				
						h . Next ( )  // consume directive
  
			
		
	
		
			
				
						for  h . Next ( )  ||  h . NextBlock ( 0 )  {  
			
		
	
		
			
				
							return  nil ,  h . ArgErr ( )  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
						return  & caddyhttp . StaticResponse { Abort :  true } ,  nil  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// parseRoute parses the route directive.
  
			
		
	
		
			
				
					func  parseRoute ( h  Helper )  ( caddyhttp . MiddlewareHandler ,  error )  {  
			
		
	
		
			
				
						sr  :=  new ( caddyhttp . Subroute )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
						
					 
				
				 
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					
						
						
							
								 
						
						
					 
				
				@ -69,6 +69,7 @@ var directiveOrder = []string{ 
			
		
	
		
			
				
						"php_fastcgi" ,  
			
		
	
		
			
				
						"file_server" ,  
			
		
	
		
			
				
						"acme_server" ,  
			
		
	
		
			
				
						"abort" ,  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// directiveIsOrdered returns true if dir is
  
			
		
	
	
		
			
				
					
						
							
								 
						
						
						
					 
				
				 
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					
						
						
							
								 
						
						
					 
				
				@ -409,8 +409,7 @@ func (app *App) makeRedirRoute(redirToPort uint, matcherSet MatcherSet) Route { 
			
		
	
		
			
				
								StaticResponse {  
			
		
	
		
			
				
									StatusCode :  WeakString ( strconv . Itoa ( http . StatusPermanentRedirect ) ) ,  
			
		
	
		
			
				
									Headers :  http . Header {  
			
		
	
		
			
				
										"Location" :    [ ] string { redirTo } ,  
			
		
	
		
			
				
										"Connection" :  [ ] string { "close" } ,  
			
		
	
		
			
				
										"Location" :  [ ] string { redirTo } ,  
			
		
	
		
			
				
									} ,  
			
		
	
		
			
				
									Close :  true ,  
			
		
	
		
			
				
								} ,  
			
		
	
	
		
			
				
					
						
							
								 
						
						
						
					 
				
				 
			
		
	
								
							
						
					 
					
				 
			 
		
			
			
			
			
			
			
				
				
					
						
							
								
									
	
		
			
				
					
						
						
							
								 
						
						
					 
				
				@ -42,6 +42,11 @@ type StaticResponse struct { 
			
		
	
		
			
				
						// If true, the server will close the client's connection
  
			
		
	
		
			
				
						// after writing the response.
  
			
		
	
		
			
				
						Close  bool  ` json:"close,omitempty" `  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Immediately and forcefully closes the connection without
  
			
		
	
		
			
				
						// writing a response. Interrupts any other HTTP streams on
  
			
		
	
		
			
				
						// the same connection.
  
			
		
	
		
			
				
						Abort  bool  ` json:"abort,omitempty" `  
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					// CaddyModule returns the Caddy module information.
  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -101,10 +106,18 @@ func (s *StaticResponse) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					func  ( s  StaticResponse )  ServeHTTP ( w  http . ResponseWriter ,  r  * http . Request ,  _  Handler )  error  {  
			
		
	
		
			
				
						repl  :=  r . Context ( ) . Value ( caddy . ReplacerCtxKey ) . ( * caddy . Replacer )  
			
		
	
		
			
				
						// close the connection immediately
  
			
		
	
		
			
				
						if  s . Abort  {  
			
		
	
		
			
				
							panic ( http . ErrAbortHandler )  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// close the connection after responding
  
			
		
	
		
			
				
						r . Close  =  s . Close  
			
		
	
		
			
				
						if  s . Close  {  
			
		
	
		
			
				
							r . Close  =  true  
			
		
	
		
			
				
							w . Header ( ) . Set ( "Connection" ,  "close" )  
			
		
	
		
			
				
						}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						repl  :=  r . Context ( ) . Value ( caddy . ReplacerCtxKey ) . ( * caddy . Replacer )  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// set all headers
  
			
		
	
		
			
				
						for  field ,  vals  :=  range  s . Headers  {