email

package
v0.39.0 Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2022 License: BSD-3-Clause Imports: 19 Imported by: 1

Documentation

Overview

Package email provide a library for working with Internet Message Format as defined by RFC 5322.

Index

Examples

Constants

View Source
const (
	DateFormat = "Mon, 2 Jan 2006 15:04:05 -0700"
)

Variables

View Source
var (
	// Parameter for Text Media Type, RFC 2046 section 4.1.
	ParamNameCharset = []byte("charset")

	// Parameters for "application/octet-stream", RFC 2046 section 4.5.1.
	ParamNameType    = []byte("type")
	ParamNamePadding = []byte("padding")

	// Parameter for "multipart", RFC 2046 section 5.1.
	ParamNameBoundary = []byte("boundary")

	// PArameters for "mulitpart/partial", RFC 2046 section 5.2.2.
	ParamNameID     = []byte("id")
	ParamNameNumber = []byte("number")
	ParamNameTotal  = []byte("total")
)

List of known parameter name in header field's value.

View Source
var Epoch = func() int64 {
	return time.Now().Unix()
}

Epoch return the UNIX timestamp in seconds.

This variable is exported to allow function that use time and math/rand can be tested with fixed, predictable value.

Functions

func IsValidLocal

func IsValidLocal(local []byte) bool

IsValidLocal will return true if local part contains valid characters. Local part must,

  • start or end without dot character,
  • contains only printable US-ASCII characters, excluding special characters
  • no multiple sequence of dots.

List of special characters,

"(" / ")" / "<" / ">" / "[" / "]" / ":" / ";" / "@" / "\" / "," / "." / DQUOTE

Types

type Body

type Body struct {
	// Parts contains one or more message body.
	Parts []*MIME
	// contains filtered or unexported fields
}

Body represent single or multiple message body parts.

func ParseBody

func ParseBody(raw, boundary []byte) (body *Body, rest []byte, err error)

ParseBody parse the the raw message's body using boundary.

func (*Body) Add added in v0.16.0

func (body *Body) Add(mime *MIME)

Add new MIME part to the body.

func (*Body) Relaxed

func (body *Body) Relaxed() (out []byte)

Relaxed canonicalize the original body with "relaxed" algorithm as defined in RFC 6376 section 3.4.4. It remove all trailing whitespaces, reduce sequence of whitespaces inside line into single space, and remove all empty line at the end of body. If body is not empty and not end with CRLF, a CRLF is added.

This function is expensive for message with large body, its better if we call it once and store it somewhere.

func (*Body) Set added in v0.35.0

func (body *Body) Set(mime *MIME)

Set replace the MIME content-type with new one, if its exist; otherwise append it.

func (*Body) Simple

func (body *Body) Simple() (out []byte)

Simple canonicalize the original body with "simple" algorithm as defined in RFC 6376 section 3.4.3. Basically, it converts "*CRLF" at the end of body to a single CRLF. If no message body or no trailing CRLF, a CRLF is added.

func (*Body) String

func (body *Body) String() string

String return text representation of Body.

type ContentType

type ContentType struct {
	Top    []byte
	Sub    []byte
	Params []Param
}

ContentType represent MIME header "Content-Type" field.

func ParseContentType

func ParseContentType(raw []byte) (ct *ContentType, err error)

ParseContentType parse content type from raw bytes.

func (*ContentType) GetParamValue

func (ct *ContentType) GetParamValue(name []byte) []byte

GetParamValue return parameter value related to specific name.

func (*ContentType) SetBoundary added in v0.16.0

func (ct *ContentType) SetBoundary(boundary []byte)

SetBoundary set the parameter boundary in content-type header's value.

func (*ContentType) String

func (ct *ContentType) String() string

String return text representation of content type with its parameters.

type Field

