smtpd

package
v0.0.0-...-7438d6a Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2015 License: AGPL-3.0, MIT Imports: 13 Imported by: 0

README

lavab/smtpd Build Status GoDoc

smtpd is a simple library for implementing SMTP servers in Golang. Supports STARTTLS, middleware chains for event handling and configurable limits.

Example

package main

import (
	"log"

	"github.com/getsentry/raven-go"
	"github.com/lavab/smtpd"
)

func main() {
	// Connect to raven for sentry logging
	rc, err := raven.NewClient("some raven dsn", nil)
	if err != nil {
		log.Fatal(err)
	}

	// Create a new SMTPD server
	server := &smtpd.Server{
		WelcomeMessage: "Hello world!",

		WrapperChain: []smtpd.Wrapper{
			smtpd.Wrapper(func(next smtpd.Wrapped) smtpd.Wrapped {
				return smtpd.Wrapped(func() {
					rc.CapturePanic(next, nil)
				})
			}),
		},
		DeliveryChain: []smtpd.Middleware{
			smtpd.Middleware(func(next smtpd.Handler) smtpd.Handler {
				return smtpd.Handler(func(conn *smtpd.Connection) {
					log.Printf("Sender: %s", conn.Envelope.Sender)
					log.Printf("Recipients: %s", strings.Join(conn.Envelope.Recipients, ", "))
					log.Printf("Body:\n%s", string(conn.Envelope.Body))
					
					next(conn)
				})
			}),
		},
	}

	// Bind it to an address
	if err := server.ListenAndServe(":25"); err != nil {
		log.Fatal(err)
	}
}

Documentation

Index

Constants

View Source
const (
	StatusPasswordNeeded       = 432
	StatusMessageError         = 450
	StatusMessageExceedStorage = 452
	StatusTempAuthFailure      = 454
	StatusAuthInvalid          = 535
	StatusAuthRequired         = 530
	StatusEncryptionRequired   = 538
	StatusServerError          = 550
	StatusExceedStorage        = 552
)

Variables

View Source
var (
	ErrPasswordNeeded       = Error{Code: StatusPasswordNeeded, Message: StatusString(StatusPasswordNeeded)}
	ErrMessageError         = Error{Code: StatusMessageError, Message: StatusString(StatusMessageError)}
	ErrMessageExceedStorage = Error{Code: StatusMessageExceedStorage, Message: StatusString(StatusMessageExceedStorage)}
	ErrTempAuthFailure      = Error{Code: StatusTempAuthFailure, Message: StatusString(StatusTempAuthFailure)}
	ErrAuthInvalid          = Error{Code: StatusAuthInvalid, Message: StatusString(StatusAuthInvalid)}
	ErrAuthRequired         = Error{Code: StatusAuthRequired, Message: StatusString(StatusAuthRequired)}
	ErrServerError          = Error{Code: StatusServerError, Message: StatusString(StatusServerError)}
	ErrExceedStorage        = Error{Code: StatusExceedStorage, Message: StatusString(StatusExceedStorage)}
)

Functions

func StatusString

func StatusString(status int) string

Types

type Connection

type Connection struct {
	Server *Server

	HeloName string
	Protocol Protocol
	Addr     net.Addr
	TLS      *tls.ConnectionState

	Envelope    *Envelope
	Environment map[string]interface{}
	// contains filtered or unexported fields
}

func (*Connection) Error

func (c *Connection) Error(err error)

type Delivery

type Delivery interface {
	HandleDelivery(func(conn *Connection)) func(conn *Connection)
}

Delivery is called after the whole MIME message is sent to the server.

type DeliveryFunc

type DeliveryFunc func(func(conn *Connection)) func(conn *Connection)

func (DeliveryFunc) HandleDelivery

func (d DeliveryFunc) HandleDelivery(x func(conn *Connection)) func(conn *Connection)

type Envelope

type Envelope struct {
	Sender     string
	Recipients []string
	Data       []byte
}

func (*Envelope) AddReceivedLine

func (e *Envelope) AddReceivedLine(c *Connection)

type Error

type Error struct {
	Code    int
	Message string
}

func (Error) Error

func (e Error) Error() string

type Protocol

type Protocol string
const (
	SMTP  Protocol = "SMTP"
	ESMTP          = "ESMTP"
)

func (Protocol) String

func (p Protocol) String() string

type Recipient

type Recipient interface {
	HandleRecipient(func(conn *Connection)) func(conn *Connection)
}

Recipient is called whenever client sents a RCPT command to the server.

type RecipientFunc

type RecipientFunc func(func(conn *Connection)) func(conn *Connection)

func (RecipientFunc) HandleRecipient

func (r RecipientFunc) HandleRecipient(x func(conn *Connection)) func(conn *Connection)

type Sender

type Sender interface {
	HandleSender(func(conn *Connection)) func(conn *Connection)
}

Sender allows data preloading whenever a new envelope is created.

type SenderFunc

type SenderFunc func(func(conn *Connection)) func(conn *Connection)

func (SenderFunc) HandleSender

func (s SenderFunc) HandleSender(x func(conn *Connection)) func(conn *Connection)

type Server

type Server struct {
	Hostname       string
	WelcomeMessage string

	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	DataTimeout  time.Duration

	MaxConnections int
	MaxMessageSize int
	MaxRecipients  int

	WrapperChain   []Wrapper
	SenderChain    []Sender
	RecipientChain []Recipient
	DeliveryChain  []Delivery

	TLSConfig *tls.Config
	ForceTLS  bool
	// contains filtered or unexported fields
}

func (*Server) ListenAndServe

func (s *Server) ListenAndServe(addr string) error

func (*Server) Serve

func (s *Server) Serve(l net.Listener) error

type Wrapper

type Wrapper interface {
	Wrap(func()) func()
}

Wrapper is used for surrounding whole calls with defer etc.

type WrapperFunc

type WrapperFunc func(func()) func()

func (WrapperFunc) Wrap

func (w WrapperFunc) Wrap(x func()) func()

Jump to

Keyboard shortcuts

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