simple

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 5, 2022 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package simple provides tools for basic email parsing. This primarily means splitting the header from the body, and parsing the header in full. It does not do anything special with the body.

This is primarily useful in cases where you want to work with message headers. You can read and modify these headers and roundtrip the file without making any changes to the body.

If you need to work with the parts of the body, you probably ought to consider using the MIME parser in "github.com/zostay/go-email/pkg/email/mime" instead.

Example
package main

import (
	"io/ioutil"
	"strings"

	"github.com/zostay/go-email/pkg/email/simple"
)

func main() {
	msg, err := ioutil.ReadFile("input.msg")
	if err != nil {
		panic(err)
	}

	m, err := simple.Parse(msg)
	if err != nil {
		panic(err)
	}

	if kw := m.HeaderGet("Keywords"); kw != "" {
		kws := strings.Split(kw, ",")
		for _, k := range kws {
			if strings.TrimSpace(k) == "Snuffle" {
				kw += ", Upagus"
				_ = m.HeaderSet("Keywords", kw)
				_ = ioutil.WriteFile("output.msg", m.Bytes(), 0644)
			}
		}
	}
}
Output:

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrIllegalFieldName = errors.New("field name contains illegal character")
	ErrIllegalBodyValue = errors.New("body value contains illegal character")
)

Functions

func ParseHeaderField

func ParseHeaderField(f, lb []byte) (*email.HeaderField, error)

ParseHeaderField will take a single header field, including any folded continuation lines. This will then construct a header field object.

func ParseHeaderLines

func ParseHeaderLines(m, lb []byte) ([][]byte, error)

ParseHeaderLines is used by ParseHeader and ParseHeaderLB to create a list of lines where each line represents a single field, including and folded continuation lines.

Often, mail tools (like some versions of Microsoft Outlook or Exchange *eyeroll*) will incorrectly fold a line. As such, a field line is consider the start of a field when it does not start with a space AND it contains a colon. Otherwise, we will treat it as a fold even though this is not correct according to RFC 5322.

If the header starts with text that does not appear to be a header. The start text will be skipped for header parsing. However, it will be accumulated into a BadStartError and returned with the parsed header.

func SplitHeadFromBody

func SplitHeadFromBody(m []byte) (int, []byte)

SplitHeadFromBody will detect the index of the split between the message header and the message body as well as the line break the email is using. It returns both.

Types

type BadStartError

type BadStartError struct {
	BadStart []byte // the text skipped at the start of header
}

BadStartError is returned when the header begins with junk text that does not appear to be a header. This text is preserved in the error object.

func (*BadStartError) Error

func (err *BadStartError) Error() string

Error returns the error message.

type BodySetter

type BodySetter func(*email.HeaderField, interface{}, []byte) error

BodySetter is a helper that is used to convert complex types used to set headers into strings and then set the field body value.

type Header struct {
	// SetBody is set to a BodySetter that handles string, slices and arrays of
	// bytes, and fmt.Stringer objects.
	SetBody BodySetter
	email.Header
}

Header provides a simple header interface for dealing with email headers without worrying about MIME details.

func NewHeader

func NewHeader(lb string, hs ...string) (*Header, error)

NewHeader will build a new simple header. The strings provied are alternating name/value pairs.

This will return an error if an odd number of strings is passed. It may also return an error if the given header names or body values are not limited to legal characters.

func ParseHeader

func ParseHeader(m []byte) (*Header, error)

ParseHeader will parse the given string into an email header. It assumes that the entire string given represents the header. It will assume "\n" as the line break character to use during parsing.

func ParseHeaderLB

func ParseHeaderLB(m, lb []byte) (*Header, error)

ParseHeaderLB will parse the given string into an email header using the given line break string. It will assume the entire string given represents the header to be parsed.

func (*Header) HeaderAdd

func (h *Header) HeaderAdd(n string, b interface{}) error

HeaderAdd will add a new header field with the given name and body value to the bottom of the header. Existing headers will be left alone as-is.

Returns an error if the given header name or body value is not legal.

func (*Header) HeaderAddBefore

func (h *Header) HeaderAddBefore(n string, b interface{}) error

HeaderAddBefore will add a new header field with the given name and body value to teh top of the header. Existing headers will be left alone as-is.

Returns an error if the given header name or body value is not legal.

func (*Header) HeaderAddBeforeN

func (h *Header) HeaderAddBeforeN(n string, b interface{}, ix int) error

HeaderAddBeforeN will add a new header field before the (ix+1)th instance of the given header. If there is any header field with the given name, but not a (ix+1)th header, it will be added before the lsat one.

If ix is negative, then it will be added before the (-ix)th header field from the end. If there is at least one header field with the given name, but no (-ix)th header, it will be added before the first one.

