Skip to content
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] setting custom MethodNotAllowedHandler for subrouter returns 404s #509

Closed
jonasdebeukelaer opened this issue Aug 16, 2019 · 2 comments · Fixed by #510
Closed

[bug] setting custom MethodNotAllowedHandler for subrouter returns 404s #509

jonasdebeukelaer opened this issue Aug 16, 2019 · 2 comments · Fixed by #510
Assignees
Labels

Comments

@jonasdebeukelaer
Copy link
Contributor

Describe the bug

When setting a custom MethodNotAllowedHandler for a Subrouter, a default 404 page not found error is returned instead of the defined handler. Removing the custom handler makes a 405 method not found return as normal.

Versions

Go version: go1.12 darwin/amd64
package version: 6137e19

Steps to Reproduce

Run a server with a subrouter, whose MethodNotAllowedHandler has been set a custom one. sending a POST to http://localhost:3000/api/test responses with 404 page not found

Expected behavior

the custom response custom method not allowed should be returned when trying to POST to http://localhost:3000/api/test

Code Snippets
here's a whole minimal server for your convenience:

package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/mux"
)

func main() {
	router := mux.NewRouter()
	h := handler{}
	nah := notAllowedHandler{}

	apiRouter := router.PathPrefix("/api").Subrouter()
	apiRouter.MethodNotAllowedHandler = nah
	apiRouter.Handle("/test", h).Methods("GET")

	server := &http.Server{
		Addr:    ":3000",
		Handler: router,
	}

	if err := server.ListenAndServe(); err != http.ErrServerClosed {
		fmt.Println("server shutdown:", err)
	}
}

type handler struct {
}

func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "ok")
}

type notAllowedHandler struct {
}

func (h notAllowedHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusMethodNotAllowed)
	fmt.Fprint(w, "custom method not allowed")
}

@elithrar elithrar self-assigned this Aug 16, 2019
@elithrar
Copy link
Contributor

Reproduced on d83b6ff

Fix is likely here:

mux/mux.go

Lines 136 to 167 in eab9c4f

func (r *Router) Match(req *http.Request, match *RouteMatch) bool {
for _, route := range r.routes {
if route.Match(req, match) {
// Build middleware chain if no error was found
if match.MatchErr == nil {
for i := len(r.middlewares) - 1; i >= 0; i-- {
match.Handler = r.middlewares[i].Middleware(match.Handler)
}
}
return true
}
}
if match.MatchErr == ErrMethodMismatch {
if r.MethodNotAllowedHandler != nil {
match.Handler = r.MethodNotAllowedHandler
return true
}
return false
}
// Closest match for a router (includes sub-routers)
if r.NotFoundHandler != nil {
match.Handler = r.NotFoundHandler
match.MatchErr = ErrNotFound
return true
}
match.MatchErr = ErrNotFound
return false
}

Are you willing to submit a PR? I'm travelling through until next week.

@jonasdebeukelaer
Copy link
Contributor Author

Hey, yeah I had an initial dig around and agree the issue is around there.
Sure I'll submit one, hopefully today

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants