From e9d2f75d36092b544058bceb7b799ff4749748b8 Mon Sep 17 00:00:00 2001 From: "wangzekun.zekin" Date: Tue, 18 Apr 2023 14:52:55 +0800 Subject: [PATCH 1/2] fix: server will ignore last data when Read return n,EOF --- factory/http2_test.go | 8 ++++++-- server.go | 23 +++++++++++++---------- server_test.go | 2 ++ 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/factory/http2_test.go b/factory/http2_test.go index e2f742a..8ebe279 100644 --- a/factory/http2_test.go +++ b/factory/http2_test.go @@ -145,7 +145,9 @@ func getStream(data []byte) io.Reader { go func() { time.Sleep(100 * time.Millisecond) - writer.Write(data) + if len(data) != 0 { + writer.Write(data) + } writer.Close() }() @@ -156,8 +158,10 @@ func getBadStream(data []byte) io.Reader { reader, writer := io.Pipe() go func() { - writer.Write(data) time.Sleep(100 * time.Millisecond) + if len(data) != 0 { + writer.Write(data) + } writer.CloseWithError(errors.New("test error")) }() diff --git a/server.go b/server.go index 8c62ce5..45b06bb 100644 --- a/server.go +++ b/server.go @@ -1834,26 +1834,29 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream) (*responseWriter, er return rw, nil } -func writeResponseBody(rw *responseWriter, reqCtx *app.RequestContext) error { +func writeResponseBody(rw *responseWriter, reqCtx *app.RequestContext) (err error) { if reqCtx.Response.IsBodyStream() { vbuf := utils.CopyBufPool.Get() buf := vbuf.([]byte) for { - n, err := reqCtx.Response.BodyStream().Read(buf) - if err == io.EOF { + var n int + n, err = reqCtx.Response.BodyStream().Read(buf) + if n == 0 { + if err == nil { + return errors.New("BUG: io.Reader returned 0, nil") + } + if err == io.EOF { + err = nil + } break } - if err != nil { - return err - } - _, err = rw.Write(buf[:n]) - if err != nil { - return err + if _, err = rw.Write(buf[:n]); err != nil { + break } } utils.CopyBufPool.Put(vbuf) - return nil + return err } else { // reqCtx.Response.Body can be no error // will split at FrameWriteRequest's Consume function diff --git a/server_test.go b/server_test.go index 109c561..d686b16 100644 --- a/server_test.go +++ b/server_test.go @@ -202,6 +202,7 @@ func newHertzServerTester(t testing.TB, handler app.HandlerFunc, opts ...interfa } st.hpackEnc = hpack.NewEncoder(&st.headerBuf) st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField) + st.addLogFilter("Transport readFrame error") testHookGetServerConn = func(v *serverConn) { st.scMu.Lock() @@ -228,6 +229,7 @@ func newHertzServerTester(t testing.TB, handler app.HandlerFunc, opts ...interfa st.fr.logWrites = true } } + return st } From b99de2162f2f8cd21deed49b3024ef09c3ac23ab Mon Sep 17 00:00:00 2001 From: "wangzekun.zekin" Date: Sun, 23 Apr 2023 11:04:28 +0800 Subject: [PATCH 2/2] update error message --- server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server.go b/server.go index 45b06bb..7703bb3 100644 --- a/server.go +++ b/server.go @@ -1836,14 +1836,14 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream) (*responseWriter, er func writeResponseBody(rw *responseWriter, reqCtx *app.RequestContext) (err error) { if reqCtx.Response.IsBodyStream() { + var n int vbuf := utils.CopyBufPool.Get() buf := vbuf.([]byte) for { - var n int n, err = reqCtx.Response.BodyStream().Read(buf) if n == 0 { if err == nil { - return errors.New("BUG: io.Reader returned 0, nil") + return errors.New("response bodyStream().Read(buf) returns 0, nil") } if err == io.EOF { err = nil