mailx

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2024 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package mailx implements precise syntactic RFC 822 message manipulation.

Package-wide plans: + TODO NEVER return io.EOF, change to io.ErrUnexpectedEOF + TODO change mailx.EOH to io.EOF

Index

Constants

View Source
const (
	MaxLineLength     = 80 // including CRLF
	MaxAtomLength     = 75
	MaxLineOverlength = 1000 // including CRLF
)
View Source
const CRLF = "\r\n"
View Source
const MessageIdEntropy = 24
View Source
const TimeLayout string = time.RFC1123Z

This is one of the many formats mail.ParseDate attempts to parse; it also appears to be the most accurate date format specified for mail. time.RFC1123Z == "Mon, 02 Jan 2006 15:04:05 -0700"

Variables

View Source
var EOH = fmt.Errorf("%w: end of header", io.EOF)
View Source
var ErrMalformedField = errors.New("malformed field")
View Source
var ErrNotCRLFTerminated = errors.New("not CRLF-terminated")

Functions

func CopyMIMEHeader

func CopyMIMEHeader(header textproto.MIMEHeader) textproto.MIMEHeader

func Fields2Mimeheader

func Fields2Mimeheader(fields []Field) textproto.MIMEHeader

func JoinFields

func JoinFields(fn string, fields []Field) string

func SplitHeaderPartial

func SplitHeaderPartial(r io.Reader, fieldNames ...string) (textproto.MIMEHeader, error)

SplitHeaderPartial interprets r as an RFC 822 message, reads the entire header and returns a textproto.MIMEHeader containing the fields whose name matches one of fieldNames. Only these fields are decoded.

Types

type Field

type Field struct {
	Name, Body string
}

Field.Name MAY NOT be in textproto.CanonicalMIMEHeaderKey form. It may also not be RFC-822-valid. See Field.CanonicalName() for both.

func Isolator

func Isolator(fn string) Field

func Mimeheader2Fields

func Mimeheader2Fields(h textproto.MIMEHeader) []Field

func Split

func Split(r io.Reader) ([]Field, io.Reader, error)

Split is a convenience wrapper around NewSplitter. r must read a syntactically valid RFC 822 message (NOTE: some field body encodings may not be supported). Split MUST see a CRLF line after the header. No byte is lost except the CRLF separating header from body.

func (Field) CanonicalName

func (field Field) CanonicalName() string

Field.CanonicalName returns the canoncialised fixed name.

func (Field) Encode

func (field Field) Encode() []byte

Encode encodes a Field in a way to maximise both decodability of the exact (including neighbouring whitespace) Field.Body by most mail agents as well as maximise MUA passthrough.

For a valid fieldname (nonempty, consisting of c>' '&&c!=':'&&c<='~') and a valid fieldbody (properly UTF-8-encoded), Encode is injective.

Encoded field may be folded. Encoded field includes a trailing CRLF.

The empty fieldname is encoded as "-". Invalid fieldname characters are replaced by '-'. Invalid fieldbody bytes are encoded as utf8.RuneError (there is no non-character-semantics IANA charset so encoding true data in mail field bodies is not possible in any context).

Overlong atoms (> 76 octets) or overlong lines (> 80 octets, including CRLF) may get emitted for whitespace-enclosed (counting left and right ends of string as implicit whitespace) strings of the form /<[!-~]*@[!-~]*>/ to aid in non-q-atom-compliant mail transfer agent's understanding of the message.

Guaranteed to not emit lines longer than 1000 bytes (including CRLF) if len(field.Name) <= 972 (equivalently, len(field.Name) + len(": ") + + len("=?UTF-8?Q?=FF=FF=FF=FF?=") + len("\r\n") <= 1000).

NOTE: When decoding mixed qatom/atom streams, whitespace is discarded iff it is present between two qatoms. [2023-11-13, jfrech] NOTE: An empty Q-encoded atom (e.g. "=?UTF-8?Q??=")

is invalid by RFC specifications.

[2023-11-22, jfrech] NOTE: Whitespace is kept between two atoms iff they

are not both q-atoms:
    decode("a b") = "a b",
    decode("a =?UTF-8?Q?b?=") = "a b",
    decode("=?UTF-8?Q?a?= b") = "a b",
    decode("=?UTF-8?Q?a?= =?UTF-8?Q?b?=") = "ab"

func (Field) Equal

func (field Field) Equal(other Field) bool

Equality in the /Field.CanonicalName coset.

func (Field) Is

func (field Field) Is(name string) bool

func (Field) IsZero

func (field Field) IsZero() bool

type Part

type Part struct {
	ContentType        string
	ContentDisposition string
	ContentLanguage    string

	Content []byte
}

func (*Part) Encode

func (part *Part) Encode(encoding string) ([]Field, []byte, error)

type RawField

type RawField []byte

func (RawField) CanonicalName

func (rawfield RawField) CanonicalName() string

XXX this performs no checking if the rawfield is syntactically valid

func (RawField) Decode

func (rawfield RawField) Decode() (Field, error)

Field.Name == textproto.CanonicalMIMEHeaderKey(Field.Name)

func (RawField) Is

func (rawfield RawField) Is(fh string) bool

type Splitter

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

func NewSplitter

func NewSplitter(r io.Reader) *Splitter

func (*Splitter) NextField

func (s *Splitter) NextField() (Field, error)

func (*Splitter) NextRawField

func (s *Splitter) NextRawField() (RawField, error)

func (*Splitter) Read

func (s *Splitter) Read(p []byte) (int, error)

Jump to

Keyboard shortcuts

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