Skip to content

Commit

Permalink
[bugfix] Clear matchErr when traversing subrouters.
Browse files Browse the repository at this point in the history
Previously, when searching for a match, matchErr would be erroneously set, and prevent middleware from running (no match == no middleware runs).

This fix clears matchErr before traversing the next subrouter in a multi-subrouter router.
  • Loading branch information
tomare authored and elithrar committed Dec 28, 2018
1 parent a31c178 commit ef912dd
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
60 changes: 60 additions & 0 deletions middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,63 @@ func TestCORSMethodMiddleware(t *testing.T) {
}
}
}

func TestMiddlewareOnMultiSubrouter(t *testing.T) {
first := "first"
second := "second"
notFound := "404 not found"

router := NewRouter()
firstSubRouter := router.PathPrefix("/").Subrouter()
secondSubRouter := router.PathPrefix("/").Subrouter()

router.NotFoundHandler = http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte(notFound))
})

firstSubRouter.HandleFunc("/first", func(w http.ResponseWriter, r *http.Request) {

})

secondSubRouter.HandleFunc("/second", func(w http.ResponseWriter, r *http.Request) {

})

firstSubRouter.Use(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(first))
h.ServeHTTP(w, r)
})
})

secondSubRouter.Use(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(second))
h.ServeHTTP(w, r)
})
})

rw := NewRecorder()
req := newRequest("GET", "/first")

router.ServeHTTP(rw, req)
if rw.Body.String() != first {
t.Fatalf("Middleware did not run: expected %s middleware to write a response (got %s)", first, rw.Body.String())
}

rw = NewRecorder()
req = newRequest("GET", "/second")

router.ServeHTTP(rw, req)
if rw.Body.String() != second {
t.Fatalf("Middleware did not run: expected %s middleware to write a response (got %s)", second, rw.Body.String())
}

rw = NewRecorder()
req = newRequest("GET", "/second/not-exist")

router.ServeHTTP(rw, req)
if rw.Body.String() != notFound {
t.Fatalf("Notfound handler did not run: expected %s for not-exist, (got %s)", notFound, rw.Body.String())
}
}
5 changes: 5 additions & 0 deletions route.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ 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.
Expand Down

0 comments on commit ef912dd

Please sign in to comment.