imap

package module
v0.0.0-...-316373f Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2022 License: MIT Imports: 17 Imported by: 0

README

go-imap

godocs.io builds.sr.ht status

An IMAP4rev1 library written in Go. It can be used to build a client and/or a server.

Usage

Client godocs.io
package main

import (
	"log"

	"github.com/iampsl/go-imap/client"
	"github.com/iampsl/go-imap"
)

func main() {
	log.Println("Connecting to server...")

	// Connect to server
	c, err := client.DialTLS("mail.example.org:993", nil)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Connected")

	// Don't forget to logout
	defer c.Logout()

	// Login
	if err := c.Login("username", "password"); err != nil {
		log.Fatal(err)
	}
	log.Println("Logged in")

	// List mailboxes
	mailboxes := make(chan *imap.MailboxInfo, 10)
	done := make(chan error, 1)
	go func () {
		done <- c.List("", "*", mailboxes)
	}()

	log.Println("Mailboxes:")
	for m := range mailboxes {
		log.Println("* " + m.Name)
	}

	if err := <-done; err != nil {
		log.Fatal(err)
	}

	// Select INBOX
	mbox, err := c.Select("INBOX", false)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Flags for INBOX:", mbox.Flags)

	// Get the last 4 messages
	from := uint32(1)
	to := mbox.Messages
	if mbox.Messages > 3 {
		// We're using unsigned integers here, only subtract if the result is > 0
		from = mbox.Messages - 3
	}
	seqset := new(imap.SeqSet)
	seqset.AddRange(from, to)

	messages := make(chan *imap.Message, 10)
	done = make(chan error, 1)
	go func() {
		done <- c.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope}, messages)
	}()

	log.Println("Last 4 messages:")
	for msg := range messages {
		log.Println("* " + msg.Envelope.Subject)
	}

	if err := <-done; err != nil {
		log.Fatal(err)
	}

	log.Println("Done!")
}
Server godocs.io
package main

import (
	"log"

	"github.com/iampsl/go-imap/server"
	"github.com/iampsl/go-imap/backend/memory"
)

func main() {
	// Create a memory backend
	be := memory.New()

	// Create a new server
	s := server.New(be)
	s.Addr = ":1143"
	// Since we will use this server for testing only, we can allow plain text
	// authentication over unencrypted connections
	s.AllowInsecureAuth = true

	log.Println("Starting IMAP server at localhost:1143")
	if err := s.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}

You can now use telnet localhost 1143 to manually connect to the server.

Extensions

Support for several IMAP extensions is included in go-imap itself. This includes:

Support for other extensions is provided via separate packages. See below.

Extending go-imap

Extensions

Commands defined in IMAP extensions are available in other packages. See the wiki to learn how to use them.

Server backends
  • go-message - parsing and formatting MIME and mail messages
  • go-msgauth - handle DKIM, DMARC and Authentication-Results
  • go-pgpmail - decrypting and encrypting mails with OpenPGP
  • go-sasl - sending and receiving SASL authentications
  • go-smtp - building SMTP clients and servers

License

MIT

Documentation

Overview

Package imap implements IMAP4rev1 (RFC 3501).

Index

Constants

View Source
const (
	// In the connecting state, the server has not yet sent a greeting and no
	// command can be issued.
	ConnectingState = 0

	// In the not authenticated state, the client MUST supply
	// authentication credentials before most commands will be
	// permitted.  This state is entered when a connection starts
	// unless the connection has been pre-authenticated.
	NotAuthenticatedState ConnState = 1 << 0

	// In the authenticated state, the client is authenticated and MUST
	// select a mailbox to access before commands that affect messages
	// will be permitted.  This state is entered when a
	// pre-authenticated connection starts, when acceptable
	// authentication credentials have been provided, after an error in
	// selecting a mailbox, or after a successful CLOSE command.
	AuthenticatedState = 1 << 1

	// In a selected state, a mailbox has been selected to access.
	// This state is entered when a mailbox has been successfully
	// selected.
	SelectedState = AuthenticatedState + 1<<2

	// In the logout state, the connection is being terminated. This
	// state can be entered as a result of a client request (via the
	// LOGOUT command) or by unilateral action on the part of either
	// the client or server.
	LogoutState = 1 << 3

	// ConnectedState is either NotAuthenticatedState, AuthenticatedState or
	// SelectedState.
	ConnectedState = NotAuthenticatedState | AuthenticatedState | SelectedState
)
View Source
const (
	// Defined in RFC 3501 as date-text on page 83.
	DateLayout = "_2-Jan-2006"
	// Defined in RFC 3501 as date-time on page 83.
	DateTimeLayout = "_2-Jan-2006 15:04:05 -0700"
)