If no header field with the given name is present, the new header field will be added to the top of the header.

If the given field name or body value is not legal, an error will be returned and the header will not be modified.

func (*Header) HeaderAddN

func (h *Header) HeaderAddN(n string, b interface{}, ix int) error

HeaderAddN will add a new header field after the (ix+1)th instance of the given header. If there is any header field with the given name, but not a (ix+1)th header, it will be added after the last one.

If ix is negative, then it will be added after the (-ix)th header field from the end. If there is at least one header field with the given name, but no (-ix)th header, it will be added after the first one.

If no header field with the given name is present, the new header field will be added to the bottom of the header.

If the given field name or body value is not legal, an error will be returned and the header will not be modified.

func (*Header) HeaderDelete

func (h *Header) HeaderDelete(n string, ix int) error

HeaderDelete will remove the (ix+1)th header matching the given name. Returns an error if no such header exists.

func (*Header) HeaderDeleteAll

func (h *Header) HeaderDeleteAll(n string)

HeaderDeleteAll will remove all headers matching the given name.

func (*Header) HeaderGet

func (h *Header) HeaderGet(n string) string

HeaderGet will find the first header field with a matching name and return the body value. It will return an empty string if no such header is present.

func (*Header) HeaderGetAll

func (h *Header) HeaderGetAll(n string) []string

HeaderGetAll will find all header fields with a matching name and return a list of body values. Returns nil if no matching headers are present.

func (*Header) HeaderGetN

func (h *Header) HeaderGetN(n string, ix int) (string, error)

HeaderGetN will find the (ix+1)th header field with a matching name and return the body value. It will return an empty string with an error if no such header is present.

If ix is negative, it will return the (-ix)th body value from the end.

func (*Header) HeaderNames

func (h *Header) HeaderNames() []string

HeaderNames will return the unique header names found in the mail header.

func (*Header) HeaderRename

func (h *Header) HeaderRename(oldName, newName string) error

HeaderRename will find the first header with a matching name and give it a new name.

Returns an error if that name is not legal or if no header with the given name is found.

func (*Header) HeaderRenameAll

func (h *Header) HeaderRenameAll(oldName, newName string) error

HeaderRenameAll will rename all headers with the first name to have the name given second. If no headers with the given name are found, this method does nothing.

Returns an error if the name is not legal of if no header wwith the given name is found.

func (*Header) HeaderRenameN

func (h *Header) HeaderRenameN(oldName, newName string, ix int) error

HeaderRenameN will find the (ix+1)th from the top or the (-ix)th from the bottom and give it a new name.

Returns an error if that name is not legal or if no header with the given name is found.

func (*Header) HeaderSet

func (h *Header) HeaderSet(n string, b interface{}) error

HeaderSet will find the first header with a matching name and replace it with the given body. If no header by that name is set, it will add a new header with that name and body.

func (*Header) HeaderSetAll

func (h *Header) HeaderSetAll(n string, bs ...interface{}) error

HeaderSetAll does a full header replacement. This performs a number of combined operations.

1. If no body values are given, this is equivalent to HeaderDeleteAll.

  1. If some body values are given and there are some headers already present. This is equivalent to calling HeaderSet for each of those values.

  2. If there are fewer body values than headers already present, the remaining headers will be deleted.

  3. If there are more body values than headers already present, this is equivalent to calling HeaderAdd for each of those headers.

Basically, it's going to make sure all the given headers are set and will start by changing the ones already in place, removing any additional ones that aren't updated, and adding new ones if necessary.

If the operation is successful, it returns nil. If there is an error, then the object will be unchanged and an error returned.

func (*Header) HeaderSetN

func (h *Header) HeaderSetN(n string, b interface{}, ix int) error

HeaderSetN will find the (ix+1)th header matching the given name and replace the body value with the new value given.

If ix is negative, it will replace the body value of the (-ix)th value from the end.

If no header with that number is available, no change will be made and an error will be returned.

type HeaderParseError

type HeaderParseError struct {
	Errs []error // The accumulated parse errors
}

HeaderParseError is returned when an error occurs during parse. This may include multiple errors. These errors will be accumulated in this error.

func (*HeaderParseError) Error

func (err *HeaderParseError) Error() string

Error returns all the errors that occurred during header parsing.

type Message

type Message struct {
	Header
	email.Body
}

func NewMessage

func NewMessage(h *Header, body []byte) *Message

NewMessage builds a new simple email message from the given header and body.

func Parse

func Parse(m []byte) (*Message, error)

Parse will turn the given string into an email message.

func (*Message) Bytes

func (m *Message) Bytes() []byte

Bytes returns the email message as a slice of bytes.

func (*Message) String

func (m *Message) String() string

String returns the email message as a string.

Jump to

Keyboard shortcuts

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