mirror of
https://github.com/gin-gonic/gin.git
synced 2026-09-11 12:18:05 +08:00
fix(gin): reset skippedNodes between method tree probes in 405 handling
handleHTTPRequest reused c.skippedNodes across the per-method getValue probes that build the Allow header when HandleMethodNotAllowed is enabled. A probe that matched via a static branch left its skipped wildcard entries on the stack, and when a later tree's probe dead-ended it could roll back through such a stale entry into the previous tree's nodes, find a handler there, and wrongly list its own method in the Allow header. Reset the stack before each probe.
This commit is contained in:
parent
1e39af4f58
commit
2d0455aa3b
1
gin.go
1
gin.go
@ -743,6 +743,7 @@ func (engine *Engine) handleHTTPRequest(c *Context) {
|
||||
if tree.method == httpMethod {
|
||||
continue
|
||||
}
|
||||
*c.skippedNodes = (*c.skippedNodes)[:0]
|
||||
if value := tree.root.getValue(rPath, nil, c.skippedNodes, unescape); value.handlers != nil {
|
||||
allowed = append(allowed, tree.method)
|
||||
}
|
||||
|
||||
@ -527,6 +527,23 @@ func TestRouteNotAllowedEnabled3(t *testing.T) {
|
||||
assert.Contains(t, allowed, http.MethodPost)
|
||||
}
|
||||
|
||||
func TestRouteNotAllowedDoesNotReuseSkippedNodes(t *testing.T) {
|
||||
router := New()
|
||||
router.HandleMethodNotAllowed = true
|
||||
router.POST("/b", func(c *Context) {})
|
||||
router.POST("/:p0", func(c *Context) {})
|
||||
router.PUT("/a/:p1", func(c *Context) {})
|
||||
|
||||
// The POST probe for the Allow header matches static "/b" while
|
||||
// recording the skipped wildcard ":p0". handleHTTPRequest must reset
|
||||
// c.skippedNodes before probing the PUT tree, or the stale entry
|
||||
// leaks the POST route into the PUT lookup and PUT is wrongly
|
||||
// reported in the Allow header.
|
||||
w := PerformRequest(router, http.MethodGet, "/b")
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
||||
assert.Equal(t, http.MethodPost, w.Header().Get("Allow"))
|
||||
}
|
||||
|
||||
func TestRouteNotAllowedDisabled(t *testing.T) {
|
||||
router := New()
|
||||
router.HandleMethodNotAllowed = false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user