-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[bug] Using route.Methods(...) more than once #694
Comments
Correct syntax to call mux.HandleFunc("/test", handler).Methods("PUT", "GET", "OPTIONS") I believe there are ample examples mentioned in the r.Methods("GET", "POST") Regarding your background utility function, you can write something like this func RegisterRoute(
mux *mux.Router,
path string,
methods []string,
handler func(http.ResponseWriter, *http.Request),
) {
methods = append(methods, "OPTIONS")
mux.HandleFunc(path, handler).Methods(methods...)
} Just for understanding, I have tried to write a basic generic minimal code to understand what happens when we call // You can edit this code!
// Click here and start typing.
package main
import "fmt"
type matcher interface{}
func main() {
str := []matcher{"GET"}
str = append(str, matcher([]string{"PUT"}))
fmt.Println(str)
} Output of the above code is [GET [PUT]] Similarly in mux while matching the HTTP method I hope I answered your queries and doubts @edgy-sphere |
Thank you for your elaborate reply. My issue was less one of getting my code to work, because as your code snippet indicates the solution is quite trivial. But I have to disagree with your last code snippet: this module ( For clarity I provide my original code snippet again: 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) } When using
This is not how your module handles it. Instead, it has the least logical and least useful effect, which is that it requires a request with the method being both [0]: matcher(*routeRegexp) {template: "/test", ...} [1]: matcher(methodMatcher) ["PUT"] [2]: matcher(methodMatcher) ["PATCH"] So in either case, when the request method is This is why I created this issue, because using |
I would posit this is not really true - each new matcher is ANDed to the previous matchers. you are asking for this one matcher to be ORed, which would be inconsistent. All other matchers work this way. If anything, this method should be documented to explicitly state calling twice on the same route is an error. |
I agree. To be clear, that is why I did not ask to change |
Why would you want it to silently fail? By giving an error, it tells you that something is wrong. If it just ignored or replaced one of the calls, it would be much harder to track down where the issue is. |
I do not agree. The server app did not throw any error. When I sent a request to the server with either If I think my suggestion (only keep first or only keep last) would make the issue clearer. As previously said, during debugging I saw
It is not obvious that this means that any request has to match
For this reason debugging this was not very straightforward for me. Just for illustrative purposes: If instead, for example, the
it would be way clearer why only one of the methods provided is working. |
Or to make it even clearer to the user, an error could be thrown, e.g.:
|
Describe the bug
Using
func (r *Route) Methods(methods ...string)
more than once for a single route results in a response with status code405 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:
(
OPTIONS
is basically always required;methods
as a slice becausePUT
,PATCH
and evenPOST
may point to the same handler)Versions
go version go1.19 windows/amd64
Steps to Reproduce
(GitHub repo)
Expected behavior
Response with status code 200 (for the latter example).
Solutions?
Either:
Methods(...)
more than once, e.g. via changing fieldrouteConf.matchers
from type[]matcher
to typemap[string]matcher
, where keystring
(or any other practical type) may be"METHODS"
.func (r *Route) Match(req *http.Request, match *RouteMatch)
to not returnErrMethodMismatch
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.
The text was updated successfully, but these errors were encountered: