mirror of
https://github.com/gin-gonic/gin.git
synced 2026-06-23 18:13:47 +08:00
Merge 30a1dadcb0ae02dbfe894ab8c78b8ec22b79b694 into d9307dbcbbe796a64d9e0ef23452da888dd7f904
This commit is contained in:
commit
2a93f82e57
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")
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user