// separated by a newline (\n).
//
// See page 36 of RFC 959 (http://www.ietf.org/rfc/rfc959.txt) for
-// details.
+// details of another form of response accepted:
+//
+// code-message line 1
+// message line 2
+// ...
+// code message line n
//
// If the prefix of the status does not match the digits in expectCode,
// ReadResponse returns with err set to &Error{code, message}.
//
func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error) {
code, continued, message, err := r.readCodeLine(expectCode)
- for err == nil && continued {
+ multi := continued
+ for continued {
line, err := r.ReadLine()
if err != nil {
return 0, "", err
var code2 int
var moreMessage string
- code2, continued, moreMessage, err = parseCodeLine(line, expectCode)
+ code2, continued, moreMessage, err = parseCodeLine(line, 0)
if err != nil || code2 != code {
message += "\n" + strings.TrimRight(line, "\r\n")
continued = true
}
message += "\n" + moreMessage
}
+ if err != nil && multi && message != "" {
+ // replace one line error message with all lines (full message)
+ err = &Error{code, message}
+ }
return
}
}
}
+// Test that multi-line errors are appropriately and fully read. Issue 10230.
+func TestReadMultiLineError(t *testing.T) {
+ r := reader("550-5.1.1 The email account that you tried to reach does not exist. Please try\n" +
+ "550-5.1.1 double-checking the recipient's email address for typos or\n" +
+ "550-5.1.1 unnecessary spaces. Learn more at\n" +
+ "Unexpected but legal text!\n" +
+ "550 5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp\n")
+
+ wantMsg := "5.1.1 The email account that you tried to reach does not exist. Please try\n" +
+ "5.1.1 double-checking the recipient's email address for typos or\n" +
+ "5.1.1 unnecessary spaces. Learn more at\n" +
+ "Unexpected but legal text!\n" +
+ "5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp"
+
+ code, msg, err := r.ReadResponse(250)
+ if err == nil {
+ t.Errorf("ReadResponse: no error, want error")
+ }
+ if code != 550 {
+ t.Errorf("ReadResponse: code=%d, want %d", code, 550)
+ }
+ if msg != wantMsg {
+ t.Errorf("ReadResponse: msg=%q, want %q", msg, wantMsg)
+ }
+ if err.Error() != "550 "+wantMsg {
+ t.Errorf("ReadResponse: error=%q, want %q", err.Error(), "550 "+wantMsg)
+ }
+}
+
func TestCommonHeaders(t *testing.T) {
for h := range commonHeader {
if h != CanonicalMIMEHeaderKey(h) {