Date and time layouts. Dovecot adds a leading zero to dates:

https://github.com/dovecot/core/blob/4fbd5c5e113078e72f29465ccc96d44955ceadc2/src/lib-imap/imap-date.c#L166

Cyrus adds a leading space to dates:

https://github.com/cyrusimap/cyrus-imapd/blob/1cb805a3bffbdf829df0964f3b802cdc917e76db/lib/times.c#L543

GMail doesn't support leading spaces in dates used in SEARCH commands.

View Source
const (
	// SetFlags replaces existing flags by new ones.
	SetFlags FlagsOp = "FLAGS"
	// AddFlags adds new flags.
	AddFlags = "+FLAGS"
	// RemoveFlags removes existing flags.
	RemoveFlags = "-FLAGS"
)
View Source
const (
	// It is not possible for any child levels of hierarchy to exist under this\
	// name; no child levels exist now and none can be created in the future.
	NoInferiorsAttr = "\\Noinferiors"
	// It is not possible to use this name as a selectable mailbox.
	NoSelectAttr = "\\Noselect"
	// The mailbox has been marked "interesting" by the server; the mailbox
	// probably contains messages that have been added since the last time the
	// mailbox was selected.
	MarkedAttr = "\\Marked"
	// The mailbox does not contain any additional messages since the last time
	// the mailbox was selected.
	UnmarkedAttr = "\\Unmarked"
)

Mailbox attributes definied in RFC 3501 section 7.2.2.

View Source
const (
	// This mailbox presents all messages in the user's message store.
	AllAttr = "\\All"
	// This mailbox is used to archive messages.
	ArchiveAttr = "\\Archive"
	// This mailbox is used to hold draft messages -- typically, messages that are
	// being composed but have not yet been sent.
	DraftsAttr = "\\Drafts"
	// This mailbox presents all messages marked in some way as "important".
	FlaggedAttr = "\\Flagged"
	// This mailbox is where messages deemed to be junk mail are held.
	JunkAttr = "\\Junk"
	// This mailbox is used to hold copies of messages that have been sent.
	SentAttr = "\\Sent"
	// This mailbox is used to hold messages that have been deleted or marked for
	// deletion.
	TrashAttr = "\\Trash"
)

Mailbox attributes defined in RFC 6154 section 2 (SPECIAL-USE extension).

View Source
const (
	// The presence of this attribute indicates that the mailbox has child
	// mailboxes.
	HasChildrenAttr = "\\HasChildren"
	// The presence of this attribute indicates that the mailbox has no child
	// mailboxes.
	HasNoChildrenAttr = "\\HasNoChildren"
)

Mailbox attributes defined in RFC 3348 (CHILDREN extension)

View Source
const (
	SeenFlag     = "\\Seen"
	AnsweredFlag = "\\Answered"
	FlaggedFlag  = "\\Flagged"
	DeletedFlag  = "\\Deleted"
	DraftFlag    = "\\Draft"
	RecentFlag   = "\\Recent"
)

System message flags, defined in RFC 3501 section 2.3.2.

View Source
const (
	// Refers to the entire part, including headers.
	EntireSpecifier PartSpecifier = ""
	// Refers to the header of the part. Must include the final CRLF delimiting
	// the header and the body.
	HeaderSpecifier = "HEADER"
	// Refers to the text body of the part, omitting the header.
	TextSpecifier = "TEXT"
	// Refers to the MIME Internet Message Body header.  Must include the final
	// CRLF delimiting the header and the body.
	MIMESpecifier = "MIME"
)

Part specifiers described in RFC 3501 page 55.

View Source
const ImportantAttr = "\\Important"

This mailbox attribute is a signal that the mailbox contains messages that are likely important to the user. This attribute is defined in RFC 8457 section 3.

View Source
const ImportantFlag = "$Important"

ImportantFlag is a message flag to signal that a message is likely important to the user. This flag is defined in RFC 8457 section 2.

View Source
const InboxName = "INBOX"

The primary mailbox, as defined in RFC 3501 section 5.1.

View Source
const TryCreateFlag = "\\*"

TryCreateFlag is a special flag in MailboxStatus.PermanentFlags indicating that it is possible to create new keywords by attempting to store those flags in the mailbox.

Variables

View Source
var CharsetReader func(charset string, r io.Reader) (io.Reader, error)

CharsetReader, if non-nil, defines a function to generate charset-conversion readers, converting from the provided charset into UTF-8. Charsets are always lower-case. utf-8 and us-ascii charsets are handled by default. One of the the CharsetReader's result values must be non-nil.

Functions

func CanonicalFlag

func CanonicalFlag(flag string) string

CanonicalFlag returns the canonical form of a flag. Flags are case-insensitive.

