go-smtp icon indicating copy to clipboard operation
go-smtp copied to clipboard

client: introduce DataCommand

Open emersion opened this issue 10 months ago • 1 comments

  • [ ] Tests
  • [ ] Docs
  • [ ] Consider introducing LMTPDataCommand as well
  • [ ] Consider splitting Close and waiting for server reply? Not sure it's really necessary here. Would allow returning a DataResponse struct maybe.

Closes: https://github.com/emersion/go-smtp/issues/189

emersion avatar Apr 24 '24 14:04 emersion

Why not use a CloseWithResponse function?

func (d *dataCloser) CloseWithResponse() (code int, msg string, err error) {
	if d.closed {
		return 0, "", fmt.Errorf("smtp: data writer closed twice")
	}

	if err := d.WriteCloser.Close(); err != nil {
		return 0, "", err
	}

	d.c.conn.SetDeadline(time.Now().Add(d.c.SubmissionTimeout))
	defer d.c.conn.SetDeadline(time.Time{})

	expectedResponses := len(d.c.rcpts)
	if d.c.lmtp {
		for expectedResponses > 0 {
			rcpt := d.c.rcpts[len(d.c.rcpts)-expectedResponses]
			if _, _, err := d.c.readResponse(250); err != nil {
				if smtpErr, ok := err.(*SMTPError); ok {
					if d.statusCb != nil {
						d.statusCb(rcpt, smtpErr)
					}
				} else {
					return 0, "", err
				}
			} else if d.statusCb != nil {
				d.statusCb(rcpt, nil)
			}
			expectedResponses--
		}
	} else {
		code, msg, err = d.c.readResponse(250)
	}

	d.closed = true
	return code, msg, err
}

func (d *dataCloser) Close() error {
	_, _, err := d.CloseWithResponse()
	return err
}

davrux avatar Jul 22 '24 13:07 davrux