mirror of
https://github.com/mjl-/mox.git
synced 2025-07-12 17:44:35 +03:00
smtpclient: handle server closing connection after writing its response to RCPT TO
if icloud.com has your ip blocklisted, it will close the smtp connection after writing a response to RCPT TO, before writing a response to a pipelined DATA command. this is similar to the case (already handled) where a mail server would close the connection after a response to MAIL FROM when pipelined. we now recognize this situation (unexpected EOF before we get a response to DATA, with all RCPT TO's failed), and treat the last response to RCPT TO as the result. for issue #198 by soheilpro, thanks for reporting and sending an smtpclient trace that showed the behaviour.
This commit is contained in:
@ -1265,6 +1265,15 @@ func (c *Client) DeliverMultiple(ctx context.Context, mailFrom string, rcptTo []
|
||||
c.xbotchf(0, "", "", nil, "writing pipelined mail/rcpt/data: %w", writeerr)
|
||||
}
|
||||
|
||||
// If remote closed the connection before writing a DATA response, and the RCPT
|
||||
// TO's failed (e.g. after deciding we're on a blocklist), use the last response
|
||||
// for a rcptto as result.
|
||||
if dataerr != nil && errors.Is(dataerr, io.ErrUnexpectedEOF) && nok == 0 {
|
||||
c.botched = true
|
||||
r := rcptResps[len(rcptResps)-1]
|
||||
c.xerrorf(r.Permanent, r.Code, r.Secode, r.Line, r.MoreLines, "%w: server closed connection just before responding to data command", ErrStatus)
|
||||
}
|
||||
|
||||
// If the data command had an i/o or protocol error, it's also a failure for the
|
||||
// entire transaction.
|
||||
if dataerr != nil {
|
||||
|
Reference in New Issue
Block a user