If the flag is defined in RFC 3501, it returns the flag with the case of the RFC. Otherwise, it returns the lowercase version of the flag.

func CanonicalMailboxName

func CanonicalMailboxName(name string) string

CanonicalMailboxName returns the canonical form of a mailbox name. Mailbox names can be case-sensitive or case-insensitive depending on the backend implementation. The special INBOX mailbox is case-insensitive.

func FormatAddressList

func FormatAddressList(addrs []*Address) interface{}

Format an address list to fields.

func FormatMailboxName

func FormatMailboxName(name string) interface{}

func FormatParamList

func FormatParamList(params map[string]string) []interface{}

func FormatStringList

func FormatStringList(list []string) (fields []interface{})

Convert a string list to a field list.

func IsParseError

func IsParseError(err error) bool

IsParseError returns true if the provided error is a parse error produced by Reader.

func NewDebugWriter

func NewDebugWriter(local, remote io.Writer) io.Writer

NewDebugWriter creates a new io.Writer that will write local network activity to local and remote network activity to remote.

func NewLockedWriter

func NewLockedWriter(w io.Writer) io.Writer

NewLockedWriter - goroutine safe writer.

func ParseNamedResp

func ParseNamedResp(resp Resp) (name string, fields []interface{}, ok bool)

ParseNamedResp attempts to parse a named data response.

func ParseNumber

func ParseNumber(f interface{}) (uint32, error)

ParseNumber parses a number.

func ParseParamList

func ParseParamList(fields []interface{}) (map[string]string, error)

func ParseString

func ParseString(f interface{}) (string, error)

ParseString parses a string, which is either a literal, a quoted string or an atom.

func ParseStringList

func ParseStringList(f interface{}) ([]string, error)

Convert a field list to a string list.

Types

type Address

type Address struct {
	// The personal name.
	PersonalName string
	// The SMTP at-domain-list (source route).
	AtDomainList string
	// The mailbox name.
	MailboxName string
	// The host name.
	HostName string
}

An address.

func ParseAddressList

func ParseAddressList(fields []interface{}) (addrs []*Address)

Parse an address list from fields.

func (*Address) Address

func (addr *Address) Address() string

Address returns the mailbox address (e.g. "foo@example.org").

func (*Address) Format

func (addr *Address) Format() []interface{}

Format an address to fields.

func (*Address) Parse

func (addr *Address) Parse(fields []interface{}) error

Parse an address from fields.

type BodyPartName

type BodyPartName struct {
	// The specifier of the requested part.
	Specifier PartSpecifier
	// The part path. Parts indexes start at 1.
	Path []int
	// If Specifier is HEADER, contains header fields that will/won't be returned,
	// depending of the value of NotFields.
	Fields []string
	// If set to true, Fields is a blacklist of fields instead of a whitelist.
	NotFields bool
}

A body part name.

func (*BodyPartName) Equal

func (part *BodyPartName) Equal(other *BodyPartName) bool

Equal checks whether two body part names are equal.

type BodySectionName

type BodySectionName struct {
	BodyPartName

	// If set to true, do not implicitly set the \Seen flag.
	Peek bool
	// The substring of the section requested. The first value is the position of
	// the first desired octet and the second value is the maximum number of
	// octets desired.
	Partial []int
	// contains filtered or unexported fields
}

A body section name. See RFC 3501 page 55.

func ParseBodySectionName

func ParseBodySectionName(s FetchItem) (*BodySectionName, error)

ParseBodySectionName parses a body section name.

func (*BodySectionName) Equal

func (section *BodySectionName) Equal(other *BodySectionName) bool

Equal checks whether two sections are equal.

func (*BodySectionName) ExtractPartial

func (section *BodySectionName) ExtractPartial(b []byte) []byte

ExtractPartial returns a subset of the specified bytes matching the partial requested in the section name.

func (*BodySectionName) FetchItem

func (section *BodySectionName) FetchItem() FetchItem

type BodyStructure

type BodyStructure struct {

	// The MIME type (e.g. "text", "image")
	MIMEType string
	// The MIME subtype (e.g. "plain", "png")
	MIMESubType string
	// The MIME parameters.
	Params map[string]string

	// The Content-Id header.
	Id string
	// The Content-Description header.
	Description string
	// The Content-Encoding header.
	Encoding string
	// The Content-Length header.
	Size uint32

	// The children parts, if multipart.
	Parts []*BodyStructure
	// The envelope, if message/rfc822.
	Envelope *Envelope
	// The body structure, if message/rfc822.
	BodyStructure *BodyStructure
	// The number of lines, if text or message/rfc822.
	Lines uint32

	// True if the body structure contains extension data.
	Extended bool

	// The Content-Disposition header field value.
	Disposition string
	// The Content-Disposition header field parameters.
	DispositionParams map[string]string
	// The Content-Language header field, if multipart.
	Language []string
	// The content URI, if multipart.
	Location []string

	// The MD5 checksum.
	MD5 string
}

