Skip to content

Commit

Permalink
client: introduce DataCommand
Browse files Browse the repository at this point in the history
Closes: #189
  • Loading branch information
emersion committed Apr 24, 2024
1 parent 170fe35 commit b7f245f
Showing 1 changed file with 42 additions and 2 deletions.
44 changes: 42 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,46 @@ func (c *Client) Rcpt(to string, opts *RcptOptions) error {
return nil
}

type DataCommand struct {
c *Client
wc io.WriteCloser

closeErr error
statusText string
}

func (cmd *DataCommand) Write(b []byte) (int, error) {
return cmd.wc.Write(b)
}

func (cmd *DataCommand) Close() error {
if cmd.closeErr != nil {
return cmd.closeErr
}

if err := cmd.wc.Close(); err != nil {
cmd.closeErr = err
return err
}

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

_, msg, err := cmd.c.readResponse(250)
if err != nil {
cmd.closeErr = err
return err
}

cmd.statusText = msg
cmd.closeErr = errors.New("smtp: data writer closed twice")
return nil
}

func (cmd *DataCommand) StatusText() string {
return cmd.statusText
}

type dataCloser struct {
c *Client
io.WriteCloser
Expand Down Expand Up @@ -583,12 +623,12 @@ func (d *dataCloser) Close() error {
// Data must be preceded by one or more calls to Rcpt.
//
// If server returns an error, it will be of type *SMTPError.
func (c *Client) Data() (io.WriteCloser, error) {
func (c *Client) Data() (*DataCommand, error) {
_, _, err := c.cmd(354, "DATA")
if err != nil {
return nil, err
}
return &dataCloser{c: c, WriteCloser: c.text.DotWriter()}, nil
return &DataCommand{c: c, wc: c.text.DotWriter()}, nil
}

// LMTPData is the LMTP-specific version of the Data method. It accepts a callback
Expand Down

0 comments on commit b7f245f

Please sign in to comment.