Compare commits

...

5 Commits

Author SHA1 Message Date
hooting
4bbb2a902b
Merge 84a97ef73e13c71e757aaefddbaf9213e6bc3442 into 63dd3e60cab89c27fb66bce1423bd268d52abad1 2025-11-27 23:14:13 -03:00
Yilong Li
63dd3e60ca
fix(recover): suppress http.ErrAbortHandler in recover (#4336)
Co-authored-by: Bo-Yi Wu <appleboy.tw@gmail.com>
2025-11-27 23:20:52 +08:00
Bo-Yi Wu
84a97ef73e
Merge branch 'master' into master 2021-05-02 10:06:14 +08:00
thinkerou
81c4110cb4
Merge branch 'master' into master 2021-04-09 19:53:43 +08:00
unknown
24cea05888 1. add ShouldBindMsgPack; 2. seriallize the given struct as MsgPack into the response body. 2021-03-30 15:07:39 +08:00
3 changed files with 38 additions and 0 deletions

View File

@ -865,6 +865,11 @@ func (c *Context) ShouldBindJSON(obj any) error {
return c.ShouldBindWith(obj, binding.JSON)
}
// ShouldBindMsgPack is a shortcut for c.ShouldBindWith(obj, binding.MsgPack).
func (c *Context) ShouldBindMsgPack(obj interface{}) error {
return c.ShouldBindWith(obj, binding.MsgPack)
}
// ShouldBindXML is a shortcut for c.ShouldBindWith(obj, binding.XML).
// It works like ShouldBindJSON but binds the request body as XML data.
func (c *Context) ShouldBindXML(obj any) error {
@ -1188,6 +1193,12 @@ func (c *Context) JSON(code int, obj any) {
c.Render(code, render.JSON{Data: obj})
}
// MsgPack serializes the given struct as MsgPack into the response body.
// It also sets the Content-Type as "application/msgpack".
func (c *Context) MsgPack(code int, obj interface{}) {
c.Render(code, render.MsgPack{Data: obj})
}
// AsciiJSON serializes the given struct as JSON into the response body with unicode to ASCII string.
// It also sets the Content-Type as "application/json".
func (c *Context) AsciiJSON(code int, obj any) {

View File

@ -68,6 +68,9 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
}
}
}
if e, ok := err.(error); ok && errors.Is(e, http.ErrAbortHandler) {
brokenPipe = true
}
if logger != nil {
const stackSkip = 3
if brokenPipe {

View File

@ -142,6 +142,30 @@ func TestPanicWithBrokenPipe(t *testing.T) {
}
}
// TestPanicWithAbortHandler asserts that recovery handles http.ErrAbortHandler as broken pipe
func TestPanicWithAbortHandler(t *testing.T) {
const expectCode = 204
var buf strings.Builder
router := New()
router.Use(RecoveryWithWriter(&buf))
router.GET("/recovery", func(c *Context) {
// Start writing response
c.Header("X-Test", "Value")
c.Status(expectCode)
// Panic with ErrAbortHandler which should be treated as broken pipe
panic(http.ErrAbortHandler)
})
// RUN
w := PerformRequest(router, http.MethodGet, "/recovery")
// TEST
assert.Equal(t, expectCode, w.Code)
out := buf.String()
assert.Contains(t, out, "net/http: abort Handler")
assert.NotContains(t, out, "panic recovered")
}
func TestCustomRecoveryWithWriter(t *testing.T) {
errBuffer := new(strings.Builder)
buffer := new(strings.Builder)