A body structure. See RFC 3501 page 74.

func (*BodyStructure) Filename

func (bs *BodyStructure) Filename() (string, error)

Filename parses the body structure's filename, if it's an attachment. An empty string is returned if the filename isn't specified. An error is returned if and only if a charset error occurs, in which case the undecoded filename is returned too.

func (*BodyStructure) Format

func (bs *BodyStructure) Format() (fields []interface{})

func (*BodyStructure) Parse

func (bs *BodyStructure) Parse(fields []interface{}) error

func (*BodyStructure) Walk

Walk walks the body structure tree, calling f for each part in the tree, including bs itself. The parts are visited in DFS pre-order.

type BodyStructureWalkFunc

type BodyStructureWalkFunc func(path []int, part *BodyStructure) (walkChildren bool)

BodyStructureWalkFunc is the type of the function called for each body structure visited by BodyStructure.Walk. The path argument contains the IMAP part path (see BodyPartName).

The function should return true to visit all of the part's children or false to skip them.

type Command

type Command struct {
	// The command tag. It acts as a unique identifier for this command. If empty,
	// the command is untagged.
	Tag string
	// The command name.
	Name string
	// The command arguments.
	Arguments []interface{}
}

A command.

func (*Command) Command

func (cmd *Command) Command() *Command

Implements the Commander interface.

func (*Command) Parse

func (cmd *Command) Parse(fields []interface{}) error

Parse a command from fields.

func (*Command) WriteTo

func (cmd *Command) WriteTo(w *Writer) error

type Commander

type Commander interface {
	Command() *Command
}

A value that can be converted to a command.

type Conn

type Conn struct {
	net.Conn
	*Reader
	*Writer
	// contains filtered or unexported fields
}

An IMAP connection.

func NewConn

func NewConn(conn net.Conn, r *Reader, w *Writer) *Conn

NewConn creates a new IMAP connection.

func (*Conn) Flush

func (c *Conn) Flush() error

Flush writes any buffered data to the underlying connection.

func (*Conn) Info

func (c *Conn) Info() *ConnInfo

func (*Conn) SetDebug

func (c *Conn) SetDebug(w io.Writer)

SetDebug defines an io.Writer to which all network activity will be logged. If nil is provided, network activity will not be logged.

func (*Conn) Upgrade

func (c *Conn) Upgrade(upgrader ConnUpgrader) error

Upgrade a connection, e.g. wrap an unencrypted connection with an encrypted tunnel.

func (*Conn) Wait

func (c *Conn) Wait()

Called by reader/writer goroutines to wait for Upgrade to finish

func (*Conn) WaitReady

func (c *Conn) WaitReady()

Called by Upgrader to wait for reader/writer goroutines to be ready for upgrade.

func (*Conn) Write

func (c *Conn) Write(b []byte) (n int, err error)

Write implements io.Writer.

type ConnInfo

type ConnInfo struct {
	RemoteAddr net.Addr
	LocalAddr  net.Addr

	// nil if connection is not using TLS.
	TLS *tls.ConnectionState
}

Underlying connection state information.

type ConnState

type ConnState int

A connection state. See RFC 3501 section 3.

type ConnUpgrader

type ConnUpgrader func(conn net.Conn) (net.Conn, error)

A function that upgrades a connection.

This should only be used by libraries implementing an IMAP extension (e.g. COMPRESS).

type ContinuationReq

type ContinuationReq struct {
	// The info message sent with the continuation request.
	Info string
}

ContinuationReq is a continuation request response.

func (*ContinuationReq) WriteTo

func (r *ContinuationReq) WriteTo(w *Writer) error

type DataResp

type DataResp struct {
	// The response tag. Can be either "" for untagged responses, "+" for continuation
	// requests or a previous command's tag.
	Tag string
	// The parsed response fields.
	Fields []interface{}
}

DataResp is an IMAP response containing data.

func NewUntaggedResp

func NewUntaggedResp(fields []interface{}) *DataResp

NewUntaggedResp creates a new untagged response.

func (*DataResp) WriteTo

func (r *DataResp) WriteTo(w *Writer) error

type Date

type Date time.Time

time.Time with a specific layout.

type DateTime

type DateTime time.Time

time.Time with a specific layout.

type Envelope

