textproto: prevent long lines in HTTP headers from causing HTTP 400 responses.

This fixes the issue without an extra copy in the average case.

R=golang-dev, ality, bradfitz
CC=golang-dev
https://golang.org/cl/5272049
diff --git a/src/pkg/net/textproto/reader.go b/src/pkg/net/textproto/reader.go
index ece9a99..98b3927 100644
--- a/src/pkg/net/textproto/reader.go
+++ b/src/pkg/net/textproto/reader.go
@@ -50,8 +50,22 @@
 
 func (r *Reader) readLineSlice() ([]byte, os.Error) {
 	r.closeDot()
-	line, _, err := r.R.ReadLine()
-	return line, err
+	var line []byte
+	for {
+		l, more, err := r.R.ReadLine()
+		if err != nil {
+			return nil, err
+		}
+		// Avoid the copy if the first call produced a full line.
+		if line == nil && !more {
+			return l, nil
+		}
+		line = append(line, l...)
+		if !more {
+			break
+		}
+	}
+	return line, nil
 }
 
 // ReadContinuedLine reads a possibly continued line from r,
diff --git a/src/pkg/net/textproto/reader_test.go b/src/pkg/net/textproto/reader_test.go
index 23ebc3f..a087e29 100644
--- a/src/pkg/net/textproto/reader_test.go
+++ b/src/pkg/net/textproto/reader_test.go
@@ -139,6 +139,23 @@
 	}
 }
 
+func TestLargeReadMIMEHeader(t *testing.T) {
+	data := make([]byte, 16*1024)
+	for i := 0; i < len(data); i++ {
+		data[i] = 'x'
+	}
+	sdata := string(data)
+	r := reader("Cookie: " + sdata + "\r\n\n")
+	m, err := r.ReadMIMEHeader()
+	if err != nil {
+		t.Fatalf("ReadMIMEHeader: %v", err)
+	}
+	cookie := m.Get("Cookie")
+	if cookie != sdata {
+		t.Fatalf("ReadMIMEHeader: %v bytes, want %v bytes", len(cookie), len(sdata))
+	}
+}
+
 type readResponseTest struct {
 	in       string
 	inCode   int