mirror of
https://github.com/gin-gonic/gin.git
synced 2026-06-04 17:58:14 +08:00
Compare commits
5 Commits
44a89742ca
...
cd932b1d4e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd932b1d4e | ||
|
|
d3ffc99852 | ||
|
|
fa1c0ce2ab | ||
|
|
d81699791a | ||
|
|
b0e3cdc077 |
@ -1327,7 +1327,7 @@ func (c *Context) SSEvent(name string, message any) {
|
||||
// indicates "Is client disconnected in middle of stream"
|
||||
func (c *Context) Stream(step func(w io.Writer) bool) bool {
|
||||
w := c.Writer
|
||||
clientGone := w.CloseNotify()
|
||||
clientGone := c.Request.Context().Done()
|
||||
for {
|
||||
select {
|
||||
case <-clientGone:
|
||||
|
||||
72
gin_test.go
72
gin_test.go
@ -743,6 +743,78 @@ func TestEngineHandleContextPreventsMiddlewareReEntry(t *testing.T) {
|
||||
assert.Equal(t, int64(1), handlerCounterV2)
|
||||
}
|
||||
|
||||
func TestEngineHandleContextNoRouteWithGroupMiddleware(t *testing.T) {
|
||||
// Scenario from issue #1848:
|
||||
// - Engine with no global middleware (gin.New())
|
||||
// - A group with middleware
|
||||
// - A route in that group
|
||||
// - NoRoute handler that redirects via HandleContext
|
||||
// The group middleware should run exactly once per HandleContext call,
|
||||
// not accumulate across redirects.
|
||||
|
||||
var middlewareCount, handlerCount int64
|
||||
|
||||
r := New()
|
||||
grp := r.Group("", func(c *Context) {
|
||||
atomic.AddInt64(&middlewareCount, 1)
|
||||
c.Next()
|
||||
})
|
||||
grp.GET("/target", func(c *Context) {
|
||||
atomic.AddInt64(&handlerCount, 1)
|
||||
c.String(http.StatusOK, "ok")
|
||||
})
|
||||
|
||||
r.NoRoute(func(c *Context) {
|
||||
c.Request.URL.Path = "/target"
|
||||
r.HandleContext(c)
|
||||
})
|
||||
|
||||
// Access a non-existent route to trigger NoRoute -> HandleContext
|
||||
w := PerformRequest(r, "GET", "/nonexistent")
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "ok", w.Body.String())
|
||||
// Middleware and handler should each run exactly once
|
||||
assert.Equal(t, int64(1), atomic.LoadInt64(&middlewareCount))
|
||||
assert.Equal(t, int64(1), atomic.LoadInt64(&handlerCount))
|
||||
}
|
||||
|
||||
func TestEngineHandleContextNoRouteWithEngineMiddleware(t *testing.T) {
|
||||
// When engine middleware exists and NoRoute redirects via HandleContext,
|
||||
// verify the handlers run the expected number of times.
|
||||
|
||||
var engineMwCount, groupMwCount, handlerCount int64
|
||||
|
||||
r := New()
|
||||
r.Use(func(c *Context) {
|
||||
atomic.AddInt64(&engineMwCount, 1)
|
||||
c.Next()
|
||||
})
|
||||
|
||||
grp := r.Group("", func(c *Context) {
|
||||
atomic.AddInt64(&groupMwCount, 1)
|
||||
c.Next()
|
||||
})
|
||||
grp.GET("/target", func(c *Context) {
|
||||
atomic.AddInt64(&handlerCount, 1)
|
||||
c.String(http.StatusOK, "ok")
|
||||
})
|
||||
|
||||
r.NoRoute(func(c *Context) {
|
||||
c.Request.URL.Path = "/target"
|
||||
r.HandleContext(c)
|
||||
})
|
||||
|
||||
w := PerformRequest(r, "GET", "/nonexistent")
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Equal(t, "ok", w.Body.String())
|
||||
// Handler and group middleware should each run once (from HandleContext)
|
||||
assert.Equal(t, int64(1), atomic.LoadInt64(&handlerCount))
|
||||
assert.Equal(t, int64(1), atomic.LoadInt64(&groupMwCount))
|
||||
// Engine middleware runs twice: once for the NoRoute chain, once for the HandleContext chain
|
||||
// This is expected behavior since HandleContext re-enters the full handler chain
|
||||
assert.Equal(t, int64(2), atomic.LoadInt64(&engineMwCount))
|
||||
}
|
||||
|
||||
func TestEngineHandleContextUseEscapedPathPercentEncoded(t *testing.T) {
|
||||
r := New()
|
||||
r.UseEscapedPath = true
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user