field

package
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2023 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package field provides low-level functions and types for working with individual header fields. The primary tool for this is Field. This encapsulates a field twice. Once in a decoded, convenient human-readable form and (optionally) a second raw form, which is the fully encoded form. When headers are parsed, the original is preserved, but the field name and value will provide clean decoded values as much as possible.

This package also provides the tools for folding and unfolding header fields and dealing with message line breaks.

The ParseLines() function of this package is able to break up the lines of a header into individual header field lines.

Given a parsed header field line, the Parse() function will return a parsed and decoded original field that should safely round-trip, if not modified. Parsing is quite liberal and will accept and correctly parse many email messages that can be generated by well-known software vendors who routinely violated RFCs when generating messages.

Index

Constants

View Source
const (
	DefaultFoldIndent          = " "  // indent placed before folded lines
	DefaultPreferredFoldLength = 80   // we prefer headers and 7bit/8bit bodies lines shorter than this
	DefaultForcedFoldLength    = 1000 // we forceably break headers and 7bit/8bit bodies lines longer than this

	DoNotFold = -1 // we prefer not to fold at all
)

Variables

View Source
var (
	// CharsetEncoder is the Encoder used for outputting unicode strings as
	// bytes in the output format. You may replace this with a custom encoder if
	// you like or to make use of an encoder that is able to handle a wide
	// variety of encodings, you can import the encoding package:
	//  import _ "github.com/zostay/go-email/pkg/encoding"
	CharsetEncoder Encoder = DefaultCharsetEncoder

	// CharsetDecoder is the Decoder used for transforming input characters into
	// unicode for use in the decoded fields of MIME messages. You may replace
	// this with a customer decoder you prefer or to make use of a decoder that
	// supports a broad range of encodings, you can import the encoding package:
	//  import _ "github.com/zostay/go-email/pkg/encoding"
	CharsetDecoder Decoder = DefaultCharsetDecoder
)
View Source
var (
	// DefaultFoldEncoding creates a new FoldEncoding using default settings. This
	// is the recommended way to create a FoldEncoding.
	DefaultFoldEncoding = &FoldEncoding{
		DefaultFoldIndent,
		DefaultPreferredFoldLength,
		DefaultForcedFoldLength,
	}

	// DoNotFoldEncoding is a FoldEncoding that doesn't perform folding.
	DoNotFoldEncoding = &FoldEncoding{
		DefaultFoldIndent,
		DoNotFold,
		DoNotFold,
	}
)
View Source
var (
	// ErrFoldIndentSpace is returned by NewFoldEncoding when a non-space/non-tab
	// character is put in the foldIndent setting.
	ErrFoldIndentSpace = errors.New("fold indent may only contains spaces and tabs")

	// ErrFoldIndentTooShort is returned by NewFoldEncoding when the foldIndent
	// is empty.
	ErrFoldIndentTooShort = errors.New("fold indent must contain at least one space or tab")

	// ErrFoldIndentTooLong is returned by NewFoldEncoding when the foldIndent
	// setting is equal to or longer than the preferredFoldLength.
	ErrFoldIndentTooLong = errors.New("fold indent must be shorter than the preferred fold length")

	// ErrFoldLengthTooLong is returned by NewFoldEncoding when the
	// preferredFoldLength is longer than the forcedFoldLength.
	ErrFoldLengthTooLong = errors.New("preferred fold length must be no longer than the forced fold length")

	// ErrFoldLengthTooShort is returned by NewFoldEncoding when the
	// forcedFoldLength is shorter than 3 bytes long.
	ErrFoldLengthTooShort = errors.New("preferred fold length and forced fold length cannot be too short")

	// ErrDoNotFold is returned by NewFoldEncoding when the preferredFoldLength
	// or forcedFoldLength are set to DoNotFold (-1), but both are not set that
	// way. You must set both to DoNotFold to prevent folding or neither to
	// DoNotFold.
	ErrDoNotFold = errors.New("preferred fold length and forced fold length must both be -1 if either are -1")
)

Functions

func CharsetDecoderToCharsetReader

func CharsetDecoderToCharsetReader(decode func(string, []byte) (string, error)) func(string, io.Reader) (io.Reader, error)

