Skip to content

Commit

Permalink
Fixes path order dependent response when a nil handler is defined for…
Browse files Browse the repository at this point in the history
… a route(gorilla#515)
  • Loading branch information
rkilingr committed Sep 2, 2019
1 parent e1863a6 commit dde8a3e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
42 changes: 42 additions & 0 deletions mux_test.go
Expand Up @@ -2803,6 +2803,48 @@ func TestSubrouterNotFound(t *testing.T) {
}
}

// testOptionsMiddleWare returns 200 on an OPTIONS request
func testOptionsMiddleWare(inner http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK)
return
}
inner.ServeHTTP(w, r)
})
}

// TestRouterOrder Should Pass whichever order route is defined
func TestRouterOrder(t *testing.T) {
handler := func(w http.ResponseWriter, r *http.Request) {}
router := NewRouter()
router.Path("/a/b").Handler(http.HandlerFunc(handler)).Methods(http.MethodGet)
router.Path("/a/{a}").Handler(nil).Methods(http.MethodOptions)
router.Use(MiddlewareFunc(testOptionsMiddleWare))

w := NewRecorder()
req := newRequest(http.MethodOptions, "/a/b")

router.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("Expected status code 200 (got %d)", w.Code)
}

reversedPathRouter := NewRouter()
reversedPathRouter.Path("/a/{a}").Handler(http.HandlerFunc(handler)).Methods(http.MethodGet)
reversedPathRouter.Path("/a/b").Handler(nil).Methods(http.MethodOptions)
reversedPathRouter.Use(MiddlewareFunc(testOptionsMiddleWare))

w = NewRecorder()

reversedPathRouter.ServeHTTP(w, req)

if w.Code != http.StatusOK {
t.Fatalf("Expected status code 200 (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
Expand Down
6 changes: 4 additions & 2 deletions route.go
Expand Up @@ -74,11 +74,13 @@ func (r *Route) Match(req *http.Request, match *RouteMatch) bool {
return false
}

if match.MatchErr == ErrMethodMismatch && r.handler != nil {
if match.MatchErr == ErrMethodMismatch {
// We found a route which matches request method, clear MatchErr
match.MatchErr = nil
// Then override the mis-matched handler
match.Handler = r.handler
if r.handler != nil {
match.Handler = r.handler
}
}

// Yay, we have a match. Let's collect some info about it.
Expand Down

0 comments on commit dde8a3e

Please sign in to comment.