type Field struct {
	// ContentType contains unpacked value of field with Name
	// "Content-Type" or nil if still packed.
	ContentType *ContentType

	// Name contains "relaxed" canonicalization of field name.
	Name []byte
	// Value contains "relaxed" canonicalization of field value.
	Value []byte

	// Type of field, the numeric representation of field name.
	Type FieldType
	// contains filtered or unexported fields
}

Field represent field name and value in header.

func ParseField

func ParseField(raw []byte) (field *Field, rest []byte, err error)

ParseField create and initialize Field by parsing a single line message header field from raw input.

If raw input contains multiple lines, the rest of lines will be returned.

On error, it will return nil Field, and rest will contains the beginning of invalid input.

func (*Field) Relaxed

func (field *Field) Relaxed() (out []byte)

Relaxed return the relaxed canonicalization of field name and value.

func (*Field) Simple

func (field *Field) Simple() (out []byte)

Simple return the simple canonicalization of field name and value.

type FieldType

type FieldType int

FieldType represent numerical identification of field name.

const (
	FieldTypeOptional FieldType = iota
	// The origination date field, RFC 5322 section 3.6.1.
	FieldTypeDate
	// Originator fields, RFC 5322 section 3.6.2.
	FieldTypeFrom
	FieldTypeSender
	FieldTypeReplyTo
	// Destination fields, RFC 5322 section 3.6.3.
	FieldTypeTo
	FieldTypeCC
	FieldTypeBCC
	// Identitication fields, RFC 5322 section 3.6.4.
	FieldTypeMessageID
	FieldTypeInReplyTo
	FieldTypeReferences
	// Informational fields, RFC 5322 section 3.6.5.
	FieldTypeSubject
	FieldTypeComments
	FieldTypeKeywords
	// Resent fields, RFC 5322 section 3.6.6.
	FieldTypeResentDate
	FieldTypeResentFrom
	FieldTypeResentSender
	FieldTypeResentTo
	FieldTypeResentCC
	FieldTypeResentBCC
	FieldTypeResentMessageID
	// Trace fields, RFC 5322 section 3.6.7.
	FieldTypeReturnPath
	FieldTypeReceived

	// MIME header fields, RFC 2045
	FieldTypeMIMEVersion
	FieldTypeContentType
	FieldTypeContentTransferEncoding
	FieldTypeContentID
	FieldTypeContentDescription

	// DKIM Signature, RFC 6376.
	FieldTypeDKIMSignature
)

List of valid email envelope headers.

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

Header represent list of fields in message.

func ParseHeader

func ParseHeader(raw []byte) (hdr *Header, rest []byte, err error)

ParseHeader parse the raw header from top to bottom.

Raw header that start with CRLF indicate an empty header. In this case, it will return nil Header, indicating that no header was parsed, and the leading CRLF is removed on returned "rest".

The raw header may end with optional CRLF, an empty line that separate header from body of message.

