lmail

package module
v0.0.0-...-1a5044a Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2015 License: MIT Imports: 14 Imported by: 0

README

lmail - lmail absolutley is lmail

lmail is a smtp server library written in go. It resembles the api provided by the net.http package.

Documentation

Please refer to http://godoc.org/github.com/mattimo/lmail for documentation.

Usage

import "github.com/mattimo/lmail" 

The easiest way to get started is to just call ListenAndServer() with a small dummy handler.

type DummyHandler type{}

func (d DummyHandler) HandleMail(m *lmail.Mail) (int, error) {
	io.Copy(ioutil.Discard, mail.RawReader())
	fmt.Println(m)
}

func main {
	lmail.ListenAndServer(":2525", &DummyHandler{})
}

This ist just a simple example. It would read the mail and print it. Mails are only read from the smtp connection the first time the whole message is read.

Documentation

Index

Constants

View Source
const (
	CodeSystemcStatus = 211
	CodeHelp          = 214
	CodeReady         = 220
	CodeClosing       = 221
	CodeOk            = 250
	CodeUserNotLocal  = 251
	CodeUserNoVerify  = 252

	CodeStartMailInput = 354

	CodeNotAvailable        = 421
	CodeMailboxNotAvailable = 450
	CodeAborted             = 451
	CodeInsufficientStorage = 452

	CodeTlsNotAvaiable = 454

	CodeNotRecognized           = 500
	CodeSyntaxError             = 501
	CodeNotImplemented          = 502
	CodeBadSequence             = 503
	CodeParameterNotImplemented = 504
	CodeNotTaken                = 550
	CodeErrUserNotLocal         = 551
	CodeMailAborted             = 552
	CodeMailboxNameNotAllowed   = 553
	CodeTransactionFailed       = 554
)

SMTP return codes

Variables

View Source
var MaildirCreateMode os.FileMode = 0700

MaildirCreateMode is the mode that is used to create the maildir tree structure.

View Source
var SmtpErrors = map[int]string{
	500: "Syntax Error, command not recognized",
	501: "Syntax Error in parameter or argument",
	502: "Command Not implemented",
	503: "Bad sequence of commands",
	504: "Parameter not implemented",
	550: "Requested action not taken: mailbox unavailable",
	551: "User not local; please try <forward-path>",
	552: "Requested mail action aborted: exceeded storage allocatio",
	553: "Requested action not taken: mailbox name not allowed",
	554: "Transaction failed",
}

SmtpErrors is a list of permanent negative completion messages.

Functions

func ListenAndServe

func ListenAndServe(addr string, handler Handler) error

ListenAndServe Listens on a TCP network address and then calls Serve with the given handler.

A trivial example server is:

import (
	"fmt"
	"io"
	"lmail"
)

type MyHandler struct {}

func (h *MyHandler) HandleMail(m *Mail) (code int, err error) {
	var buf []bytes
	reader := m.RawReader()
	for n, err := reader.Read(buf); n > 0 {
		if err != nil && err != io.EOF {
			return 501, err
		}
		fmt.Printnf("%s", buf)
	}

}

func main() {
	handler := &MyHandler{}
	fmt.Println(lmail.ListenAndServe(":2525", handler))
}

func ListenAndServeTLS

func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error

ListenAndServeTLS is the STARTTLS enabled clone of ListenAndServe Listens on a TCP network address and then calls Serve with the given handler. Additionally, files containing a certificate and matching private key for the server must be provided. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate followed by the CA's certificate.

A trivial example server is:

import (
	"fmt"
	"io"
	"lmail"
)

type MyHandler struct {}

func (h *MyHandler) HandleMail(m *Mail) (code int, err error) {
	var buf []bytes
	reader := m.RawReader()
	for n, err := reader.Read(buf); n > 0 {
		if err != nil && err != io.EOF {
			return 501, err
		}
		fmt.Printnf("%s", buf)
	}

}

func main() {
	handler := &MyHandler{}
	err := lmail.ListenAndServeTLS(":2525", "server.pen", server.key, handler)
	if err != nil {
		fmt.Println("Server Failure:", err)
	}
}

One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.

Types

type DefaultMuxer

type DefaultMuxer struct {
	DefaultHandler Handler
	// contains filtered or unexported fields
}

DefaultMuxer is a simple map based muxer to.

This muxer is fairly simple. you can register an address that receives its own handler. Each handler is called if the address is registered otherwise the default handler is called. The default Default handler is the lmail.NullHandler