CharsetDecoderToCharsetReader transforms a CharsetDecoder defined here into the interface used by mime.WordDecoder.

func Decode

func Decode(body string) (string, error)

Decode transforms a single header field body and looks for MIME word encoded field values. When they are found, these are decoded into native unicode.

func DefaultCharsetDecoder

func DefaultCharsetDecoder(charset string, b []byte) (string, error)

DefaultCharsetDecoder is the default decoder. It is able to handle us-ascii, iso-8859-1 (a.k.a. latin1), and utf-8 only. Anything else will result in an error.

When us-ascii is input, any NUL or 8-bit character (i.e., bytes greater than 0x7f) will be translated into unicode.ReplacementChar.

When utf-8 is input, the bytes will be read in and transformed into runes such that only valid unicode bytes will be permitted in. Errors will be brought in as unicode.ReplacementChar.

When iso-8859-1/latin1 is input, the input is left along as-is.

func DefaultCharsetEncoder

func DefaultCharsetEncoder(charset, s string) ([]byte, error)

DefaultCharsetEncoder is the default encoder. It is able to handle us-ascii and utf-8 only. Anything else will result in an error.

When outputting us-ascii, ios-8859-1 (a.k.a. latin1), any utf-8 character present that does not fit in us-ascii will be replaced with "\x1a", which is the ASCII SUB character.

func Encode

func Encode(body string) string

Encode transforms a single header field body by looking for any characters allowed for header encoding and turning them into encode body values using word encoder. It will always output b-type (Base-64) encoding using UTF-8 as the character set.

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 Base

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

Base implements an email.Field with a baseline implementation that does not implement folding. The body is only capable of holding opaque values stored as strings.

func (*Base) Body

func (f *Base) Body() string

Body returns the value of the header field as a string.

func (*Base) Bytes

func (f *Base) Bytes() []byte

Bytes returns the complete header field as a slice of bytes.

func (*Base) Name

func (f *Base) Name() string

Name returns the name of the header field.

func (*Base) SetBody

func (f *Base) SetBody(body string)

SetBody updates the body fo the header field.

func (*Base) SetName

func (f *Base) SetName(name string)

SetName updates the name of the header field.

func (*Base) String

func (f *Base) String() string

String returns the complete header field as a string.

type Break

type Break []byte

Break is basically identical to header.Break, but with a focus on bytes.

type Decoder

type Decoder func(charset string, b []byte) (string, error)

Decoder represents the character decoding function used by the mime package for transforming parsed data supplied in arbitrary text encodings. This will be decoded into native unicode.

The decoder should only permit a valid transformation from the source format into unicode. Any byte present in the input that is invalid for the source character encoding should be replaced with the unicode.ReplacementChar.

If the source charset is not supported, bytes should be returned as nil and an error should be returned.

type Encoder

type Encoder func(charset, s string) ([]byte, error)

Encoder represents the character encoding function used by the mime package to transform data supplied in native unicode format to be written out in the character encoding indicated by the charset of the message.

The encoder should attempt to clean up and only output text that is valid in the target encoding. If no encoding is present, then us-ascii should be assumed.

If the target charset is not supported, bytes should be returned as nil and an error should be returned.

type Field

type Field struct {
	Base
	*Raw
}

Field provides a low-level interface to manage a single email header field. Every Field contains name and body values from the embedded Base object. In addition to this base object, it may also contain an even lower-level representation in Raw. This allows the object to maintain a decoded logical string value as well as a fully encoded raw value.

The Name() and Body() methods will always surface the Base field.

The Strings() and Bytes() methods will always work on the Raw field if present, but fallback to using the Base field if not present.

The SetName() and SetBody() methods will always update Base and result in Raw being cleared, if present. The SetRaw() method is provided to create a new Raw value after such an edit.

Both Raw and Base are exposed if something more low-level or nuanced is needed.

func New

func New(name, body string) *Field

New constructs a new field with no original value.

func Parse

func Parse(f Line, lb []byte) *Field

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

func (*Field) Body

func (f *Field) Body() string

Body returns the Base.Body().

func (*Field) Bytes