type Envelope struct {
	// The message date.
	Date time.Time
	// The message subject.
	Subject string
	// The From header addresses.
	From []*Address
	// The message senders.
	Sender []*Address
	// The Reply-To header addresses.
	ReplyTo []*Address
	// The To header addresses.
	To []*Address
	// The Cc header addresses.
	Cc []*Address
	// The Bcc header addresses.
	Bcc []*Address
	// The In-Reply-To header. Contains the parent Message-Id.
	InReplyTo string
	// The Message-Id header.
	MessageId string
}

A message envelope, ie. message metadata from its headers. See RFC 3501 page 77.

func (*Envelope) Format

func (e *Envelope) Format() (fields []interface{})

Format an envelope to fields.

func (*Envelope) Parse

func (e *Envelope) Parse(fields []interface{}) error

Parse an envelope from fields.

type ErrBadSeqSet

type ErrBadSeqSet string

ErrBadSeqSet is used to report problems with the format of a sequence set value.

func (ErrBadSeqSet) Error

func (err ErrBadSeqSet) Error() string

type ErrStatusResp

type ErrStatusResp struct {
	// Response to send instead of default.
	Resp *StatusResp
}

ErrStatusResp can be returned by a server.Handler to replace the default status response. The response tag must be empty.

To suppress default response, Resp should be set to nil.

func (*ErrStatusResp) Error

func (err *ErrStatusResp) Error() string

type FetchItem

type FetchItem string

A FetchItem is a message data item that can be fetched.

const (
	// Macros
	FetchAll  FetchItem = "ALL"
	FetchFast FetchItem = "FAST"
	FetchFull FetchItem = "FULL"

	// Items
	FetchBody          FetchItem = "BODY"
	FetchBodyStructure FetchItem = "BODYSTRUCTURE"
	FetchEnvelope      FetchItem = "ENVELOPE"
	FetchFlags         FetchItem = "FLAGS"
	FetchInternalDate  FetchItem = "INTERNALDATE"
	FetchRFC822        FetchItem = "RFC822"
	FetchRFC822Header  FetchItem = "RFC822.HEADER"
	FetchRFC822Size    FetchItem = "RFC822.SIZE"
	FetchRFC822Text    FetchItem = "RFC822.TEXT"
	FetchUid           FetchItem = "UID"
)

List of items that can be fetched. See RFC 3501 section 6.4.5.

Warning: FetchBody will not return the raw message body, instead it will return a subset of FetchBodyStructure.

func (FetchItem) Expand

func (item FetchItem) Expand() []FetchItem

Expand expands the item if it's a macro.

type FlagsOp

type FlagsOp string

FlagsOp is an operation that will be applied on message flags.

func ParseFlagsOp

func ParseFlagsOp(item StoreItem) (op FlagsOp, silent bool, err error)

ParseFlagsOp parses a flags operation from StoreItem.

type Literal

type Literal interface {
	io.Reader

	// Len returns the number of bytes of the literal.
	Len() int
}

A literal, as defined in RFC 3501 section 4.3.

type LiteralLengthErr

type LiteralLengthErr struct {
	Actual   int
	Expected int
}

LiteralLengthErr is returned when the Len() of the Literal object does not match the actual length of the byte stream.

func (LiteralLengthErr) Error

func (e LiteralLengthErr) Error() string

type LockedWriter

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

func (*LockedWriter) Write

func (w *LockedWriter) Write(b []byte) (int, error)

type Logger

type Logger interface {
	Printf(format string, v ...interface{})
	Println(v ...interface{})
}

Logger is the behaviour used by server/client to report errors for accepting connections and unexpected behavior from handlers.

type MailboxInfo

type MailboxInfo struct {
	// The mailbox attributes.
	Attributes []string
	// The server's path separator.
	Delimiter string
	// The mailbox name.
	Name string
}

Basic mailbox info.

func (*MailboxInfo) Format

func (info *MailboxInfo) Format() []interface{}

Format mailbox info to fields.

func (*MailboxInfo) Match

func (info *MailboxInfo) Match(reference, pattern string) bool

Match checks if a reference and a pattern matches this mailbox name, as defined in RFC 3501 section 6.3.8.

func (*MailboxInfo) Parse

func (info *MailboxInfo) Parse(fields []interface{}) error

Parse mailbox info from fields.

type MailboxStatus

