mirror of
https://github.com/gin-gonic/gin.git
synced 2026-07-09 04:02:00 +08:00
Compare commits
4 Commits
b7816a6781
...
bddf43524e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bddf43524e | ||
|
|
19f6f28f5c | ||
|
|
665047840e | ||
|
|
03f3e420a3 |
11
gin.go
11
gin.go
@ -122,6 +122,13 @@ type Engine struct {
|
||||
// handler.
|
||||
HandleMethodNotAllowed bool
|
||||
|
||||
// SkipMethodNotAllowedMiddleware if enabled, global middleware registered via Use()
|
||||
// will not be executed for 405 Method Not Allowed responses. This allows
|
||||
// NoMethod handlers to run without triggering middleware that may reject
|
||||
// the request (e.g., authentication, checksum validation) before the 405
|
||||
// response can be sent.
|
||||
SkipMethodNotAllowedMiddleware bool
|
||||
|
||||
// ForwardedByClientIP if enabled, client IP will be parsed from the request's headers that
|
||||
// match those stored at `(*gin.Engine).RemoteIPHeaders`. If no IP was
|
||||
// fetched, it falls back to the IP obtained from
|
||||
@ -358,6 +365,10 @@ func (engine *Engine) rebuild404Handlers() {
|
||||
}
|
||||
|
||||
func (engine *Engine) rebuild405Handlers() {
|
||||
if engine.SkipMethodNotAllowedMiddleware {
|
||||
engine.allNoMethod = engine.noMethod
|
||||
return
|
||||
}
|
||||
engine.allNoMethod = engine.combineHandlers(engine.noMethod)
|
||||
}
|
||||
|
||||
|
||||
59
gin_test.go
59
gin_test.go
@ -1156,3 +1156,62 @@ func TestUpdateRouteTreesCalledOnce(t *testing.T) {
|
||||
assert.Equal(t, "ok", w.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
// Test the fix for https://github.com/gin-gonic/gin/issues/4189
|
||||
func TestSkipMethodNotAllowedMiddleware(t *testing.T) {
|
||||
g := New()
|
||||
g.HandleMethodNotAllowed = true
|
||||
g.SkipMethodNotAllowedMiddleware = true
|
||||
|
||||
var middlewareCalled bool
|
||||
middleware := func(c *Context) {
|
||||
middlewareCalled = true
|
||||
c.Next()
|
||||
}
|
||||
noMethodHandler := func(c *Context) {
|
||||
c.String(http.StatusMethodNotAllowed, "method not allowed")
|
||||
}
|
||||
|
||||
g.Use(middleware)
|
||||
g.NoMethod(noMethodHandler)
|
||||
g.POST("/test", func(c *Context) {
|
||||
c.String(http.StatusOK, "ok")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/test", nil)
|
||||
g.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
||||
assert.Equal(t, "method not allowed", w.Body.String())
|
||||
assert.False(t, middlewareCalled, "middleware should not be called when SkipMethodNotAllowedMiddleware is true")
|
||||
}
|
||||
|
||||
func TestSkipMethodNotAllowedMiddlewareDisabled(t *testing.T) {
|
||||
g := New()
|
||||
g.HandleMethodNotAllowed = true
|
||||
g.SkipMethodNotAllowedMiddleware = false
|
||||
|
||||
var middlewareCalled bool
|
||||
middleware := func(c *Context) {
|
||||
middlewareCalled = true
|
||||
c.Next()
|
||||
}
|
||||
noMethodHandler := func(c *Context) {
|
||||
c.String(http.StatusMethodNotAllowed, "method not allowed")
|
||||
}
|
||||
|
||||
g.Use(middleware)
|
||||
g.NoMethod(noMethodHandler)
|
||||
g.POST("/test", func(c *Context) {
|
||||
c.String(http.StatusOK, "ok")
|
||||
})
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(http.MethodGet, "/test", nil)
|
||||
g.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusMethodNotAllowed, w.Code)
|
||||
assert.Equal(t, "method not allowed", w.Body.String())
|
||||
assert.True(t, middlewareCalled, "middleware should be called when SkipMethodNotAllowedMiddleware is false")
|
||||
}
|
||||
|
||||
4
go.mod
4
go.mod
@ -5,7 +5,7 @@ go 1.25.0
|
||||
require (
|
||||
github.com/bytedance/sonic v1.15.0
|
||||
github.com/gin-contrib/sse v1.1.0
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-playground/validator/v10 v10.30.3
|
||||
github.com/goccy/go-json v0.10.6
|
||||
github.com/goccy/go-yaml v1.19.2
|
||||
github.com/json-iterator/go v1.1.12
|
||||
@ -39,7 +39,7 @@ require (
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
golang.org/x/arch v0.25.0 // indirect
|
||||
golang.org/x/crypto v0.51.0 // indirect
|
||||
golang.org/x/crypto v0.52.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
)
|
||||
|
||||
8
go.sum
8
go.sum
@ -20,8 +20,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||
github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8=
|
||||
github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc=
|
||||
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
@ -79,8 +79,8 @@ go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
|
||||
golang.org/x/arch v0.25.0 h1:qnk6Ksugpi5Bz32947rkUgDt9/s5qvqDPl/gBKdMJLE=
|
||||
golang.org/x/arch v0.25.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
|
||||
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user