smtpclient

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 6, 2023 License: MIT Imports: 17 Imported by: 2

Documentation

Overview

Package smtpclient is an SMTP client, used by the queue for sending outgoing messages.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrSize                = errors.New("message too large for remote smtp server") // SMTP server announced a maximum message size and the message to be delivered exceeds it.
	Err8bitmimeUnsupported = errors.New("remote smtp server does not implement 8bitmime extension, required by message")
	ErrSMTPUTF8Unsupported = errors.New("remote smtp server does not implement smtputf8 extension, required by message")
	ErrStatus              = errors.New("remote smtp server sent unexpected response status code") // Relatively common, e.g. when a 250 OK was expected and server sent 451 temporary error.
	ErrProtocol            = errors.New("smtp protocol error")                                     // After a malformed SMTP response or inconsistent multi-line response.
	ErrTLS                 = errors.New("tls error")                                               // E.g. handshake failure, or hostname validation was required and failed.
	ErrBotched             = errors.New("smtp connection is botched")                              // Set on a client, and returned for new operations, after an i/o error or malformed SMTP response.
	ErrClosed              = errors.New("client is closed")
)

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is an SMTP client that can deliver messages to a mail server.

Use New to make a new client.

func New

func New(ctx context.Context, log *mlog.Log, conn net.Conn, tlsMode TLSMode, remoteHostname, auth string) (*Client, error)

New initializes an SMTP session on the given connection, returning a client that can be used to deliver messages.

New reads the server greeting, identifies itself with a HELO or EHLO command, initializes TLS if remote supports it and optionally authenticates. If successful, a client is returned on which eventually Close must be called. Otherwise an error is returned and the caller is responsible for closing the connection.

Connecting to the correct host is outside the scope of the client. The queue managing outgoing messages decides which host to deliver to, taking multiple MX records with preferences, other DNS records, MTA-STS, retries and special cases into account.

tlsMode indicates if TLS is required, optional or should not be used. A certificate is only validated (trusted, match remoteHostname and not expired) for tls mode "required". By default, SMTP does not verify TLS for interopability reasons, but MTA-STS or DANE can require it. If opportunistic TLS is used, and a TLS error is encountered, the caller may want to try again (on a new connection) without TLS.

If auth is non-empty, it is executed as a command after SMTP greeting/EHLO initialization, before starting delivery. For authenticating to a submission service with AUTH PLAIN, only meant for testing.

func (*Client) Botched

func (c *Client) Botched() bool

Botched returns whether this connection is botched, e.g. a protocol error occurred and the connection is in unknown state, and cannot be used for message delivery.

func (*Client) Close

func (c *Client) Close() (rerr error)

Close cleans up the client, closing the underlying connection.

If the connection is in initialized and not botched, a QUIT command is sent and the response read with a short timeout before closing the underlying connection.

Close returns any error encountered during QUIT and closing.

func (*Client) Deliver

func (c *Client) Deliver(ctx context.Context, mailFrom string, rcptTo string, msgSize int64, msg io.Reader, req8bitmime, reqSMTPUTF8 bool) (rerr error)

Deliver attempts to deliver a message to a mail server.

mailFrom must be an email address, or empty in case of a DSN. rcptTo must be an email address.

If the message contains bytes with the high bit set, req8bitmime must be true. If set, the remote server must support the 8BITMIME extension or delivery will fail.

If the message is internationalized, e.g. when headers contain non-ASCII character, or when UTF-8 is used in a localpart, reqSMTPUTF8 must be true. If set, the remote server must support the SMTPUTF8 extension or delivery will fail.

Deliver uses the following SMTP extensions if the remote server supports them: 8BITMIME, SMTPUTF8, SIZE, PIPELINING, ENHANCEDSTATUSCODES, STARTTLS.

Returned errors can be of type Error, one of the Err-variables in this package or other underlying errors, e.g. for i/o. Use errors.Is to check.

func (*Client) Reset

func (c *Client) Reset() (rerr error)

Reset sends an SMTP RSET command to reset the message transaction state. Deliver automatically sends it if needed.

func (*Client) Supports8BITMIME

func (c *Client) Supports8BITMIME() bool

Supports8BITMIME returns whether the SMTP server supports the 8BITMIME extension, needed for sending data with non-ASCII bytes.

func (*Client) SupportsSMTPUTF8

func (c *Client) SupportsSMTPUTF8() bool

SupportsSMTPUTF8 returns whether the SMTP server supports the SMTPUTF8 extension, needed for sending messages with UTF-8 in headers or in an (SMTP) address.

type Error

type Error struct {
	// Whether failure is permanent, typically because of 5xx response.
	Permanent bool
	// SMTP response status, e.g. 2xx for success, 4xx for transient error and 5xx for
	// permanent failure.
	Code int
	// Short enhanced status, minus first digit and dot. Can be empty, e.g. for io
	// errors or if remote does not send enhanced status codes. If remote responds with
	// "550 5.7.1 ...", the Secode will be "7.1".
	Secode string
	// SMTP command causing failure.
	Command string
	// For errors due to SMTP responses, the full SMTP line excluding CRLF that caused
	// the error. Typically the last line read.
	Line string
	// Underlying error, e.g. one of the Err variables in this package, or io errors.
	Err error
}

Error represents a failure to deliver a message.

Code, Secode, Command and Line are only set for SMTP-level errors, and are zero values otherwise.

func (Error) Error

func (e Error) Error() string

Error returns a readable error string.

func (Error) Unwrap

func (e Error) Unwrap() error

Unwrap returns the underlying Err.

type TLSMode

type TLSMode string

TLSMode indicates if TLS must, should or must not be used.

const (
	// TLS with validated certificate is required: matching name, not expired, trusted by CA.
	TLSStrict TLSMode = "strict"

	// Use TLS if remote claims to support it, but do not validate the certificate
	// (not trusted by CA, different host name or expired certificate is accepted).
	TLSOpportunistic TLSMode = "opportunistic"

	// TLS must not be attempted, e.g. due to earlier TLS handshake error.
	TLSSkip TLSMode = "skip"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL