Refactor DSN field in Client structure

Renamed `dsn` field to `requestDSN` in Client structure for clarity and consistency. Adjusted associated methods and tests to reflect this change, improving code readability and maintainability.
This commit is contained in:
Winni Neessen 2024-10-04 20:29:14 +02:00
parent 92c411454b
commit ef3da39840
Signed by: wneessen
GPG key ID: 385AC9889632126E
2 changed files with 75 additions and 72 deletions

143
client.go
View file

@ -40,19 +40,6 @@ const (
DefaultTLSMinVersion = tls.VersionTLS12 DefaultTLSMinVersion = tls.VersionTLS12
) )
type (
// DSNMailReturnOption is a type wrapper for a string and specifies the type of return content requested
// in a Delivery Status Notification (DSN).
// https://datatracker.ietf.org/doc/html/rfc1891/
DSNMailReturnOption string
// DSNRcptNotifyOption is a type wrapper for a string and specifies the notification options for a
// recipient in DSNs.
// https://datatracker.ietf.org/doc/html/rfc1891/
DSNRcptNotifyOption string
)
const ( const (
// DSNMailReturnHeadersOnly requests that only the message headers of the mail message are returned in // DSNMailReturnHeadersOnly requests that only the message headers of the mail message are returned in
@ -90,82 +77,98 @@ const (
DSNRcptNotifyDelay DSNRcptNotifyOption = "DELAY" DSNRcptNotifyDelay DSNRcptNotifyOption = "DELAY"
) )
// DialContextFunc is a type to define custom DialContext function. type (
type DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)
// Client is the SMTP client struct // DialContextFunc defines a function type for establishing a network connection using context, network
type Client struct { // type, and address. It is used to specify custom DialContext function.
// Timeout for the SMTP server connection //
connTimeout time.Duration // By default we use net.Dial or tls.Dial respectively.
DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)
// dialContextFunc is a custom DialContext function to dial target SMTP server // DSNMailReturnOption is a type wrapper for a string and specifies the type of return content requested
dialContextFunc DialContextFunc // in a Delivery Status Notification (DSN).
// https://datatracker.ietf.org/doc/html/rfc1891/
DSNMailReturnOption string
// dsn indicates that we want to use DSN for the Client // DSNRcptNotifyOption is a type wrapper for a string and specifies the notification options for a
dsn bool // recipient in DSNs.
// https://datatracker.ietf.org/doc/html/rfc1891/
DSNRcptNotifyOption string
// dsnmrtype defines the DSNMailReturnOption in case DSN is enabled // Option is a function type that modifies the configuration or behavior of a Client instance.
dsnmrtype DSNMailReturnOption Option func(*Client) error
// dsnrntype defines the DSNRcptNotifyOption in case DSN is enabled // Client is the go-mail client that is responsible for connecting and interacting with an SMTP server.
dsnrntype []string Client struct {
// connTimeout specifies timeout for the connection to the SMTP server.
connTimeout time.Duration
// fallbackPort is used as an alternative port number in case the primary port is unavailable or // dialContextFunc is the DialContextFunc that is used by the Client to connect to the SMTP server.
// fails to bind. dialContextFunc DialContextFunc
fallbackPort int
// HELO/EHLO string for the greeting the target SMTP server // dsnmrtype defines the DSNMailReturnOption in case DSN is enabled
helo string dsnmrtype DSNMailReturnOption
// Hostname of the target SMTP server to connect to // dsnrntype defines the DSNRcptNotifyOption in case DSN is enabled
host string dsnrntype []string
// isEncrypted indicates if a Client connection is encrypted or not // fallbackPort is used as an alternative port number in case the primary port is unavailable or
isEncrypted bool // fails to bind.
fallbackPort int
// logger is a logger that implements the log.Logger interface // HELO/EHLO string for the greeting the target SMTP server
logger log.Logger helo string
// mutex is used to synchronize access to shared resources, ensuring that only one goroutine can // Hostname of the target SMTP server to connect to
// modify them at a time. host string
mutex sync.RWMutex
// noNoop indicates the Noop is to be skipped // isEncrypted indicates if a Client connection is encrypted or not
noNoop bool isEncrypted bool
// pass is the corresponding SMTP AUTH password // logger is a logger that implements the log.Logger interface
pass string logger log.Logger
// port specifies the network port number on which the server listens for incoming connections. // mutex is used to synchronize access to shared resources, ensuring that only one goroutine can
port int // modify them at a time.
mutex sync.RWMutex
// smtpAuth is a pointer to smtp.Auth // noNoop indicates the Noop is to be skipped
smtpAuth smtp.Auth noNoop bool
// smtpAuthType represents the authentication type for SMTP AUTH // pass is the corresponding SMTP AUTH password
smtpAuthType SMTPAuthType pass string
// smtpClient is the smtp.Client that is set up when using the Dial*() methods // port specifies the network port number on which the server listens for incoming connections.
smtpClient *smtp.Client port int
// tlspolicy sets the client to use the provided TLSPolicy for the STARTTLS protocol // requestDSN indicates that we want to use DSN for the Client
tlspolicy TLSPolicy requestDSN bool
// tlsconfig represents the tls.Config setting for the STARTTLS connection // smtpAuth is a pointer to smtp.Auth
tlsconfig *tls.Config smtpAuth smtp.Auth
// useDebugLog enables the debug logging on the SMTP client // smtpAuthType represents the authentication type for SMTP AUTH
useDebugLog bool smtpAuthType SMTPAuthType
// user is the SMTP AUTH username // smtpClient is the smtp.Client that is set up when using the Dial*() methods
user string smtpClient *smtp.Client
// Use SSL for the connection // tlspolicy sets the client to use the provided TLSPolicy for the STARTTLS protocol
useSSL bool tlspolicy TLSPolicy
}
// Option returns a function that can be used for grouping Client options // tlsconfig represents the tls.Config setting for the STARTTLS connection
type Option func(*Client) error tlsconfig *tls.Config
// useDebugLog enables the debug logging on the SMTP client
useDebugLog bool
// user is the SMTP AUTH username
user string
// Use SSL for the connection
useSSL bool
}
)
var ( var (
// ErrInvalidPort should be used if a port is specified that is not valid // ErrInvalidPort should be used if a port is specified that is not valid
@ -394,7 +397,7 @@ func WithPassword(password string) Option {
// and DSNRcptNotifyFailure // and DSNRcptNotifyFailure
func WithDSN() Option { func WithDSN() Option {
return func(c *Client) error { return func(c *Client) error {
c.dsn = true c.requestDSN = true
c.dsnmrtype = DSNMailReturnFull c.dsnmrtype = DSNMailReturnFull
c.dsnrntype = []string{string(DSNRcptNotifyFailure), string(DSNRcptNotifySuccess)} c.dsnrntype = []string{string(DSNRcptNotifyFailure), string(DSNRcptNotifySuccess)}
return nil return nil
@ -414,7 +417,7 @@ func WithDSNMailReturnType(option DSNMailReturnOption) Option {
return ErrInvalidDSNMailReturnOption return ErrInvalidDSNMailReturnOption
} }
c.dsn = true c.requestDSN = true
c.dsnmrtype = option c.dsnmrtype = option
return nil return nil
} }
@ -448,7 +451,7 @@ func WithDSNRcptNotifyType(opts ...DSNRcptNotifyOption) Option {
return ErrInvalidDSNRcptNotifyCombination return ErrInvalidDSNRcptNotifyCombination
} }
c.dsn = true c.requestDSN = true
c.dsnrntype = rcptOpts c.dsnrntype = rcptOpts
return nil return nil
} }
@ -870,7 +873,7 @@ func (c *Client) sendSingleMsg(message *Msg) error {
} }
} }
if c.dsn { if c.requestDSN {
if c.dsnmrtype != "" { if c.dsnmrtype != "" {
c.smtpClient.SetDSNMailReturnOption(string(c.dsnmrtype)) c.smtpClient.SetDSNMailReturnOption(string(c.dsnmrtype))
} }

View file

@ -483,8 +483,8 @@ func TestWithDSN(t *testing.T) {
t.Errorf("failed to create new client: %s", err) t.Errorf("failed to create new client: %s", err)
return return
} }
if !c.dsn { if !c.requestDSN {
t.Errorf("WithDSN failed. c.dsn expected to be: %t, got: %t", true, c.dsn) t.Errorf("WithDSN failed. c.requestDSN expected to be: %t, got: %t", true, c.requestDSN)
} }
if c.dsnmrtype != DSNMailReturnFull { if c.dsnmrtype != DSNMailReturnFull {
t.Errorf("WithDSN failed. c.dsnmrtype expected to be: %s, got: %s", DSNMailReturnFull, t.Errorf("WithDSN failed. c.dsnmrtype expected to be: %s, got: %s", DSNMailReturnFull,