Skip to content

Commit 773767d

Browse files
callthingsoffjba
authored andcommitted
net/http: avoid appending an existing trailing slash to path again
This CL is similar to CL 562557, and it takes over CL 594175. While here, unrelatedly remove mapKeys function, use slices.Sorted(maps.Keys(ms)) to simplify code. Fixes #67657 Change-Id: Id8b99216f87a6dcfd6d5fa61407b515324c79112 Reviewed-on: https://go-review.googlesource.com/c/go/+/594737 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Jonathan Amsterdam <[email protected]> Reviewed-by: Joedian Reid <[email protected]>
1 parent 7f90b96 commit 773767d

File tree

3 files changed

+22
-15
lines changed

3 files changed

+22
-15
lines changed

src/net/http/routing_tree_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package http
77
import (
88
"fmt"
99
"io"
10+
"maps"
1011
"strings"
1112
"testing"
1213

@@ -261,9 +262,7 @@ func TestMatchingMethods(t *testing.T) {
261262
t.Run(test.name, func(t *testing.T) {
262263
ms := map[string]bool{}
263264
test.tree.matchingMethods(test.host, test.path, ms)
264-
keys := mapKeys(ms)
265-
slices.Sort(keys)
266-
got := strings.Join(keys, ",")
265+
got := strings.Join(slices.Sorted(maps.Keys(ms)), ",")
267266
if got != test.want {
268267
t.Errorf("got %s, want %s", got, test.want)
269268
}

src/net/http/serve_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,22 @@ func TestMuxNoSlashRedirectWithTrailingSlash(t *testing.T) {
613613
}
614614
}
615615

616+
// Test that we don't attempt trailing-slash response 405 on a path that already has
617+
// a trailing slash.
618+
// See issue #67657.
619+
func TestMuxNoSlash405WithTrailingSlash(t *testing.T) {
620+
mux := NewServeMux()
621+
mux.HandleFunc("GET /{x}/", func(w ResponseWriter, r *Request) {
622+
fmt.Fprintln(w, "ok")
623+
})
624+
w := httptest.NewRecorder()
625+
req, _ := NewRequest("GET", "/", nil)
626+
mux.ServeHTTP(w, req)
627+
if g, w := w.Code, 404; g != w {
628+
t.Errorf("got %d, want %d", g, w)
629+
}
630+
}
631+
616632
func TestShouldRedirectConcurrency(t *testing.T) { run(t, testShouldRedirectConcurrency) }
617633
func testShouldRedirectConcurrency(t *testing.T, mode testMode) {
618634
mux := NewServeMux()

src/net/http/server.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"internal/godebug"
1717
"io"
1818
"log"
19+
"maps"
1920
"math/rand"
2021
"net"
2122
"net/textproto"
@@ -2721,19 +2722,10 @@ func (mux *ServeMux) matchingMethods(host, path string) []string {
27212722
ms := map[string]bool{}
27222723
mux.tree.matchingMethods(host, path, ms)
27232724
// matchOrRedirect will try appending a trailing slash if there is no match.
2724-
mux.tree.matchingMethods(host, path+"/", ms)
2725-
methods := mapKeys(ms)
2726-
slices.Sort(methods)
2727-
return methods
2728-
}
2729-
2730-
// TODO(jba): replace with maps.Keys when it is defined.
2731-
func mapKeys[K comparable, V any](m map[K]V) []K {
2732-
var ks []K
2733-
for k := range m {
2734-
ks = append(ks, k)
2725+
if !strings.HasSuffix(path, "/") {
2726+
mux.tree.matchingMethods(host, path+"/", ms)
27352727
}
2736-
return ks
2728+
return slices.Sorted(maps.Keys(ms))
27372729
}
27382730

27392731
// ServeHTTP dispatches the request to the handler whose

0 commit comments

Comments
 (0)