mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-09 15:32:54 +01:00
Winni Neessen
63d8cef8ca
This PR refactors the the DSN (RFC 1891) SMTP client handling, that was introduced in f4cdc61dd0
.
While most of the Client options stay the same, the whole workaround logic for the SMTP client has been removed and added as part of the SMTP client instead.
This was we got rid of the Client's own `mail()`, `rcpt()`, `dsnRcpt()`, `dsnMail()` methods as well as the copies of the `cmd()` and `validateLine()` methods. The Client is now using the proper `Mail()` and `Rcpt()` methods of the SMTP client instead.
110 lines
3 KiB
Go
110 lines
3 KiB
Go
// SPDX-FileCopyrightText: 2022-2023 The go-mail Authors
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
//go:build go1.20
|
|
// +build go1.20
|
|
|
|
package mail
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
// Send sends out the mail message
|
|
func (c *Client) Send(ml ...*Msg) (rerr error) {
|
|
if err := c.checkConn(); err != nil {
|
|
rerr = &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)}
|
|
return
|
|
}
|
|
for _, m := range ml {
|
|
m.sendError = nil
|
|
if m.encoding == NoEncoding {
|
|
if ok, _ := c.sc.Extension("8BITMIME"); !ok {
|
|
m.sendError = &SendError{Reason: ErrNoUnencoded, isTemp: false}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
}
|
|
f, err := m.GetSender(false)
|
|
if err != nil {
|
|
m.sendError = &SendError{Reason: ErrGetSender, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
rl, err := m.GetRecipients()
|
|
if err != nil {
|
|
m.sendError = &SendError{Reason: ErrGetRcpts, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
|
|
if c.dsn {
|
|
if c.dsnmrtype != "" {
|
|
c.sc.SetDSNMailReturnOption(string(c.dsnmrtype))
|
|
}
|
|
}
|
|
if err := c.sc.Mail(f); err != nil {
|
|
m.sendError = &SendError{Reason: ErrSMTPMailFrom, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
if reserr := c.sc.Reset(); reserr != nil {
|
|
rerr = errors.Join(rerr, reserr)
|
|
}
|
|
continue
|
|
}
|
|
failed := false
|
|
rse := &SendError{}
|
|
rse.errlist = make([]error, 0)
|
|
rse.rcpt = make([]string, 0)
|
|
rno := strings.Join(c.dsnrntype, ",")
|
|
c.sc.SetDSNRcptNotifyOption(rno)
|
|
for _, r := range rl {
|
|
if err := c.sc.Rcpt(r); err != nil {
|
|
rse.Reason = ErrSMTPRcptTo
|
|
rse.errlist = append(rse.errlist, err)
|
|
rse.rcpt = append(rse.rcpt, r)
|
|
rse.isTemp = isTempError(err)
|
|
failed = true
|
|
}
|
|
}
|
|
if failed {
|
|
if reserr := c.sc.Reset(); reserr != nil {
|
|
rerr = errors.Join(rerr, reserr)
|
|
}
|
|
m.sendError = rse
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
w, err := c.sc.Data()
|
|
if err != nil {
|
|
m.sendError = &SendError{Reason: ErrSMTPData, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
_, err = m.WriteTo(w)
|
|
if err != nil {
|
|
m.sendError = &SendError{Reason: ErrWriteContent, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
|
|
if err := w.Close(); err != nil {
|
|
m.sendError = &SendError{Reason: ErrSMTPDataClose, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
|
|
if err := c.Reset(); err != nil {
|
|
m.sendError = &SendError{Reason: ErrSMTPReset, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
continue
|
|
}
|
|
if err := c.checkConn(); err != nil {
|
|
m.sendError = &SendError{Reason: ErrConnCheck, errlist: []error{err}, isTemp: isTempError(err)}
|
|
rerr = errors.Join(rerr, m.sendError)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|