func (f *Field) Bytes() []byte

Bytes returns the Raw.Bytes() if Raw is not nil. It returns the Base.Bytes() otherwise.

func (*Field) Clone added in v2.0.3

func (f *Field) Clone() *Field

Clone makes a deep copy of the field and returns it.

func (*Field) Name

func (f *Field) Name() string

Name returns the Base.Name().

func (*Field) SetBody

func (f *Field) SetBody(b string)

SetBody sets the body of the field by calling Base.SetBody(). Calling this will also result in Raw being set to nil.

func (*Field) SetName

func (f *Field) SetName(n string)

SetName sets the name of the field by calling Base.SetName(). Calling this will also result in Raw being set to nil.

func (*Field) SetRaw

func (f *Field) SetRaw(o []byte)

SetRaw replaces Raw with a new value. The value will be run through field.Parse(). If there's a problem parsing the field, this method will fail with an error.

func (*Field) String

func (f *Field) String() string

String returns the Raw.String() if Raw is not nil. It returns the Base.String() otherwise.

type FoldEncoding

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

FoldEncoding provides the tooling for folding email message headers.

func NewFoldEncoding

func NewFoldEncoding(
	foldIndent string,
	preferredFoldLength,
	forcedFoldLength int,
) (*FoldEncoding, error)

NewFoldEncoding creates a new FoldEncoding with the given settings. The foldIndent must be a string, filled with one or more space or tab characters, and it must be shorter than the preferredFoldLength. The preferredFoldLength must be equal to or less than forcedFoldLength. if any of the given inputs do not meet these requirements, an error will be returned.

The fold encoding does not do anything special to ensure that no folding occurs before the colon even though that would be incorrect. It relies on the assumption that the fold lengths chosen will be wider than the longest field name. That should be enough to guarantee that field names never get folded.

func (*FoldEncoding) Fold

func (vf *FoldEncoding) Fold(out io.Writer, f []byte, lb Break) (int64, error)

Fold will take an unfolded or perhaps partially folded value from an email and fold it. It will make sure that every fold line is properly indented, try to break lines on appropriate spaces, and force long lines to be broken before the maximum line length.

Writes the folded output to the given io.Writer and returns the number of bytes written and returns an error if there's an error writing the data.

func (*FoldEncoding) Unfold

func (vf *FoldEncoding) Unfold(f []byte) []byte

Unfold will take a folded header line from an email and unfold it for reading. This gives you the proper header body value.

type Line

type Line []byte

Line represents the unparsed content for a complete header field line.

type Lines

type Lines []Line

Lines represents the unparsed content for zero or more header field lines.

func ParseLines

func ParseLines(m, lb []byte) (Lines, error)

ParseLines splits the given input into lines according to the rules we use to determine how to break header fields up inside a header. The input bytes are expected to include only the header. It will parse the whole input as if all of it belongs to the header. It returns the input as Lines, which are [][]byte, ready to feed into the header field parser.

This method does not follow RFC 5322 precisely. It will accept input that would be rejected by the specification as part of the effort this module library makes in attempting to be liberal in what it accepts, but strict in what it generates.

If the first line (or lines) of input start with spaces or contain no colons, these lines will be skipped in the Lines returned. However, a BadStartError will be returned.

From then on, this will start a new field on any line that does not start with a space and contains a colon. After the first such line is encountered, any line after that will be considered a continuation if it starts with a space or does not contain a colon. (And for the purposes of this method's documentation, we consider a space character or tab character to be a space, but all other characters are treated as non-spaces. This is in keeping with RFC 5322.)

type Raw

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

Raw is a email.Field implementation that presents the parsed Raw value. Objects of this type are immutable.

func (*Raw) Body

func (f *Raw) Body() string

Body returns the body part of the Raw as bytes. Please note that the value returned may be folded.

func (*Raw) Bytes

func (f *Raw) Bytes() []byte

Bytes returns the Raw.

func (*Raw) Name

func (f *Raw) Name() string

Name returns the name part of the Raw. Please note that the value returned may be foleded.

func (*Raw) String

func (f *Raw) String() string

String returns the Raw as a string.

Jump to

Keyboard shortcuts

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