mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	fastcgi: Prepend missing leading slash when matching paths (see #1645)
httpserver: More path matching tests
This commit is contained in:
		
							parent
							
								
									d8fb2ddc2d
								
							
						
					
					
						commit
						59a5afab29
					
				@ -36,9 +36,25 @@ type Handler struct {
 | 
				
			|||||||
// ServeHTTP satisfies the httpserver.Handler interface.
 | 
					// ServeHTTP satisfies the httpserver.Handler interface.
 | 
				
			||||||
func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
					func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
 | 
				
			||||||
	for _, rule := range h.Rules {
 | 
						for _, rule := range h.Rules {
 | 
				
			||||||
 | 
							// First requirement: Base path must match request path. If it doesn't,
 | 
				
			||||||
		// First requirement: Base path must match and the path must be allowed.
 | 
							// we check to make sure the leading slash is not missing, and if so,
 | 
				
			||||||
		if !httpserver.Path(r.URL.Path).Matches(rule.Path) || !rule.AllowedPath(r.URL.Path) {
 | 
							// we check again with it prepended. This is in case people forget
 | 
				
			||||||
 | 
							// a leading slash when performing rewrites, and we don't want to expose
 | 
				
			||||||
 | 
							// the contents of the (likely PHP) script. See issue #1645.
 | 
				
			||||||
 | 
							hpath := httpserver.Path(r.URL.Path)
 | 
				
			||||||
 | 
							if !hpath.Matches(rule.Path) {
 | 
				
			||||||
 | 
								if strings.HasPrefix(string(hpath), "/") {
 | 
				
			||||||
 | 
									// this is a normal-looking path, and it doesn't match; try next rule
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								hpath = httpserver.Path("/" + string(hpath)) // prepend leading slash
 | 
				
			||||||
 | 
								if !hpath.Matches(rule.Path) {
 | 
				
			||||||
 | 
									// even after fixing the request path, it still doesn't match; try next rule
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// The path must also be allowed (not ignored).
 | 
				
			||||||
 | 
							if !rule.AllowedPath(r.URL.Path) {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,7 @@ import "testing"
 | 
				
			|||||||
func TestPathMatches(t *testing.T) {
 | 
					func TestPathMatches(t *testing.T) {
 | 
				
			||||||
	for i, testcase := range []struct {
 | 
						for i, testcase := range []struct {
 | 
				
			||||||
		reqPath         Path
 | 
							reqPath         Path
 | 
				
			||||||
		rulePath        string
 | 
							rulePath        string // or "base path" as in Caddyfile docs
 | 
				
			||||||
		shouldMatch     bool
 | 
							shouldMatch     bool
 | 
				
			||||||
		caseInsensitive bool
 | 
							caseInsensitive bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
@ -48,7 +48,42 @@ func TestPathMatches(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			reqPath:     "",
 | 
								reqPath:     "",
 | 
				
			||||||
			rulePath:    "/", // a lone forward slash means to match all requests (see issue #1645)
 | 
								rulePath:    "/", // a lone forward slash means to match all requests (see issue #1645) - many future test cases related to this issue
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "foobar.php",
 | 
				
			||||||
 | 
								rulePath:    "/",
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "",
 | 
				
			||||||
 | 
								rulePath:    "",
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "/foo/bar",
 | 
				
			||||||
 | 
								rulePath:    "",
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "/foo/bar",
 | 
				
			||||||
 | 
								rulePath:    "",
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "no/leading/slash",
 | 
				
			||||||
 | 
								rulePath:    "/",
 | 
				
			||||||
 | 
								shouldMatch: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "no/leading/slash",
 | 
				
			||||||
 | 
								rulePath:    "/no/leading/slash",
 | 
				
			||||||
 | 
								shouldMatch: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								reqPath:     "no/leading/slash",
 | 
				
			||||||
 | 
								rulePath:    "",
 | 
				
			||||||
			shouldMatch: true,
 | 
								shouldMatch: true,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	} {
 | 
						} {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user