Hello,
I'm encountering unexpected behavior with net/http routing in Go 1.24.1 (amd64, ubuntu linux) when using http.StripPrefix to delegate to a nested http.ServeMux which uses the Go 1.22+ METHOD /path routing syntax. Instead of the nested ServeMux executing its registered handlers for the stripped path, it consistently returns a 301 Moved Permanently redirect to the stripped path itself. ```go package main import ( "fmt" "log" "net/http" "runtime" ) func handleInnerTest(w http.ResponseWriter, r *http.Request) { log.Printf("HANDLER HIT: handleInnerTest (GET /test) | Received Path: %s\n", r.URL.Path) fmt.Fprintln(w, "OK - GET /test") } func handleInnerLogin(w http.ResponseWriter, r *http.Request) { log.Printf("HANDLER HIT: handleInnerLogin (POST /login) | Received Path: %s\n", r.URL.Path) if r.Method != http.MethodPost { http.Error(w, "Method Not Allowed (Handler expected POST)", http.StatusMethodNotAllowed) return } fmt.Fprintln(w, "OK - POST /login") } func main() { log.Printf("Go Version: %s\n", runtime.Version()) innerMux := http.NewServeMux() innerMux.HandleFunc("GET /test", handleInnerTest) innerMux.HandleFunc("POST /login", handleInnerLogin) innerMux.HandleFunc("GET /api2/test2", handleInnerTest) outerMux := http.NewServeMux() // This should remove "/api/" before innerMux sees the request. outerMux.Handle("/api/", http.StripPrefix("/api/", innerMux)) outerMux.Handle("/api2/", innerMux) outerMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { log.Printf("HANDLER HIT: Outer Root Handler | Received Path: %s\n", r.URL.Path) http.NotFound(w, r) }) port := ":8090" log.Printf("Starting server on %s...\n", port) log.Println("----\nEXPECTED BEHAVIOR:") log.Println(" GET /api/test -> 200 OK ('OK - GET /test')") log.Println(" GET /api/nonexistent -> 404 Not Found (from innerMux)") log.Println(" POST /api/login -> 200 OK ('OK - POST /login')") log.Println("----") log.Println("Run tests like:") log.Println(" curl -v http://localhost:8090/api/test") // is HTTP/1.1 301 Moved Permanently && no log print log.Println(" curl -v http://localhost:8090/api/nonexistent") // is HTTP/1.1 301 Moved Permanently && no log print log.Println(" curl -v -X POST http://localhost:8090/api/login") // is HTTP/1.1 301 Moved Permanently && no log print log.Println(" curl -v http://localhost:8090/test/") // is HTTP/1.1 404 Not Found && prints HANDLER HIT: Outer Root Handler | Received Path: /test/ log.Println(" curl -v http://localhost:8090/api2/test2") // is HTTP/1.1 200 OK && prints HANDLER HIT: handleInnerTest (GET /test) | Received Path: /api2/test2 log.Println("----") err := http.ListenAndServe(port, outerMux) if err != nil { log.Fatalf("Server failed: %v\n", err) } } ``` It seems counter-intuitive that after http.StripPrefix modifies the path, the inner ServeMux doesn't seem to use that stripped path to match its handlers, instead issuing a redirect, like curl -v http://localhost:8090/api/test -> `<a href="/test">Moved Permanently</a>` Have I misunderstood how these components should interact? Thanks for any insights. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/cbd4f731-8bcb-4683-8f81-115bb8e4f1a7n%40googlegroups.com.