On success it will return the rest of raw input (possible message's body) without leading CRLF.

func (*Header) Boundary

func (hdr *Header) Boundary() []byte

Boundary return the message body boundary defined in Content-Type. If no field Content-Type or no boundary it will return nil.

func (*Header) ContentType

func (hdr *Header) ContentType() *ContentType

ContentType return the unpacked value of field "Content-Type", or nil if no field Content-Type exist or there is an error when unpacking.

func (*Header) DKIM

func (hdr *Header) DKIM(n int) (dkimHeader *Header)

DKIM return sub-header of the "n" DKIM-Signature, start from the top. If no DKIM-Signature found it will return nil.

For example, to get the second DKIM-Signature from the top, call it with "n=2", but if no second DKIM-Signature it will return nil.

func (*Header) Filter

func (hdr *Header) Filter(ft FieldType) (fields []*Field)

Filter specific field type. If multiple fields type exist it will return all of them.

func (*Header) PushTop

func (hdr *Header) PushTop(f *Field)

PushTop put the field at the top of header.

func (*Header) Relaxed

func (hdr *Header) Relaxed() []byte

Relaxed canonicalize the header using "relaxed" algorithm and return it.

func (*Header) Set added in v0.16.0

func (hdr *Header) Set(ft FieldType, value []byte) (err error)

Set the header's value based on specific type. If no field type found, the new field will be added to the list.

func (*Header) SetMultipart added in v0.16.0

func (hdr *Header) SetMultipart() (err error)

SetMultipart make the header a multipart bodies with boundary.

func (*Header) Simple

func (hdr *Header) Simple() []byte

Simple canonicalize the header using "simple" algorithm.

func (*Header) WriteTo added in v0.35.0

func (hdr *Header) WriteTo(w io.Writer) (n int, err error)

WriteTo the header into w. The header does not end with an empty line to allow multiple Header written multiple times.

type MIME

type MIME struct {
	Header  *Header
	Content []byte
	// contains filtered or unexported fields
}

MIME represent part of message body with their header and content.

func ParseBodyPart

func ParseBodyPart(raw, boundary []byte) (mime *MIME, rest []byte, err error)

ParseBodyPart parse one body part using boundary and return the rest of body.

func (*MIME) String

func (mime *MIME) String() string

String return string representation of MIME object.

func (*MIME) WriteTo added in v0.35.0

func (mime *MIME) WriteTo(w io.Writer) (n int, err error)

WriteTo write the MIME header and content into Writer w.

type Mailbox

type Mailbox struct {
	Address string // address contains the combination of "local@domain"
	Name    []byte
	Local   []byte
	Domain  []byte
	// contains filtered or unexported fields
}

Mailbox represent an invidual mailbox.

func ParseMailbox added in v0.16.0

func ParseMailbox(raw []byte) (mbox *Mailbox)

ParseMailbox parse the raw address(es) and return the first mailbox in the list. If the raw parameter is empty or no mailbox present or mailbox format is invalid, it will return nil.

Example
fmt.Printf("%v\n", ParseMailbox([]byte("local")))
fmt.Printf("%v\n", ParseMailbox([]byte("Name <domain>")))
fmt.Printf("%v\n", ParseMailbox([]byte("local@domain")))
fmt.Printf("%v\n", ParseMailbox([]byte("Name <local@domain>")))
Output:

<nil>
Name <@domain>
<local@domain>
Name <local@domain>

func ParseMailboxes added in v0.16.0

func ParseMailboxes(raw []byte) (mboxes []*Mailbox, err error)

ParseMailboxes parse raw address into single or multiple mailboxes. Raw address can be a group of address, list of mailbox, or single mailbox.

A group of address have the following syntax,

DisplayName ":" mailbox-list ";" [comment]

List of mailbox (mailbox-list) have following syntax,

mailbox *("," mailbox)

A single mailbox have following syntax,

[DisplayName] ["<"] local "@" domain [">"]

The angle bracket is optional, but both must be provided.

DisplayName, local, and domain can have comment before and/or after it,

[comment] text [comment]

A comment have the following syntax,

"(" text [comment] ")"

func (*Mailbox) MarshalJSON added in v0.16.0

func (mbox *Mailbox) MarshalJSON() (b []byte, err error)

func (*Mailbox) String

func (mbox *Mailbox) String() string

String return the text representation of mailbox.

func (*Mailbox) UnmarshalJSON added in v0.16.0

func (mbox *Mailbox) UnmarshalJSON(b []byte) (err error)

type Message

type Message struct {
	DKIMSignature *dkim.Signature

	Header Header
	Body   Body
	// contains filtered or unexported fields
}

Message represent an unpacked internet message format.

func NewMultipart added in v0.16.0

func NewMultipart(from, to, subject, bodyText, bodyHTML []byte) (
	msg *Message, err error,
)

NewMultipart create multipart email message with text and HTML bodies.

func ParseFile

func ParseFile(inFile string) (msg *Message, rest []byte, err error)

ParseFile parse message from file.

func ParseMessage

func ParseMessage(raw []byte) (msg *Message, rest []byte, err error)

ParseMessage parse the raw message header and body.

func (*Message) AddCC added in v0.35.0

func (msg *Message) AddCC(mailboxes string) (err error)

AddCC add one or more recipients to the message header CC.

func (*Message) AddTo added in v0.35.0

func (msg *Message) AddTo(mailboxes string) (err error)

AddTo add one or more recipients to the mesage header To.

func (*Message) CanonBody

func (msg *Message) CanonBody() (body []byte)

CanonBody return the canonical representation of Message.

func (*Message) CanonHeader

func (msg *Message) CanonHeader(subHeader *Header, dkimField *Field) []byte

CanonHeader generate the canonicalization of sub-header and DKIM-Signature field.

func (*Message) DKIMSign

func (msg *Message) DKIMSign(pk *rsa.PrivateKey, sig *dkim.Signature) (err error)

DKIMSign sign the message using the private key and signature. The only required fields in signature is SDID and Selector, any other required fields that are empty will be initialized with default values.

Upon calling this function, any field values in header and body MUST be already encoded.

func (*Message) DKIMVerify

func (msg *Message) DKIMVerify() (*dkim.Status, error)

DKIMVerify verify the message signature using DKIM.

func (*Message) Pack added in v0.16.0

func (msg *Message) Pack() (out []byte, err error)

Pack the message for sending.

This method will set the Date header if its not exist, using the local time; and the message-id header if its not exist using the following format:

<epoch>.<random-8-chars>@<local-hostname>

The message content type is automatically set based on the Body parts. If the Body only contain text part, the generated content-type will be set to text/plain. If the Body only contain HTML part, the generated content-type will be set to text/html. If both the text and HTML parts exist, the generated content-type will be set to multipart/alternative.

func (*Message) SetBodyHtml added in v0.35.0

func (msg *Message) SetBodyHtml(content []byte) (err error)

SetBodyHtml set or replace the message's body HTML content.

func (*Message) SetBodyText added in v0.35.0

func (msg *Message) SetBodyText(content []byte) (err error)

SetBodyText set or replace the message body text content.

func (*Message) SetCC added in v0.35.0

func (msg *Message) SetCC(mailboxes string) (err error)

SetCC set or replace the message header CC with one or more mailboxes. See AddCC to add another recipient to the CC header.

func (*Message) SetFrom added in v0.35.0

func (msg *Message) SetFrom(mailbox string) (err error)

SetFrom set or replace the message header From with mailbox. If the mailbox parameter is empty, nothing will changes.

func (*Message) SetID added in v0.35.0

func (msg *Message) SetID(id string)

SetID set or replace the message-id header to id. If the id is empty, nothing will changes.

func (*Message) SetSubject added in v0.35.0

func (msg *Message) SetSubject(subject string)

SetSubject set or replace the subject. It will do nothing if the subject is empty.

func (*Message) SetTo added in v0.35.0

func (msg *Message) SetTo(mailboxes string) (err error)

SetTo set or replace the message header To with one or more mailboxes. See AddTo to add another recipient to the To header.

func (*Message) String

func (msg *Message) String() string

String return the text representation of Message object.

type Param

type Param struct {
	Key    []byte
	Value  []byte
	Quoted bool // Quoted is true if value is contains special characters.
}

Param represent a key-value in slice of bytes.

Directories

Path Synopsis
Package dkim provide a library to parse and create DKIM-Signature header field value, as defined in RFC 6376, DomainKeys Identified Mail (DKIM) Signatures.
Package dkim provide a library to parse and create DKIM-Signature header field value, as defined in RFC 6376, DomainKeys Identified Mail (DKIM) Signatures.
Package maildir provide a library to manage email using maildir format.
Package maildir provide a library to manage email using maildir format.

Jump to

Keyboard shortcuts

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