backends

package
v1.6.4 Latest Latest
Warning

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

Go to latest
Published: Sep 12, 2023 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	BackendStateNew backendState = iota
	BackendStateRunning
	BackendStateShuttered
	BackendStateError
	BackendStateInitialized
)

possible values for state

View Source
const GuerrillaDBAndRedisBatchMax = 50

how many rows to batch at a time

View Source
const GuerrillaDBAndRedisBatchTimeout = time.Second * 3

tick on every...

Variables

View Source
var (
	NoSuchUser          = RcptError(errors.New("no such user"))
	StorageNotAvailable = RcptError(errors.New("storage not available"))
	StorageTooBusy      = RcptError(errors.New("storage too busy"))
	StorageTimeout      = RcptError(errors.New("storage timeout"))
	QuotaExceeded       = RcptError(errors.New("quota exceeded"))
	UserSuspended       = RcptError(errors.New("user suspended"))
	StorageError        = RcptError(errors.New("storage error"))
)
View Source
var BackendResultOK = NewResult("200 OK")
View Source
var ErrProcessorNotFound error
View Source
var RedisDialer redisDial
View Source
var (
	Svc *service
)

Functions

func Compress

func Compress(stringArguments ...string) string

concatenate & compress all strings passed in

func Log

func Log() log.Logger

Get loads the log.logger in an atomic operation. Returns a stderr logger if not able to load

func MD5Hex

func MD5Hex(stringArguments ...string) string

returns an md5 hash as string of hex characters

func ParseHeaders

func ParseHeaders(mailData string) map[string]string

ParseHeaders is deprecated, see mail.Envelope.ParseHeaders instead

Types

type Backend

type Backend interface {
	// Process processes then saves the mail envelope
	Process(*mail.Envelope) Result
	// ValidateRcpt validates the last recipient that was pushed to the mail envelope
	ValidateRcpt(e *mail.Envelope) RcptError
	// Initializes the backend, eg. creates folders, sets-up database connections
	Initialize(BackendConfig) error
	// Initializes the backend after it was Shutdown()
	Reinitialize() error
	// Shutdown frees / closes anything created during initializations
	Shutdown() error
	// Start Starts a backend that has been initialized
	Start() error
}

Backends process received mail. Depending on the implementation, they can store mail in the database, write to a file, check for spam, re-transmit to another server, etc. Must return an SMTP message (i.e. "250 OK") and a boolean indicating whether the message was processed successfully.

func New

func New(backendConfig BackendConfig, l log.Logger) (Backend, error)

New makes a new default BackendGateway backend, and initializes it using backendConfig and stores the logger

type BackendConfig

type BackendConfig map[string]interface{}

type BackendGateway

type BackendGateway struct {

	// controls access to state
	sync.Mutex
	State backendState
	// contains filtered or unexported fields
}

A backend gateway is a proxy that implements the Backend interface. It is used to start multiple goroutine workers for saving mail, and then distribute email saving to the workers via a channel. Shutting down via Shutdown() will stop all workers. The rest of this program always talks to the backend via this gateway.

func (*BackendGateway) Initialize

func (gw *BackendGateway) Initialize(cfg BackendConfig) error

Initialize builds the workers and initializes each one

func (*BackendGateway) Process

func (gw *BackendGateway) Process(e *mail.Envelope) Result

Process distributes an envelope to one of the backend workers with a TaskSaveMail task

func (*BackendGateway) Reinitialize

func (gw *BackendGateway) Reinitialize() error

Reinitialize initializes the gateway with the existing config after it was shutdown

func (*BackendGateway) Shutdown

func (gw *BackendGateway) Shutdown() error

Shutdown shuts down the backend and leaves it in BackendStateShuttered state

func (*BackendGateway) Start

func (gw *BackendGateway) Start() error

Start starts the worker goroutines, assuming it has been initialized or shuttered before

func (*BackendGateway) ValidateRcpt

func (gw *BackendGateway) ValidateRcpt(e *mail.Envelope) RcptError

ValidateRcpt asks one of the workers to validate the recipient Only the last recipient appended to e.RcptTo will be validated.

type BaseConfig

type BaseConfig interface{}

All config structs extend from this

type DataCompressor

type DataCompressor struct {
	ExtraHeaders []byte
	Data         *bytes.Buffer
	// the pool is used to recycle buffers to ease up on the garbage collector
	Pool *sync.Pool
}

compressedData struct will be compressed using zlib when printed via fmt

func (*DataCompressor) String

func (c *DataCompressor) String() string

String implements the Stringer interface. Can only be called once! This is because the compression buffer will be reset and compressor will be returned to the pool

type Decorator

type Decorator func(Processor) Processor

We define what a decorator to our processor will look like

func Compressor

func Compressor() Decorator

func Debugger

func Debugger() Decorator

func GuerrillaDbRedis

func GuerrillaDbRedis() Decorator

GuerrillaDbRedis is a specialized processor for Guerrilla mail. It is here as an example. It's an example of a 'monolithic' processor.

func Hasher

func Hasher() Decorator

