From a536cf5dc01afdb96eb2a8715ccdbaf233586f37 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sat, 22 Dec 2018 22:33:04 -0800 Subject: [PATCH] Buffconn should buffer upto maxHeaderBytes to avoid ErrBufferFull (#7017) It can happen with erroneous clients which do not send `Host:` header until 4k worth of header bytes have been read. This can lead to Peek() method of bufio to fail with ErrBufferFull. To avoid this we should make sure that Peek buffer is as large as our maxHeaderBytes count. --- cmd/http/bufconn.go | 4 ++-- cmd/http/bufconn_test.go | 2 +- cmd/http/listener.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/http/bufconn.go b/cmd/http/bufconn.go index c57a68337..f51d25ab3 100644 --- a/cmd/http/bufconn.go +++ b/cmd/http/bufconn.go @@ -99,10 +99,10 @@ func (c *BufConn) Write(b []byte) (n int, err error) { } // newBufConn - creates a new connection object wrapping net.Conn. -func newBufConn(c net.Conn, readTimeout, writeTimeout time.Duration) *BufConn { +func newBufConn(c net.Conn, readTimeout, writeTimeout time.Duration, maxHeaderBytes int) *BufConn { return &BufConn{ QuirkConn: QuirkConn{Conn: c}, - bufReader: bufio.NewReader(c), + bufReader: bufio.NewReaderSize(c, maxHeaderBytes), readTimeout: readTimeout, writeTimeout: writeTimeout, } diff --git a/cmd/http/bufconn_test.go b/cmd/http/bufconn_test.go index f64b0985e..b2b6b609c 100644 --- a/cmd/http/bufconn_test.go +++ b/cmd/http/bufconn_test.go @@ -49,7 +49,7 @@ func TestBuffConnReadTimeout(t *testing.T) { t.Errorf("failed to accept new connection. %v", terr) return } - bufconn := newBufConn(tcpConn, 1*time.Second, 1*time.Second) + bufconn := newBufConn(tcpConn, 1*time.Second, 1*time.Second, 4096) defer bufconn.Close() // Read a line diff --git a/cmd/http/listener.go b/cmd/http/listener.go index 9af8b3815..abbd3752f 100644 --- a/cmd/http/listener.go +++ b/cmd/http/listener.go @@ -222,7 +222,7 @@ func (listener *httpListener) start() { tcpConn.SetKeepAlive(true) tcpConn.SetKeepAlivePeriod(listener.tcpKeepAliveTimeout) - bufconn := newBufConn(tcpConn, listener.readTimeout, listener.writeTimeout) + bufconn := newBufConn(tcpConn, listener.readTimeout, listener.writeTimeout, listener.maxHeaderBytes) if listener.tlsConfig != nil { ok, err := getPlainText(bufconn) if err != nil { @@ -261,7 +261,7 @@ func (listener *httpListener) start() { return } - bufconn = newBufConn(tlsConn, listener.readTimeout, listener.writeTimeout) + bufconn = newBufConn(tlsConn, listener.readTimeout, listener.writeTimeout, listener.maxHeaderBytes) } method, resource, host, err := getMethodResourceHost(bufconn, listener.maxHeaderBytes)