mirror of
https://github.com/emersion/go-smtp
synced 2026-07-02 16:12:37 +00:00
81 lines
1.6 KiB
Go
81 lines
1.6 KiB
Go
package smtp
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
type EnhancedCode [3]int
|
|
|
|
// SMTPError specifies the error code, enhanced error code (if any) and
|
|
// message returned by the server.
|
|
type SMTPError struct {
|
|
Code int
|
|
EnhancedCode EnhancedCode
|
|
Message string
|
|
}
|
|
|
|
// NoEnhancedCode is used to indicate that enhanced error code should not be
|
|
// included in response.
|
|
//
|
|
// Note that RFC 2034 requires an enhanced code to be included in all 2xx, 4xx
|
|
// and 5xx responses. This constant is exported for use by extensions, you
|
|
// should probably use EnhancedCodeNotSet instead.
|
|
var NoEnhancedCode = EnhancedCode{-1, -1, -1}
|
|
|
|
// EnhancedCodeNotSet is a nil value of EnhancedCode field in SMTPError, used
|
|
// to indicate that backend failed to provide enhanced status code. X.0.0 will
|
|
// be used (X is derived from error code).
|
|
var EnhancedCodeNotSet = EnhancedCode{0, 0, 0}
|
|
|
|
func (err *SMTPError) Error() string {
|
|
return err.Message
|
|
}
|
|
|
|
func (err *SMTPError) Temporary() bool {
|
|
return err.Code/100 == 4
|
|
}
|
|
|
|
var ErrDataTooLarge = &SMTPError{
|
|
Code: 552,
|
|
EnhancedCode: EnhancedCode{5, 3, 4},
|
|
Message: "Maximum message size exceeded",
|
|
}
|
|
|
|
type dataReader struct {
|
|
r io.Reader
|
|
|
|
limited bool
|
|
n int64 // Maximum bytes remaining
|
|
}
|
|
|
|
func newDataReader(c *Conn) io.Reader {
|
|
dr := &dataReader{
|
|
r: c.text.DotReader(),
|
|
}
|
|
|
|
if c.server.MaxMessageBytes > 0 {
|
|
dr.limited = true
|
|
dr.n = int64(c.server.MaxMessageBytes)
|
|
}
|
|
|
|
return dr
|
|
}
|
|
|
|
func (r *dataReader) Read(b []byte) (n int, err error) {
|
|
if r.limited {
|
|
if r.n <= 0 {
|
|
return 0, ErrDataTooLarge
|
|
}
|
|
if int64(len(b)) > r.n {
|
|
b = b[0:r.n]
|
|
}
|
|
}
|
|
|
|
n, err = r.r.Read(b)
|
|
|
|
if r.limited {
|
|
r.n -= int64(n)
|
|
}
|
|
return
|
|
}
|