mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	httpcaddyfile: Rewrite root and rewrite parsing to allow omitting matcher (#5844)
				
					
				
			This commit is contained in:
		
							parent
							
								
									f3e849e49f
								
							
						
					
					
						commit
						5e2f1b5ced
					
				@ -41,7 +41,7 @@ func init() {
 | 
				
			|||||||
	RegisterDirective("bind", parseBind)
 | 
						RegisterDirective("bind", parseBind)
 | 
				
			||||||
	RegisterDirective("tls", parseTLS)
 | 
						RegisterDirective("tls", parseTLS)
 | 
				
			||||||
	RegisterHandlerDirective("fs", parseFilesystem)
 | 
						RegisterHandlerDirective("fs", parseFilesystem)
 | 
				
			||||||
	RegisterHandlerDirective("root", parseRoot)
 | 
						RegisterDirective("root", parseRoot)
 | 
				
			||||||
	RegisterHandlerDirective("vars", parseVars)
 | 
						RegisterHandlerDirective("vars", parseVars)
 | 
				
			||||||
	RegisterHandlerDirective("redir", parseRedir)
 | 
						RegisterHandlerDirective("redir", parseRedir)
 | 
				
			||||||
	RegisterHandlerDirective("respond", parseRespond)
 | 
						RegisterHandlerDirective("respond", parseRespond)
 | 
				
			||||||
@ -645,18 +645,45 @@ func parseTLS(h Helper) ([]ConfigValue, error) {
 | 
				
			|||||||
// parseRoot parses the root directive. Syntax:
 | 
					// parseRoot parses the root directive. Syntax:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//	root [<matcher>] <path>
 | 
					//	root [<matcher>] <path>
 | 
				
			||||||
func parseRoot(h Helper) (caddyhttp.MiddlewareHandler, error) {
 | 
					func parseRoot(h Helper) ([]ConfigValue, error) {
 | 
				
			||||||
	var root string
 | 
						// consume directive name
 | 
				
			||||||
	for h.Next() {
 | 
					 | 
				
			||||||
	if !h.NextArg() {
 | 
						if !h.NextArg() {
 | 
				
			||||||
		return nil, h.ArgErr()
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		root = h.Val()
 | 
					
 | 
				
			||||||
		if h.NextArg() {
 | 
						// count the tokens to determine what to do
 | 
				
			||||||
 | 
						argsCount := h.CountRemainingArgs()
 | 
				
			||||||
 | 
						if argsCount == 0 {
 | 
				
			||||||
 | 
							return nil, h.Errf("too few arguments; must have at least a root path")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if argsCount > 2 {
 | 
				
			||||||
 | 
							return nil, h.Errf("too many arguments; should only be a matcher and a path")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// with only one arg, assume it's a root path with no matcher token
 | 
				
			||||||
 | 
						if argsCount == 1 {
 | 
				
			||||||
 | 
							if !h.NextArg() {
 | 
				
			||||||
			return nil, h.ArgErr()
 | 
								return nil, h.ArgErr()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							return h.NewRoute(nil, caddyhttp.VarsMiddleware{"root": h.Val()}), nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return caddyhttp.VarsMiddleware{"root": root}, nil
 | 
					
 | 
				
			||||||
 | 
						// parse the matcher token into a matcher set
 | 
				
			||||||
 | 
						userMatcherSet, err := h.ExtractMatcherSet()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// consume directive name, again, because extracting matcher does a reset
 | 
				
			||||||
 | 
						if !h.NextArg() {
 | 
				
			||||||
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// advance to the root path
 | 
				
			||||||
 | 
						if !h.NextArg() {
 | 
				
			||||||
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// make the route with the matcher
 | 
				
			||||||
 | 
						return h.NewRoute(userMatcherSet, caddyhttp.VarsMiddleware{"root": h.Val()}), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// parseFilesystem parses the fs directive. Syntax:
 | 
					// parseFilesystem parses the fs directive. Syntax:
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,112 @@
 | 
				
			|||||||
 | 
					:8080
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With explicit wildcard matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						rewrite * /a
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With path matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						rewrite /path /b
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With named matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						@named method GET
 | 
				
			||||||
 | 
						rewrite @named /c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With no matcher, assumed to be wildcard
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						rewrite /d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"apps": {
 | 
				
			||||||
 | 
							"http": {
 | 
				
			||||||
 | 
								"servers": {
 | 
				
			||||||
 | 
									"srv0": {
 | 
				
			||||||
 | 
										"listen": [
 | 
				
			||||||
 | 
											":8080"
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										"routes": [
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												"handle": [
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"group": "group0",
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "rewrite",
 | 
				
			||||||
 | 
																		"uri": "/a"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"group": "group1",
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "rewrite",
 | 
				
			||||||
 | 
																		"uri": "/b"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																],
 | 
				
			||||||
 | 
																"match": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"path": [
 | 
				
			||||||
 | 
																			"/path"
 | 
				
			||||||
 | 
																		]
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"group": "group2",
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "rewrite",
 | 
				
			||||||
 | 
																		"uri": "/c"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																],
 | 
				
			||||||
 | 
																"match": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"method": [
 | 
				
			||||||
 | 
																			"GET"
 | 
				
			||||||
 | 
																		]
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"group": "group3",
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "rewrite",
 | 
				
			||||||
 | 
																		"uri": "/d"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												]
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,108 @@
 | 
				
			|||||||
 | 
					:8080
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With explicit wildcard matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						root * /a
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With path matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						root /path /b
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With named matcher
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						@named method GET
 | 
				
			||||||
 | 
						root @named /c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# With no matcher, assumed to be wildcard
 | 
				
			||||||
 | 
					route {
 | 
				
			||||||
 | 
						root /d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"apps": {
 | 
				
			||||||
 | 
							"http": {
 | 
				
			||||||
 | 
								"servers": {
 | 
				
			||||||
 | 
									"srv0": {
 | 
				
			||||||
 | 
										"listen": [
 | 
				
			||||||
 | 
											":8080"
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										"routes": [
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												"handle": [
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "vars",
 | 
				
			||||||
 | 
																		"root": "/a"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "vars",
 | 
				
			||||||
 | 
																		"root": "/b"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																],
 | 
				
			||||||
 | 
																"match": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"path": [
 | 
				
			||||||
 | 
																			"/path"
 | 
				
			||||||
 | 
																		]
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "vars",
 | 
				
			||||||
 | 
																		"root": "/c"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																],
 | 
				
			||||||
 | 
																"match": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"method": [
 | 
				
			||||||
 | 
																			"GET"
 | 
				
			||||||
 | 
																		]
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													},
 | 
				
			||||||
 | 
													{
 | 
				
			||||||
 | 
														"handler": "subroute",
 | 
				
			||||||
 | 
														"routes": [
 | 
				
			||||||
 | 
															{
 | 
				
			||||||
 | 
																"handle": [
 | 
				
			||||||
 | 
																	{
 | 
				
			||||||
 | 
																		"handler": "vars",
 | 
				
			||||||
 | 
																		"root": "/d"
 | 
				
			||||||
 | 
																	}
 | 
				
			||||||
 | 
																]
 | 
				
			||||||
 | 
															}
 | 
				
			||||||
 | 
														]
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												]
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -26,7 +26,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
	httpcaddyfile.RegisterHandlerDirective("rewrite", parseCaddyfileRewrite)
 | 
						httpcaddyfile.RegisterDirective("rewrite", parseCaddyfileRewrite)
 | 
				
			||||||
	httpcaddyfile.RegisterHandlerDirective("method", parseCaddyfileMethod)
 | 
						httpcaddyfile.RegisterHandlerDirective("method", parseCaddyfileMethod)
 | 
				
			||||||
	httpcaddyfile.RegisterHandlerDirective("uri", parseCaddyfileURI)
 | 
						httpcaddyfile.RegisterHandlerDirective("uri", parseCaddyfileURI)
 | 
				
			||||||
	httpcaddyfile.RegisterDirective("handle_path", parseCaddyfileHandlePath)
 | 
						httpcaddyfile.RegisterDirective("handle_path", parseCaddyfileHandlePath)
 | 
				
			||||||
@ -38,7 +38,44 @@ func init() {
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Only URI components which are given in <to> will be set in the resulting URI.
 | 
					// Only URI components which are given in <to> will be set in the resulting URI.
 | 
				
			||||||
// See the docs for the rewrite handler for more information.
 | 
					// See the docs for the rewrite handler for more information.
 | 
				
			||||||
func parseCaddyfileRewrite(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
 | 
					func parseCaddyfileRewrite(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error) {
 | 
				
			||||||
 | 
						// consume directive name
 | 
				
			||||||
 | 
						if !h.NextArg() {
 | 
				
			||||||
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// count the tokens to determine what to do
 | 
				
			||||||
 | 
						argsCount := h.CountRemainingArgs()
 | 
				
			||||||
 | 
						if argsCount == 0 {
 | 
				
			||||||
 | 
							return nil, h.Errf("too few arguments; must have at least a rewrite URI")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if argsCount > 2 {
 | 
				
			||||||
 | 
							return nil, h.Errf("too many arguments; should only be a matcher and a URI")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// with only one arg, assume it's a rewrite URI with no matcher token
 | 
				
			||||||
 | 
						if argsCount == 1 {
 | 
				
			||||||
 | 
							if !h.NextArg() {
 | 
				
			||||||
 | 
								return nil, h.ArgErr()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return h.NewRoute(nil, Rewrite{URI: h.Val()}), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// parse the matcher token into a matcher set
 | 
				
			||||||
 | 
						userMatcherSet, err := h.ExtractMatcherSet()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// consume directive name, again, because extracting matcher does a reset
 | 
				
			||||||
 | 
						if !h.NextArg() {
 | 
				
			||||||
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// advance to the rewrite URI
 | 
				
			||||||
 | 
						if !h.NextArg() {
 | 
				
			||||||
 | 
							return nil, h.ArgErr()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var rewr Rewrite
 | 
						var rewr Rewrite
 | 
				
			||||||
	for h.Next() {
 | 
						for h.Next() {
 | 
				
			||||||
		if !h.NextArg() {
 | 
							if !h.NextArg() {
 | 
				
			||||||
@ -49,7 +86,7 @@ func parseCaddyfileRewrite(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler,
 | 
				
			|||||||
			return nil, h.ArgErr()
 | 
								return nil, h.ArgErr()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return rewr, nil
 | 
						return h.NewRoute(userMatcherSet, Rewrite{URI: h.Val()}), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// parseCaddyfileMethod sets up a basic method rewrite handler from Caddyfile tokens. Syntax:
 | 
					// parseCaddyfileMethod sets up a basic method rewrite handler from Caddyfile tokens. Syntax:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user