Ignore ErrNotFound while matching Subrouters (#438)
MatchErr is set by the router to ErrNotFound if no route matches. If no route of a Subrouter matches the error can by safely ignored. This implementation only ignores these errors and does not ignore other errors like ErrMethodMismatch.
This commit is contained in:
committed by
Matt Silverlock
parent
f3ff42f93a
commit
08e7f807d3
32
mux_test.go
32
mux_test.go
@@ -2715,6 +2715,38 @@ func Test_copyRouteConf(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestMethodNotAllowed(t *testing.T) {
|
||||
handler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }
|
||||
router := NewRouter()
|
||||
router.HandleFunc("/thing", handler).Methods(http.MethodGet)
|
||||
router.HandleFunc("/something", handler).Methods(http.MethodGet)
|
||||
|
||||
w := NewRecorder()
|
||||
req := newRequest(http.MethodPut, "/thing")
|
||||
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != 405 {
|
||||
t.Fatalf("Expected status code 405 (got %d)", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubrouterNotFound(t *testing.T) {
|
||||
handler := func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }
|
||||
router := NewRouter()
|
||||
router.Path("/a").Subrouter().HandleFunc("/thing", handler).Methods(http.MethodGet)
|
||||
router.Path("/b").Subrouter().HandleFunc("/something", handler).Methods(http.MethodGet)
|
||||
|
||||
w := NewRecorder()
|
||||
req := newRequest(http.MethodPut, "/not-present")
|
||||
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != 404 {
|
||||
t.Fatalf("Expected status code 404 (got %d)", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// mapToPairs converts a string map to a slice of string pairs
|
||||
func mapToPairs(m map[string]string) []string {
|
||||
var i int
|
||||
|
||||
17
route.go
17
route.go
@@ -43,11 +43,6 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Set MatchErr to nil to prevent
|
||||
// subsequent matching subrouters from failing to run middleware.
|
||||
// If not reset, the middleware would see a non-nil MatchErr and be skipped,
|
||||
// even when there was a matching route.
|
||||
match.MatchErr = nil
|
||||
var matchErr error
|
||||
|
||||
// Match everything.
|
||||
@@ -57,6 +52,18 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
|
||||
matchErr = ErrMethodMismatch
|
||||
continue
|
||||
}
|
||||
|
||||
// Ignore ErrNotFound errors. These errors arise from match call
|
||||
// to Subrouters.
|
||||
//
|
||||
// This prevents subsequent matching subrouters from failing to
|
||||
// run middleware. If not ignored, the middleware would see a
|
||||
// non-nil MatchErr and be skipped, even when there was a
|
||||
// matching route.
|
||||
if match.MatchErr == ErrNotFound {
|
||||
match.MatchErr = nil
|
||||
}
|
||||
|
||||
matchErr = nil
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user