The hasher decorator computes a hash of the email for each recipient It appends the hashes to envelope's Hashes slice.

func Header() Decorator

Generate the MTA delivery header Sets e.DeliveryHeader part of the envelope with the generated header

func HeadersParser

func HeadersParser() Decorator

func Redis

func Redis() Decorator

func SQL

func SQL() Decorator

type DefaultProcessor

type DefaultProcessor struct{}

DefaultProcessor is a undecorated worker that does nothing Notice DefaultProcessor has no knowledge of the other decorators that have orthogonal concerns.

func (DefaultProcessor) Process

func (w DefaultProcessor) Process(e *mail.Envelope, task SelectTask) (Result, error)

do nothing except return the result (this is the last call in the decorator stack, if it got here, then all is good)

type Errors

type Errors []error

func (Errors) Error

func (e Errors) Error() string

implement the Error interface

type GatewayConfig

type GatewayConfig struct {
	// WorkersSize controls how many concurrent workers to start. Defaults to 1
	WorkersSize int `json:"save_workers_size,omitempty"`
	// SaveProcess controls which processors to chain in a stack for saving email tasks
	SaveProcess string `json:"save_process,omitempty"`
	// ValidateProcess is like ProcessorStack, but for recipient validation tasks
	ValidateProcess string `json:"validate_process,omitempty"`
	// TimeoutSave is duration before timeout when saving an email, eg "29s"
	TimeoutSave string `json:"gw_save_timeout,omitempty"`
	// TimeoutValidateRcpt duration before timeout when validating a recipient, eg "1s"
	TimeoutValidateRcpt string `json:"gw_val_rcpt_timeout,omitempty"`
}

type GuerrillaDBAndRedisBackend

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

type HeaderConfig

type HeaderConfig struct {
	PrimaryHost string `json:"primary_mail_host"`
}

type InitializeWith

type InitializeWith func(backendConfig BackendConfig) error

func (InitializeWith) Initialize

func (i InitializeWith) Initialize(backendConfig BackendConfig) error

Satisfy ProcessorInitializer interface So we can now pass an anonymous function that implements ProcessorInitializer

type NoopProcessor

type NoopProcessor struct{ DefaultProcessor }

if no processors specified, skip operation

type ProcessWith

type ProcessWith func(*mail.Envelope, SelectTask) (Result, error)

Signature of Processor

func (ProcessWith) Process

func (f ProcessWith) Process(e *mail.Envelope, task SelectTask) (Result, error)

Make ProcessWith will satisfy the Processor interface

type Processor

type Processor interface {
	Process(*mail.Envelope, SelectTask) (Result, error)
}

Our processor is defined as something that processes the envelope and returns a result and error

func Decorate

func Decorate(c Processor, ds ...Decorator) Processor

Decorate will decorate a processor with a slice of passed decorators

type ProcessorConstructor

type ProcessorConstructor func() Decorator

type RcptError

type RcptError error

type RedisConn

type RedisConn interface {
	Close() error
	Do(commandName string, args ...interface{}) (reply interface{}, err error)
}

RedisConn interface provides a generic way to access Redis via drivers

type RedisDialOption

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

type RedisMockConn

type RedisMockConn struct{}

func (*RedisMockConn) Close

func (m *RedisMockConn) Close() error

func (*RedisMockConn) Do

func (m *RedisMockConn) Do(commandName string, args ...interface{}) (reply interface{}, err error)

type RedisProcessor

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

type RedisProcessorConfig

type RedisProcessorConfig struct {
	RedisExpireSeconds int    `json:"redis_expire_seconds"`
	RedisInterface     string `json:"redis_interface"`
}

type Result

type Result interface {
	fmt.Stringer
	// Code should return the SMTP code associated with this response, ie. `250`
	Code() int
}

Result represents a response to an SMTP client after receiving DATA. The String method should return an SMTP message ready to send back to the client, for example `250 OK: Message received`.

func NewResult

func NewResult(r ...interface{}) Result

type SQLProcessor

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

type SQLProcessorConfig

type SQLProcessorConfig struct {
	Table           string `json:"mail_table"`
	Driver          string `json:"sql_driver"`
	DSN             string `json:"sql_dsn"`
	SQLInsert       string `json:"sql_insert,omitempty"`
	SQLValues       string `json:"sql_values,omitempty"`
	PrimaryHost     string `json:"primary_mail_host"`
	MaxConnLifetime string `json:"sql_max_conn_lifetime,omitempty"`
	MaxOpenConns    int    `json:"sql_max_open_conns,omitempty"`
	MaxIdleConns    int    `json:"sql_max_idle_conns,omitempty"`
}

type SelectTask

type SelectTask int
const (
	TaskSaveMail SelectTask = iota
	TaskValidateRcpt
)

func (SelectTask) String

func (o SelectTask) String() string

type ShutdownWith

type ShutdownWith func() error

func (ShutdownWith) Shutdown

func (s ShutdownWith) Shutdown() error

satisfy ProcessorShutdowner interface, same concept as InitializeWith type

Directories

Path Synopsis
storage

Jump to

Keyboard shortcuts

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