From 982edd5a7ff1b05be3a0e106825f1f92f32bd9dc Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Sat, 14 Nov 2015 12:39:51 +0200 Subject: [PATCH] Treat all errors on first header byte read as EOF. This eliminates numerous and useless 'connection reset by peer' log messages for keep-alive connections on busy server --- header.go | 16 ++++++---------- header_test.go | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/header.go b/header.go index ba7d824..7c9e61a 100644 --- a/header.go +++ b/header.go @@ -555,11 +555,9 @@ func (h *ResponseHeader) tryRead(r *bufio.Reader, n int) error { h.Clear() b, err := r.Peek(n) if len(b) == 0 { - if err == io.EOF { - return err - } - if err == nil { - panic("bufio.Reader.Peek() returned nil, nil") + // treat all errors on the first byte read as EOF + if n == 1 || err == io.EOF { + return io.EOF } return fmt.Errorf("error when reading response headers: %s", err) } @@ -597,11 +595,9 @@ func (h *RequestHeader) tryRead(r *bufio.Reader, n int) error { h.Clear() b, err := r.Peek(n) if len(b) == 0 { - if err == io.EOF { - return err - } - if err == nil { - panic("bufio.Reader.Peek() returned nil, nil") + // treat all errors on the first byte read as EOF + if n == 1 || err == io.EOF { + return io.EOF } return fmt.Errorf("error when reading request headers: %s", err) } diff --git a/header_test.go b/header_test.go index d5af6ac..aec25e3 100644 --- a/header_test.go +++ b/header_test.go @@ -10,6 +10,42 @@ import ( "testing" ) +func TestResponseHeaderFirstByteReadEOF(t *testing.T) { + var h ResponseHeader + + r := &errorReader{fmt.Errorf("non-eof error")} + br := bufio.NewReader(r) + err := h.Read(br) + if err == nil { + t.Fatalf("expecting error") + } + if err != io.EOF { + t.Fatalf("unexpected error %s. Expecting %s", err, io.EOF) + } +} + +func TestRequestHeaderFirstByteReadEOF(t *testing.T) { + var h RequestHeader + + r := &errorReader{fmt.Errorf("non-eof error")} + br := bufio.NewReader(r) + err := h.Read(br) + if err == nil { + t.Fatalf("expecting error") + } + if err != io.EOF { + t.Fatalf("unexpected error %s. Expecting %s", err, io.EOF) + } +} + +type errorReader struct { + err error +} + +func (r *errorReader) Read(p []byte) (int, error) { + return 0, r.err +} + func TestRequestHeaderEmptyMethod(t *testing.T) { var h RequestHeader