type MailboxStatus struct {
	// The mailbox name.
	Name string
	// True if the mailbox is open in read-only mode.
	ReadOnly bool
	// The mailbox items that are currently filled in. This map's values
	// should not be used directly, they must only be used by libraries
	// implementing extensions of the IMAP protocol.
	Items map[StatusItem]interface{}

	// The Items map may be accessed in different goroutines. Protect
	// concurrent writes.
	ItemsLocker sync.Mutex

	// The mailbox flags.
	Flags []string
	// The mailbox permanent flags.
	PermanentFlags []string
	// The sequence number of the first unseen message in the mailbox.
	UnseenSeqNum uint32

	// The number of messages in this mailbox.
	Messages uint32
	// The number of messages not seen since the last time the mailbox was opened.
	Recent uint32
	// The number of unread messages.
	Unseen uint32
	// The next UID.
	UidNext uint32
	// Together with a UID, it is a unique identifier for a message.
	// Must be greater than or equal to 1.
	UidValidity uint32

	// Per-mailbox limit of message size. Set only if server supports the
	// APPENDLIMIT extension.
	AppendLimit uint32
}

A mailbox status.

func NewMailboxStatus

func NewMailboxStatus(name string, items []StatusItem) *MailboxStatus

Create a new mailbox status that will contain the specified items.

func (*MailboxStatus) Format

func (status *MailboxStatus) Format() []interface{}

func (*MailboxStatus) Parse

func (status *MailboxStatus) Parse(fields []interface{}) error

type Message

type Message struct {
	// The message sequence number. It must be greater than or equal to 1.
	SeqNum uint32
	// The mailbox items that are currently filled in. This map's values
	// should not be used directly, they must only be used by libraries
	// implementing extensions of the IMAP protocol.
	Items map[FetchItem]interface{}

	// The message envelope.
	Envelope *Envelope
	// The message body structure (either BODYSTRUCTURE or BODY).
	BodyStructure *BodyStructure
	// The message flags.
	Flags []string
	// The date the message was received by the server.
	InternalDate time.Time
	// The message size.
	Size uint32
	// The message unique identifier. It must be greater than or equal to 1.
	Uid uint32
	// The message body sections.
	Body map[*BodySectionName]Literal
	// contains filtered or unexported fields
}

A message.

func NewMessage

func NewMessage(seqNum uint32, items []FetchItem) *Message

Create a new empty message that will contain the specified items.

func (*Message) Format

func (m *Message) Format() []interface{}

func (*Message) GetBody

func (m *Message) GetBody(section *BodySectionName) Literal

GetBody gets the body section with the specified name. Returns nil if it's not found.

func (*Message) Parse

func (m *Message) Parse(fields []interface{}) error

Parse a message from fields.

type Parser

type Parser interface {
	Parse(fields []interface{}) error
}

type PartSpecifier

type PartSpecifier string

A PartSpecifier specifies which parts of the MIME entity should be returned.

type RawString

type RawString string

A raw string.

type Reader

type Reader struct {
	MaxLiteralSize uint32 // The maximum literal size.
	// contains filtered or unexported fields
}

An IMAP reader.

func NewReader

func NewReader(r reader) *Reader

func NewServerReader

func NewServerReader(r reader, continues chan<- bool) *Reader

func (*Reader) ReadAtom

func (r *Reader) ReadAtom() (interface{}, error)

func (*Reader) ReadCrlf

func (r *Reader) ReadCrlf() (err error)

func (*Reader) ReadFields

func (r *Reader) ReadFields() (fields []interface{}, err error)

func (*Reader) ReadInfo

func (r *Reader) ReadInfo() (info string, err error)

func (*Reader) ReadLine

func (r *Reader) ReadLine() (fields []interface{}, err error)

func (*Reader) ReadList

func (r *Reader) ReadList() (fields []interface{}, err error)

func (*Reader) ReadLiteral

func (r *Reader) ReadLiteral() (Literal, error)

func (*Reader) ReadQuotedString

func (r *Reader) ReadQuotedString() (string, error)

func (*Reader) ReadRespCode

func (r *Reader) ReadRespCode() (code StatusRespCode, fields []interface{}, err error)

func (*Reader) ReadSp

func (r *Reader) ReadSp() error

type Resp

type Resp interface {
	// contains filtered or unexported methods
}

Resp is an IMAP response. It is either a *DataResp, a *ContinuationReq or a *StatusResp.

func ReadResp

func ReadResp(r *Reader) (Resp, error)

ReadResp reads a single response from a Reader.

type SearchCriteria

type SearchCriteria struct {
	SeqNum *SeqSet // Sequence number is in sequence set
	Uid    *SeqSet // UID is in sequence set

	// Time and timezone are ignored
	Since      time.Time // Internal date is since this date
	Before     time.Time // Internal date is before this date
	SentSince  time.Time // Date header field is since this date
	SentBefore time.Time // Date header field is before this date

	Header textproto.MIMEHeader // Each header field value is present
	Body   []string             // Each string is in the body
	Text   []string             // Each string is in the text (header + body)

	WithFlags    []string // Each flag is present
	WithoutFlags []string // Each flag is not present

	Larger  uint32 // Size is larger than this number
	Smaller uint32 // Size is smaller than this number

	Not []*SearchCriteria    // Each criteria doesn't match
	Or  [][2]*SearchCriteria // Each criteria pair has at least one match of two
}

