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 <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Joedian Reid <joedian@google.com>
import (
"fmt"
"io"
+ "maps"
"strings"
"testing"
t.Run(test.name, func(t *testing.T) {
ms := map[string]bool{}
test.tree.matchingMethods(test.host, test.path, ms)
- keys := mapKeys(ms)
- slices.Sort(keys)
- got := strings.Join(keys, ",")
+ got := strings.Join(slices.Sorted(maps.Keys(ms)), ",")
if got != test.want {
t.Errorf("got %s, want %s", got, test.want)
}
}
}
+// Test that we don't attempt trailing-slash response 405 on a path that already has
+// a trailing slash.
+// See issue #67657.
+func TestMuxNoSlash405WithTrailingSlash(t *testing.T) {
+ mux := NewServeMux()
+ mux.HandleFunc("GET /{x}/", func(w ResponseWriter, r *Request) {
+ fmt.Fprintln(w, "ok")
+ })
+ w := httptest.NewRecorder()
+ req, _ := NewRequest("GET", "/", nil)
+ mux.ServeHTTP(w, req)
+ if g, w := w.Code, 404; g != w {
+ t.Errorf("got %d, want %d", g, w)
+ }
+}
+
func TestShouldRedirectConcurrency(t *testing.T) { run(t, testShouldRedirectConcurrency) }
func testShouldRedirectConcurrency(t *testing.T, mode testMode) {
mux := NewServeMux()
"internal/godebug"
"io"
"log"
+ "maps"
"math/rand"
"net"
"net/textproto"
ms := map[string]bool{}
mux.tree.matchingMethods(host, path, ms)
// matchOrRedirect will try appending a trailing slash if there is no match.
- mux.tree.matchingMethods(host, path+"/", ms)
- methods := mapKeys(ms)
- slices.Sort(methods)
- return methods
-}
-
-// TODO(jba): replace with maps.Keys when it is defined.
-func mapKeys[K comparable, V any](m map[K]V) []K {
- var ks []K
- for k := range m {
- ks = append(ks, k)
+ if !strings.HasSuffix(path, "/") {
+ mux.tree.matchingMethods(host, path+"/", ms)
}
- return ks
+ return slices.Sorted(maps.Keys(ms))
}
// ServeHTTP dispatches the request to the handler whose