func NewDefaultMuxer

func NewDefaultMuxer() *DefaultMuxer

NewDefaultMuxer gets a new default muxer.

func (*DefaultMuxer) AddRcptHandler

func (m *DefaultMuxer) AddRcptHandler(match string, handler Handler)

AddRcptHandler registers a handler for an address string.

func (*DefaultMuxer) HandleMail

func (m *DefaultMuxer) HandleMail(mail *Mail) (code int, err error)

HandleMail handles a mail and then calls the registerd Handler for the matching RCPTs.

type Handler

type Handler interface {
	// Handles Mails, gets passed a mail struct as an argument, and should return
	// an smtp error, and an error object for all other errors.
	// If the smtp error code is 0 or err is not nil it is ignored.
	// if err is not nil, the server will respond with the appropriate
	// error code or ignore the handler
	HandleMail(*Mail) (int, error)
}

Handler interface

type Mail

type Mail struct {

	// Server Client name. We use the reverse Lookup of the client
	//connection
	Client string
	// Client connection name as advertised by the client itself
	ClientName string
	// Mail sender as advertised by client
	From string
	// Slice of reciepients as registered by the client
	Rcpts []string
	// contains filtered or unexported fields
}

Mail type represents mail data and is passed between handlers.

Data is only read from the connection when it is read from either the message Body or the Raw reader.

func (*Mail) MimeMessage

func (m *Mail) MimeMessage() (msg *mail.Message, err error)

MimeMessage returns the mime header from the message. If the header could not be read it returns an error.

func (*Mail) PutMessage

func (m *Mail) PutMessage(raw io.Reader)

PutMessage puts a raw mail to the buffer. Takes an io.Reader as an argument.

func (*Mail) RawReader

func (m *Mail) RawReader() io.Reader

RawReader returns a raw Reader for the Message. The returned reader can be read from several goroutines simultaniously.

type Maildir

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

Maildir is a mail Handler That saves into a maildir. Maildir is an easy way to store mails. For reference how to retrieve mail from a maildir refer to:

http://cr.yp.to/proto/maildir.html

This maildir implementation is supposed to read incoming mails from the receiving Socket into a new File in the maildirs /tmp directory and then move it to /new.

func NewMaildir

func NewMaildir(dir string) (*Maildir, error)

NewMaildir creates a new maildir at the given location. If the underlying directory structure does not exist, it is created. It returns a usable maildir struct and any errors the occure during initialisation.

func (*Maildir) Deliver

func (m *Maildir) Deliver(f string) error

Deliver an email. If the mail was regarded as ok it shall be deliverd. This method only takes a string of the maildir file and moves it from tmp to new

func (*Maildir) HandleMail

func (m *Maildir) HandleMail(mail *Mail) (code int, err error)

HandleMail is a simple handler, for mails that shall be stored.

func (*Maildir) StoreTmp

func (m *Maildir) StoreTmp(reader io.Reader) (int64, *os.File, error)

StoreTmp stores a mail in the maildir. takes a reader and returns how many bytes where read and an error

type NullHandler

type NullHandler struct{}

NullHandler is a simple handler that discards the mail. This Handler reads from the raw buffer until io.EOF and discards the readers contents.

func (*NullHandler) HandleMail

func (d *NullHandler) HandleMail(m *Mail) (code int, err error)

HandleMail callback that just discards the mail.

type Server

type Server struct {
	Addr    string  //TCP address to listen on, ":smtp" if empty
	Handler Handler // handler to invoke, lmail.DefaultServeMux if nil
	Name    string  // Server name, hostname if emtpy

	// TLS config to use when a starttls session is initiated by the
	// client if nil, starttls will fail.
	TLSConfig *tls.Config

	// Error Logger, if nil logs are sent to os.Stderr.
	ErrorLog *log.Logger
}

Server type that implements a simple smtp server

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe() error

ListenAndServe listens on the TCP network address srv.Addr and then calls Serve to handle requests on incoming connections. If srv.Addr is blank, ":smtp" is used.

func (*Server) ListenAndServeTLS

func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS listens on the TCP network address srv.Addr and then calls Serve With startls enabled to handle requests on incoming connections.

Filenames containing a certificate and matching private key for the server must be provided. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate followed by the CA's certificate.

If srv.Addr is blank, ":smtp" is used. if there is an error parsing the certificates, we return an errror

func (*Server) Serve

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

Serve accepts incoming connections on the Listener l, creating a new connection handler goroutine for each and which then calls a handler.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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