SearchCriteria is a search criteria. A message matches the criteria if and only if it matches each one of its fields.

func NewSearchCriteria

func NewSearchCriteria() *SearchCriteria

NewSearchCriteria creates a new search criteria.

func (*SearchCriteria) Format

func (c *SearchCriteria) Format() []interface{}

Format formats search criteria to fields. UTF-8 is used.

func (*SearchCriteria) ParseWithCharset

func (c *SearchCriteria) ParseWithCharset(fields []interface{}, charsetReader func(io.Reader) io.Reader) error

ParseWithCharset parses a search criteria from the provided fields. charsetReader is an optional function that converts from the fields charset to UTF-8.

type Seq

type Seq struct {
	Start, Stop uint32
}

Seq represents a single seq-number or seq-range value (RFC 3501 ABNF). Values may be static (e.g. "1", "2:4") or dynamic (e.g. "*", "1:*"). A seq-number is represented by setting Start = Stop. Zero is used to represent "*", which is safe because seq-number uses nz-number rule. The order of values is always Start <= Stop, except when representing "n:*", where Start = n and Stop = 0.

func (Seq) Contains

func (s Seq) Contains(q uint32) bool

Contains returns true if the seq-number q is contained in sequence value s. The dynamic value "*" contains only other "*" values, the dynamic range "n:*" contains "*" and all numbers >= n.

func (Seq) Less

func (s Seq) Less(q uint32) bool

Less returns true if s precedes and does not contain seq-number q.

func (Seq) Merge

func (s Seq) Merge(t Seq) (union Seq, ok bool)

Merge combines sequence values s and t into a single union if the two intersect or one is a superset of the other. The order of s and t does not matter. If the values cannot be merged, s is returned unmodified and ok is set to false.

func (Seq) String

func (s Seq) String() string

String returns sequence value s as a seq-number or seq-range string.

type SeqSet

type SeqSet struct {
	Set []Seq
}

SeqSet is used to represent a set of message sequence numbers or UIDs (see sequence-set ABNF rule). The zero value is an empty set.

func ParseSeqSet

func ParseSeqSet(set string) (s *SeqSet, err error)

ParseSeqSet returns a new SeqSet instance after parsing the set string.

func (*SeqSet) Add

func (s *SeqSet) Add(set string) error

Add inserts new sequence values into the set. The string format is described by RFC 3501 sequence-set ABNF rule. If an error is encountered, all values inserted successfully prior to the error remain in the set.

func (*SeqSet) AddNum

func (s *SeqSet) AddNum(q ...uint32)

AddNum inserts new sequence numbers into the set. The value 0 represents "*".

func (*SeqSet) AddRange

func (s *SeqSet) AddRange(Start, Stop uint32)

AddRange inserts a new sequence range into the set.

func (*SeqSet) AddSet

func (s *SeqSet) AddSet(t *SeqSet)

AddSet inserts all values from t into s.

func (*SeqSet) Clear

func (s *SeqSet) Clear()

Clear removes all values from the set.

func (SeqSet) Contains

func (s SeqSet) Contains(q uint32) bool

Contains returns true if the non-zero sequence number or UID q is contained in the set. The dynamic range "n:*" contains all q >= n. It is the caller's responsibility to handle the special case where q is the maximum UID in the mailbox and q < n (i.e. the set cannot match UIDs against "*:n" or "*" since it doesn't know what the maximum value is).

func (SeqSet) Dynamic

func (s SeqSet) Dynamic() bool

Dynamic returns true if the set contains "*" or "n:*" values.

func (SeqSet) Empty

func (s SeqSet) Empty() bool

Empty returns true if the sequence set does not contain any values.

func (SeqSet) String

func (s SeqSet) String() string

String returns a sorted representation of all contained sequence values.

type StatusItem

type StatusItem string

A StatusItem is a mailbox status data item that can be retrieved with a STATUS command. See RFC 3501 section 6.3.10.

const (
	StatusMessages    StatusItem = "MESSAGES"
	StatusRecent      StatusItem = "RECENT"
	StatusUidNext     StatusItem = "UIDNEXT"
	StatusUidValidity StatusItem = "UIDVALIDITY"
	StatusUnseen      StatusItem = "UNSEEN"

	StatusAppendLimit StatusItem = "APPENDLIMIT"
)

type StatusResp

type StatusResp struct {
	// The response tag. If empty, it defaults to *.
	Tag string
	// The status type.
	Type StatusRespType
	// The status code.
	// See https://www.iana.org/assignments/imap-response-codes/imap-response-codes.xhtml
	Code StatusRespCode
	// Arguments provided with the status code.
	Arguments []interface{}
	// The status info.
	Info string
}

