Handle RESP strings longer than bufio.Reader size

diff --git a/redis/conn.go b/redis/conn.go
index 5aa0f32..d281bcb 100644
--- a/redis/conn.go
+++ b/redis/conn.go
@@ -427,10 +427,21 @@
 	return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
 }
 
+// readLine reads a line of input from the RESP stream.
 func (c *conn) readLine() ([]byte, error) {
+	// To avoid allocations, attempt to read the line using ReadSlice. This
+	// call typically succeeds. The known case where the call fails is when
+	// reading the output from the MONITOR command.
 	p, err := c.br.ReadSlice('\n')
 	if err == bufio.ErrBufferFull {
-		return nil, protocolError("long response line")
+		// The line does not fit in the bufio.Reader's buffer. Fall back to
+		// allocating a buffer for the line.
+		buf := append([]byte{}, p...)
+		for err == bufio.ErrBufferFull {
+			p, err = c.br.ReadSlice('\n')
+			buf = append(buf, p...)
+		}
+		p = buf
 	}
 	if err != nil {
 		return nil, err
diff --git a/redis/conn_test.go b/redis/conn_test.go
index 63a4c23..779bdfd 100644
--- a/redis/conn_test.go
+++ b/redis/conn_test.go
@@ -170,6 +170,10 @@
 		"PONG",
 	},
 	{
+		"+OK\n\n", // no \r
+		errorSentinel,
+	},
+	{
 		"@OK\r\n",
 		errorSentinel,
 	},
@@ -207,6 +211,11 @@
 	},
 
 	{
+		// "" is not a valid length
+		"$\r\nfoobar\r\n",
+		errorSentinel,
+	},
+	{
 		// "x" is not a valid length
 		"$x\r\nfoobar\r\n",
 		errorSentinel,
@@ -217,6 +226,11 @@
 		errorSentinel,
 	},
 	{
+		// ""  is not a valid integer
+		":\r\n",
+		errorSentinel,
+	},
+	{
 		// "x"  is not a valid integer
 		":x\r\n",
 		errorSentinel,
@@ -258,6 +272,30 @@
 	}
 }
 
+func TestReadString(t *testing.T) {
+	// n is value of bufio.defaultBufSize
+	const n = 4096
+
+	// Test read string lengths near bufio.Reader buffer boundaries.
+	testRanges := [][2]int{{0, 64}, {n - 64, n + 64}, {2*n - 64, 2*n + 64}}
+
+	p := make([]byte, 2*n+64)
+	for i := range p {
+		p[i] = byte('a' + i%26)
+	}
+	s := string(p)
+
+	for _, r := range testRanges {
+		for i := r[0]; i < r[1]; i++ {
+			c, _ := redis.Dial("", "", dialTestConn("+"+s[:i]+"\r\n", nil))
+			actual, err := c.Receive()
+			if err != nil || actual != s[:i] {
+				t.Fatalf("Receive(string len %d) -> err=%v, equal=%v", i, err, actual != s[:i])
+			}
+		}
+	}
+}
+
 var testCommands = []struct {
 	args     []interface{}
 	expected interface{}