[bug] Using route.Methods(...) more than once
Author: edgy-sphereCreated Sep 12, 2022Updated Jul 27, 2024
Labelsbug
**Describe the bug**
Using `func (r *Route) Methods(methods ...string)` more than once for a single route results in a response with status code `405 Method Not Allowed` for this route.
**Background**
I tried to simplify the development of my web APIs, so I introduced some utility functions, with the relevant part essentially being:
func RegisterRoute(
mux *mux.Router,
path string,
methods []string,
handler func(http.ResponseWriter, *http.Request),
) {
mux.HandleFunc(path, handler).Methods("OPTIONS").Methods(methods...)
}
(`OPTIONS` is basically always required; `methods` as a slice because `PUT`, `PATCH` and even `POST` may point to the same handler)
**Versions**
go version go1.19 windows/amd64
> package version: run `git rev-parse HEAD` inside the repo -- what repo? I used go to get `[email protected]`
**Steps to Reproduce**
([GitHub repo](https://github.com/edgy-sphere/debug-mux))
package main
import (
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
mux := mux.NewRouter()
mux.HandleFunc("/test", handler).Methods("PUT").Methods("PATCH")
server := &http.Server{
Addr: ":9710",
Handler: mux,
}
err := server.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}
func handler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
}
**Expected behavior**
Response with status code 200 (for the latter example).
**Solutions?**
Either:
- Disallow using `Methods(...)` more than once, e.g. via changing field `routeConf.matchers` from type `[]matcher` to type `map[string]matcher`, where key `string` (or any other practical type) may be `"METHODS"`.
- Force method matchers to be unique and to be merged if it already exists, e.g. as per above.
- Change `func (r *Route) Match(req *http.Request, match *RouteMatch)` to not return `ErrMethodMismatch` if _any_ method does not match, i.e. if there are multiple method matchers.
It has been not clear to me that using `Methods(...)` twice leads to this behaviour (hence this issue), so I would at least appreciate some kind of information at the function description in the source file -- although _I_ do know now.
Also, I neither fully understand your intended design nor Git things like Pull Requests, so I am sorry if my provided solutions may very well be rather lacking.Source: gorilla/mux