A status response. See RFC 3501 section 7.1

func (*StatusResp) Err

func (r *StatusResp) Err() error

If this status is NO or BAD, returns an error with the status info. Otherwise, returns nil.

func (*StatusResp) WriteTo

func (r *StatusResp) WriteTo(w *Writer) error

type StatusRespCode

type StatusRespCode string
const (
	CodeAlert          StatusRespCode = "ALERT"
	CodeBadCharset     StatusRespCode = "BADCHARSET"
	CodeCapability     StatusRespCode = "CAPABILITY"
	CodeParse          StatusRespCode = "PARSE"
	CodePermanentFlags StatusRespCode = "PERMANENTFLAGS"
	CodeReadOnly       StatusRespCode = "READ-ONLY"
	CodeReadWrite      StatusRespCode = "READ-WRITE"
	CodeTryCreate      StatusRespCode = "TRYCREATE"
	CodeUidNext        StatusRespCode = "UIDNEXT"
	CodeUidValidity    StatusRespCode = "UIDVALIDITY"
	CodeUnseen         StatusRespCode = "UNSEEN"
)

Status response codes defined in RFC 3501 section 7.1.

type StatusRespType

type StatusRespType string

A status response type.

const (
	// The OK response indicates an information message from the server.  When
	// tagged, it indicates successful completion of the associated command.
	// The untagged form indicates an information-only message.
	StatusRespOk StatusRespType = "OK"

	// The NO response indicates an operational error message from the
	// server.  When tagged, it indicates unsuccessful completion of the
	// associated command.  The untagged form indicates a warning; the
	// command can still complete successfully.
	StatusRespNo StatusRespType = "NO"

	// The BAD response indicates an error message from the server.  When
	// tagged, it reports a protocol-level error in the client's command;
	// the tag indicates the command that caused the error.  The untagged
	// form indicates a protocol-level error for which the associated
	// command can not be determined; it can also indicate an internal
	// server failure.
	StatusRespBad StatusRespType = "BAD"

	// The PREAUTH response is always untagged, and is one of three
	// possible greetings at connection startup.  It indicates that the
	// connection has already been authenticated by external means; thus
	// no LOGIN command is needed.
	StatusRespPreauth StatusRespType = "PREAUTH"

	// The BYE response is always untagged, and indicates that the server
	// is about to close the connection.
	StatusRespBye StatusRespType = "BYE"
)

Status response types defined in RFC 3501 section 7.1.

type StoreItem

type StoreItem string

A StoreItem is a message data item that can be updated.

func FormatFlagsOp

func FormatFlagsOp(op FlagsOp, silent bool) StoreItem

FormatFlagsOp returns the StoreItem that executes the flags operation op.

type StringReader

type StringReader interface {
	// ReadString reads until the first occurrence of delim in the input,
	// returning a string containing the data up to and including the delimiter.
	// See https://golang.org/pkg/bufio/#Reader.ReadString
	ReadString(delim byte) (line string, err error)
}

A string reader.

type Waiter

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

func NewWaiter

func NewWaiter() *Waiter

func (*Waiter) Close

func (w *Waiter) Close()

func (*Waiter) Wait

func (w *Waiter) Wait()

func (*Waiter) WaitReady

func (w *Waiter) WaitReady()

type Writer

type Writer struct {
	io.Writer

	AllowAsyncLiterals bool
	// contains filtered or unexported fields
}

An IMAP writer.

func NewClientWriter

func NewClientWriter(w io.Writer, continues <-chan bool) *Writer

func NewWriter

func NewWriter(w io.Writer) *Writer

func (*Writer) Flush

func (w *Writer) Flush() error

type WriterTo

type WriterTo interface {
	WriteTo(w *Writer) error
}

Directories

Path Synopsis
Package backend defines an IMAP server backend interface.
Package backend defines an IMAP server backend interface.
backendutil
Package backendutil provides utility functions to implement IMAP backends.
Package backendutil provides utility functions to implement IMAP backends.
memory
A memory backend.
A memory backend.
Package client provides an IMAP client.
Package client provides an IMAP client.
Package commands implements IMAP commands defined in RFC 3501.
Package commands implements IMAP commands defined in RFC 3501.
IMAP responses defined in RFC 3501.
IMAP responses defined in RFC 3501.
Package server provides an IMAP server.
Package server provides an IMAP server.
Package utf7 implements modified UTF-7 encoding defined in RFC 3501 section 5.1.3
Package utf7 implements modified UTF-7 encoding defined in RFC 3501 section 5.1.3

Jump to

Keyboard shortcuts

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