]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: fix ServeMux.Handler on trailing-slash redirect
authorJonathan Amsterdam <jba@google.com>
Sat, 17 May 2025 23:36:06 +0000 (19:36 -0400)
committerJonathan Amsterdam <jba@google.com>
Mon, 19 May 2025 19:25:47 +0000 (12:25 -0700)
When a match involves a trailing-slash redirect,  ServeMux.Handler now
returns the pattern that matched.

Fixes #73688.

Change-Id: I682d9cc9a3628bed8bf21139b98369ffa6c53792
Reviewed-on: https://go-review.googlesource.com/c/go/+/673815
Reviewed-by: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
src/net/http/serve_test.go
src/net/http/server.go

index 5d2a29a6fc4f0073519555e3de91191e4bdf799c..84d383ccfa2171fd65561be4dd089bcffbd4f1f2 100644 (file)
@@ -391,6 +391,19 @@ func TestServeMuxHandler(t *testing.T) {
        }
 }
 
+// Issue 73688
+func TestServeMuxHandlerTrailingSlash(t *testing.T) {
+       setParallel(t)
+       mux := NewServeMux()
+       const original = "/{x}/"
+       mux.Handle(original, NotFoundHandler())
+       r, _ := NewRequest("POST", "/foo", nil)
+       _, p := mux.Handler(r)
+       if p != original {
+               t.Errorf("got %q, want %q", p, original)
+       }
+}
+
 // Issue 24297
 func TestServeMuxHandleFuncWithNilHandler(t *testing.T) {
        setParallel(t)
index 5dd21bdf3f198f093768e701ba4f4a164c4ed25a..921b42b59e1659cc32b405d4edd157a8350a472b 100644 (file)
@@ -2714,7 +2714,7 @@ func (mux *ServeMux) findHandler(r *Request) (h Handler, patStr string, _ *patte
                var u *url.URL
                n, matches, u = mux.matchOrRedirect(host, r.Method, path, r.URL)
                if u != nil {
-                       return RedirectHandler(u.String(), StatusMovedPermanently), u.Path, nil, nil
+                       return RedirectHandler(u.String(), StatusMovedPermanently), n.pattern.String(), nil, nil
                }
                if path != escapedPath {
                        // Redirect to cleaned path.
@@ -2760,7 +2760,11 @@ func (mux *ServeMux) matchOrRedirect(host, method, path string, u *url.URL) (_ *
                path += "/"
                n2, _ := mux.tree.match(host, method, path)
                if exactMatch(n2, path) {
-                       return nil, nil, &url.URL{Path: cleanPath(u.Path) + "/", RawQuery: u.RawQuery}
+                       // It is safe to return n2 here: it is used only in the second RedirectHandler case
+                       // of findHandler, and that method returns before it does the "n == nil" check where
+                       // the first return value matters. We return it here only to make the pattern available
+                       // to findHandler.
+                       return n2, nil, &url.URL{Path: cleanPath(u.Path) + "/", RawQuery: u.RawQuery}
                }
        }
        return n, matches, nil