mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	Refactor. Stop useless rewrite if status code is set.
This commit is contained in:
		
							parent
							
								
									be2f5c4b38
								
							
						
					
					
						commit
						48d7f1ead2
					
				@ -13,6 +13,19 @@ import (
 | 
				
			|||||||
	"github.com/mholt/caddy/middleware"
 | 
						"github.com/mholt/caddy/middleware"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RewriteResult is the result of a rewrite
 | 
				
			||||||
 | 
					type RewriteResult int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// RewriteIgnored is returned when rewrite is not done on request.
 | 
				
			||||||
 | 
						RewriteIgnored RewriteResult = iota
 | 
				
			||||||
 | 
						// RewriteDone is returned when rewrite is done on request.
 | 
				
			||||||
 | 
						RewriteDone
 | 
				
			||||||
 | 
						// RewriteStatus is returned when rewrite is not needed and status code should be set
 | 
				
			||||||
 | 
						// for the request.
 | 
				
			||||||
 | 
						RewriteStatus
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Rewrite is middleware to rewrite request locations internally before being handled.
 | 
					// Rewrite is middleware to rewrite request locations internally before being handled.
 | 
				
			||||||
type Rewrite struct {
 | 
					type Rewrite struct {
 | 
				
			||||||
	Next    middleware.Handler
 | 
						Next    middleware.Handler
 | 
				
			||||||
@ -22,16 +35,18 @@ type Rewrite struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// ServeHTTP implements the middleware.Handler interface.
 | 
					// ServeHTTP implements the middleware.Handler interface.
 | 
				
			||||||
func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
					func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
				
			||||||
 | 
					outer:
 | 
				
			||||||
	for _, rule := range rw.Rules {
 | 
						for _, rule := range rw.Rules {
 | 
				
			||||||
		if ok := rule.Rewrite(rw.FileSys, r); ok {
 | 
							switch result := rule.Rewrite(rw.FileSys, r); result {
 | 
				
			||||||
 | 
							case RewriteDone:
 | 
				
			||||||
			// if rule is complex rule and status code is set
 | 
								break outer
 | 
				
			||||||
 | 
							case RewriteIgnored:
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							case RewriteStatus:
 | 
				
			||||||
 | 
								// only valid for complex rules.
 | 
				
			||||||
			if cRule, ok := rule.(*ComplexRule); ok && cRule.Status != 0 {
 | 
								if cRule, ok := rule.(*ComplexRule); ok && cRule.Status != 0 {
 | 
				
			||||||
				return cRule.Status, nil
 | 
									return cRule.Status, nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			// rewrite done
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return rw.Next.ServeHTTP(w, r)
 | 
						return rw.Next.ServeHTTP(w, r)
 | 
				
			||||||
@ -40,7 +55,7 @@ func (rw Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
 | 
				
			|||||||
// Rule describes an internal location rewrite rule.
 | 
					// Rule describes an internal location rewrite rule.
 | 
				
			||||||
type Rule interface {
 | 
					type Rule interface {
 | 
				
			||||||
	// Rewrite rewrites the internal location of the current request.
 | 
						// Rewrite rewrites the internal location of the current request.
 | 
				
			||||||
	Rewrite(http.FileSystem, *http.Request) bool
 | 
						Rewrite(http.FileSystem, *http.Request) RewriteResult
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SimpleRule is a simple rewrite rule.
 | 
					// SimpleRule is a simple rewrite rule.
 | 
				
			||||||
@ -54,7 +69,7 @@ func NewSimpleRule(from, to string) SimpleRule {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Rewrite rewrites the internal location of the current request.
 | 
					// Rewrite rewrites the internal location of the current request.
 | 
				
			||||||
func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) bool {
 | 
					func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) RewriteResult {
 | 
				
			||||||
	if s.From == r.URL.Path {
 | 
						if s.From == r.URL.Path {
 | 
				
			||||||
		// take note of this rewrite for internal use by fastcgi
 | 
							// take note of this rewrite for internal use by fastcgi
 | 
				
			||||||
		// all we need is the URI, not full URL
 | 
							// all we need is the URI, not full URL
 | 
				
			||||||
@ -63,7 +78,7 @@ func (s SimpleRule) Rewrite(fs http.FileSystem, r *http.Request) bool {
 | 
				
			|||||||
		// attempt rewrite
 | 
							// attempt rewrite
 | 
				
			||||||
		return To(fs, r, s.To, newReplacer(r))
 | 
							return To(fs, r, s.To, newReplacer(r))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false
 | 
						return RewriteIgnored
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ComplexRule is a rewrite rule based on a regular expression
 | 
					// ComplexRule is a rewrite rule based on a regular expression
 | 
				
			||||||
@ -121,33 +136,38 @@ func NewComplexRule(base, pattern, to string, status int, ext []string, ifs []If
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Rewrite rewrites the internal location of the current request.
 | 
					// Rewrite rewrites the internal location of the current request.
 | 
				
			||||||
func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) bool {
 | 
					func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) (re RewriteResult) {
 | 
				
			||||||
	rPath := req.URL.Path
 | 
						rPath := req.URL.Path
 | 
				
			||||||
	replacer := newReplacer(req)
 | 
						replacer := newReplacer(req)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// validate base
 | 
						// validate base
 | 
				
			||||||
	if !middleware.Path(rPath).Matches(r.Base) {
 | 
						if !middleware.Path(rPath).Matches(r.Base) {
 | 
				
			||||||
		return false
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if status is present, stop rewrite and return it.
 | 
				
			||||||
 | 
						if r.Status != 0 {
 | 
				
			||||||
 | 
							return RewriteStatus
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// validate extensions
 | 
						// validate extensions
 | 
				
			||||||
	if !r.matchExt(rPath) {
 | 
						if !r.matchExt(rPath) {
 | 
				
			||||||
		return false
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// validate regexp if present
 | 
				
			||||||
 | 
						if r.Regexp != nil {
 | 
				
			||||||
		// include trailing slash in regexp if present
 | 
							// include trailing slash in regexp if present
 | 
				
			||||||
		start := len(r.Base)
 | 
							start := len(r.Base)
 | 
				
			||||||
		if strings.HasSuffix(r.Base, "/") {
 | 
							if strings.HasSuffix(r.Base, "/") {
 | 
				
			||||||
			start--
 | 
								start--
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// validate regexp if present
 | 
					 | 
				
			||||||
	if r.Regexp != nil {
 | 
					 | 
				
			||||||
		matches := r.FindStringSubmatch(rPath[start:])
 | 
							matches := r.FindStringSubmatch(rPath[start:])
 | 
				
			||||||
		switch len(matches) {
 | 
							switch len(matches) {
 | 
				
			||||||
		case 0:
 | 
							case 0:
 | 
				
			||||||
			// no match
 | 
								// no match
 | 
				
			||||||
			return false
 | 
								return
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			// set regexp match variables {1}, {2} ...
 | 
								// set regexp match variables {1}, {2} ...
 | 
				
			||||||
			for i := 1; i < len(matches); i++ {
 | 
								for i := 1; i < len(matches); i++ {
 | 
				
			||||||
@ -159,7 +179,7 @@ func (r *ComplexRule) Rewrite(fs http.FileSystem, req *http.Request) bool {
 | 
				
			|||||||
	// validate rewrite conditions
 | 
						// validate rewrite conditions
 | 
				
			||||||
	for _, i := range r.Ifs {
 | 
						for _, i := range r.Ifs {
 | 
				
			||||||
		if !i.True(req) {
 | 
							if !i.True(req) {
 | 
				
			||||||
			return false
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -13,7 +13,7 @@ import (
 | 
				
			|||||||
// To attempts rewrite. It attempts to rewrite to first valid path
 | 
					// To attempts rewrite. It attempts to rewrite to first valid path
 | 
				
			||||||
// or the last path if none of the paths are valid.
 | 
					// or the last path if none of the paths are valid.
 | 
				
			||||||
// Returns true if rewrite is successful and false otherwise.
 | 
					// Returns true if rewrite is successful and false otherwise.
 | 
				
			||||||
func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Replacer) bool {
 | 
					func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Replacer) RewriteResult {
 | 
				
			||||||
	tos := strings.Fields(to)
 | 
						tos := strings.Fields(to)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// try each rewrite paths
 | 
						// try each rewrite paths
 | 
				
			||||||
@ -38,7 +38,7 @@ func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Repl
 | 
				
			|||||||
		// Let the user know we got here. Rewrite is expected but
 | 
							// Let the user know we got here. Rewrite is expected but
 | 
				
			||||||
		// the resulting url is invalid.
 | 
							// the resulting url is invalid.
 | 
				
			||||||
		log.Printf("[ERROR] rewrite: resulting path '%v' is invalid. error: %v", t, err)
 | 
							log.Printf("[ERROR] rewrite: resulting path '%v' is invalid. error: %v", t, err)
 | 
				
			||||||
		return false
 | 
							return RewriteIgnored
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// take note of this rewrite for internal use by fastcgi
 | 
						// take note of this rewrite for internal use by fastcgi
 | 
				
			||||||
@ -56,7 +56,7 @@ func To(fs http.FileSystem, r *http.Request, to string, replacer middleware.Repl
 | 
				
			|||||||
		r.URL.Fragment = u.Fragment
 | 
							r.URL.Fragment = u.Fragment
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true
 | 
						return RewriteDone
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// isValidFile checks if file exists on the filesystem.
 | 
					// isValidFile checks if file exists on the filesystem.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user