瀏覽代碼

- redis: when not compressed, delivery header was not added
- add comments at the start of all processors

flashmob 8 年之前
父節點
當前提交
e2d7375576
共有 8 個文件被更改,包括 130 次插入73 次删除
  1. 16 18
      backends/p_compressor.go
  2. 11 11
      backends/p_debugger.go
  3. 14 14
      backends/p_hasher.go
  4. 18 4
      backends/p_header.go
  5. 11 0
      backends/p_headers_parser.go
  6. 28 10
      backends/p_mysql.go
  7. 27 16
      backends/p_redis.go
  8. 5 0
      envelope/envelope.go

+ 16 - 18
backends/p_compressor.go

@@ -8,25 +8,23 @@ import (
 	"sync"
 	"sync"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: compressor
+// ----------------------------------------------------------------------------------
+// Description   : Compress the e.Data (email data) and e.DeliveryHeader together
+// ----------------------------------------------------------------------------------
+// Config Options: None
+// --------------:-------------------------------------------------------------------
+// Input         : e.Data, e.DeliveryHeader generated by Header() processor
+// ----------------------------------------------------------------------------------
+// Output        : sets the pointer to a compressor in e.Info["zlib-compressor"]
+//               : to write the compressed data, simply use fmt to print as a string,
+//               : eg. fmt.Println("%s", e.Info["zlib-compressor"])
+//               : or just call the String() func .Info["zlib-compressor"].String()
+//               : Note that it can only be outputted once. It destroys the buffer
+//               : after being printed
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
-
-	// ----------------------------------------------------------------------------------
-	// Processor Name: compressor
-	// ----------------------------------------------------------------------------------
-	// Description   : Compress the e.Data (email data) and e.DeliveryHeader together
-	// ----------------------------------------------------------------------------------
-	// Config Options: None
-	// --------------:-------------------------------------------------------------------
-	// Input         : e.Data, e.DeliveryHeader generated by Header() processor
-	// ----------------------------------------------------------------------------------
-	// Output        : sets the pointer to a compressor in e.Info["zlib-compressor"]
-	//               : to write the compressed data, simply use fmt to print as a string,
-	//               : eg. fmt.Println("%s", e.Info["zlib-compressor"])
-	//               : or just call the String() func .Info["zlib-compressor"].String()
-	//               : Note that it can only be outputted once. It destroys the buffer
-	//               : after being printed
-	// ----------------------------------------------------------------------------------
-
 	Processors["compressor"] = func() Decorator {
 	Processors["compressor"] = func() Decorator {
 		return Compressor()
 		return Compressor()
 	}
 	}

+ 11 - 11
backends/p_debugger.go

@@ -4,18 +4,18 @@ import (
 	"github.com/flashmob/go-guerrilla/envelope"
 	"github.com/flashmob/go-guerrilla/envelope"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: debugger
+// ----------------------------------------------------------------------------------
+// Description   : Log received emails
+// ----------------------------------------------------------------------------------
+// Config Options: log_received_mails bool - log if true
+// --------------:-------------------------------------------------------------------
+// Input         : e.MailFrom, e.RcptTo, e.Header
+// ----------------------------------------------------------------------------------
+// Output        : none (only output to the log if enabled)
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
-	// ----------------------------------------------------------------------------------
-	// Processor Name: debugger
-	// ----------------------------------------------------------------------------------
-	// Description   : Log received emails
-	// ----------------------------------------------------------------------------------
-	// Config Options: log_received_mails bool - log if true
-	// --------------:-------------------------------------------------------------------
-	// Input         : e.MailFrom, e.RcptTo, e.Header
-	// ----------------------------------------------------------------------------------
-	// Output        : none (only output to the log if enabled)
-	// ----------------------------------------------------------------------------------
 	Processors["debugger"] = func() Decorator {
 	Processors["debugger"] = func() Decorator {
 		return Debugger()
 		return Debugger()
 	}
 	}

+ 14 - 14
backends/p_hasher.go

@@ -3,26 +3,26 @@ package backends
 import (
 import (
 	"crypto/md5"
 	"crypto/md5"
 	"fmt"
 	"fmt"
-	"github.com/flashmob/go-guerrilla/envelope"
 	"io"
 	"io"
 	"strings"
 	"strings"
 	"time"
 	"time"
+
+	"github.com/flashmob/go-guerrilla/envelope"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: hasher
+// ----------------------------------------------------------------------------------
+// Description   : Generates a unique md5 checksum id for an email
+// ----------------------------------------------------------------------------------
+// Config Options: None
+// --------------:-------------------------------------------------------------------
+// Input         : e.MailFrom, e.Subject, e.RcptTo
+//               : assuming e.Subject was generated by "headersparser" processor
+// ----------------------------------------------------------------------------------
+// Output        : Checksum stored in e.Hash
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
-	// ----------------------------------------------------------------------------------
-	// Processor Name: hasher
-	// ----------------------------------------------------------------------------------
-	// Description   : Generates a unique md5 checksum id for an email
-	// ----------------------------------------------------------------------------------
-	// Config Options: None
-	// --------------:-------------------------------------------------------------------
-	// Input         : e.MailFrom, e.Subject, e.RcptTo
-	//               : assuming e.Subject was generated by "headersparser" processor
-	// ----------------------------------------------------------------------------------
-	// Output        : Checksum stored in e.Hash
-	// ----------------------------------------------------------------------------------
-
 	Processors["hasher"] = func() Decorator {
 	Processors["hasher"] = func() Decorator {
 		return Hasher()
 		return Hasher()
 	}
 	}

+ 18 - 4
backends/p_header.go

@@ -10,6 +10,20 @@ type HeaderConfig struct {
 	PrimaryHost string `json:"primary_mail_host"`
 	PrimaryHost string `json:"primary_mail_host"`
 }
 }
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: header
+// ----------------------------------------------------------------------------------
+// Description   : Adds delivery information headers to e.DeliveryHeader
+// ----------------------------------------------------------------------------------
+// Config Options: none
+// --------------:-------------------------------------------------------------------
+// Input         : e.Helo
+//               : e.RemoteAddress
+//               : e.RcptTo
+//               : e.Hashes
+// ----------------------------------------------------------------------------------
+// Output        : Sets e.DeliveryHeader with additional delivery info
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
 	Processors["header"] = func() Decorator {
 	Processors["header"] = func() Decorator {
 		return Header()
 		return Header()
@@ -40,12 +54,12 @@ func Header() Decorator {
 				hash = e.Hashes[0]
 				hash = e.Hashes[0]
 			}
 			}
 			var addHead string
 			var addHead string
-			addHead += "Delivered-To: " + to + "\r\n"
-			addHead += "Received: from " + e.Helo + " (" + e.Helo + "  [" + e.RemoteAddress + "])\r\n"
+			addHead += "Delivered-To: " + to + "\n"
+			addHead += "Received: from " + e.Helo + " (" + e.Helo + "  [" + e.RemoteAddress + "])\n"
 			if len(e.RcptTo) > 0 {
 			if len(e.RcptTo) > 0 {
-				addHead += "	by " + e.RcptTo[0].Host + " with SMTP id " + hash + "@" + e.RcptTo[0].Host + ";\r\n"
+				addHead += "	by " + e.RcptTo[0].Host + " with SMTP id " + hash + "@" + e.RcptTo[0].Host + ";\n"
 			}
 			}
-			addHead += "	" + time.Now().Format(time.RFC1123Z) + "\r\n"
+			addHead += "	" + time.Now().Format(time.RFC1123Z) + "\n"
 			// save the result
 			// save the result
 			e.DeliveryHeader = addHead
 			e.DeliveryHeader = addHead
 			// next processor
 			// next processor

+ 11 - 0
backends/p_headers_parser.go

@@ -4,6 +4,17 @@ import (
 	"github.com/flashmob/go-guerrilla/envelope"
 	"github.com/flashmob/go-guerrilla/envelope"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: headersparser
+// ----------------------------------------------------------------------------------
+// Description   : Parses the header using e.ParseHeaders()
+// ----------------------------------------------------------------------------------
+// Config Options: none
+// --------------:-------------------------------------------------------------------
+// Input         : envelope
+// ----------------------------------------------------------------------------------
+// Output        : Headers will be populated in e.Header
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
 	Processors["headersparser"] = func() Decorator {
 	Processors["headersparser"] = func() Decorator {
 		return HeadersParser()
 		return HeadersParser()

+ 28 - 10
backends/p_mysql.go

@@ -11,6 +11,27 @@ import (
 	"runtime/debug"
 	"runtime/debug"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: mysql
+// ----------------------------------------------------------------------------------
+// Description   : Saves the e.Data (email data) and e.DeliveryHeader together in mysql
+//               : using the hash generated by the "hash" processor and stored in
+//               : e.Hashes
+// ----------------------------------------------------------------------------------
+// Config Options: mail_table string - mysql table name
+//               : mysql_db string - mysql database name
+//               : mysql_host string - mysql host name, eg. 127.0.0.1
+//               : mysql_pass string - mysql password
+//               : mysql_user string - mysql username
+//               : primary_mail_host string - primary host name
+// --------------:-------------------------------------------------------------------
+// Input         : e.Data
+//               : e.DeliveryHeader generated by ParseHeader() processor
+//               : e.MailFrom
+//               : e.Subject - generated by by ParseHeader() processor
+// ----------------------------------------------------------------------------------
+// Output        : No output, just saves to mysql
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
 	Processors["mysql"] = func() Decorator {
 	Processors["mysql"] = func() Decorator {
 		return MySql()
 		return MySql()
@@ -18,15 +39,12 @@ func init() {
 }
 }
 
 
 type MysqlProcessorConfig struct {
 type MysqlProcessorConfig struct {
-	NumberOfWorkers    int    `json:"save_workers_size"`
-	MysqlTable         string `json:"mail_table"`
-	MysqlDB            string `json:"mysql_db"`
-	MysqlHost          string `json:"mysql_host"`
-	MysqlPass          string `json:"mysql_pass"`
-	MysqlUser          string `json:"mysql_user"`
-	RedisExpireSeconds int    `json:"redis_expire_seconds"`
-	RedisInterface     string `json:"redis_interface"`
-	PrimaryHost        string `json:"primary_mail_host"`
+	MysqlTable  string `json:"mail_table"`
+	MysqlDB     string `json:"mysql_db"`
+	MysqlHost   string `json:"mysql_host"`
+	MysqlPass   string `json:"mysql_pass"`
+	MysqlUser   string `json:"mysql_user"`
+	PrimaryHost string `json:"primary_mail_host"`
 }
 }
 
 
 type MysqlProcessor struct {
 type MysqlProcessor struct {
@@ -175,7 +193,7 @@ func MySql() Decorator {
 				vals = append(vals, co.String())
 				vals = append(vals, co.String())
 				//co.clear()
 				//co.clear()
 			} else {
 			} else {
-				vals = append(vals, e.DeliveryHeader+e.Data.String())
+				vals = append(vals, e.String())
 			}
 			}
 
 
 			vals = append(vals,
 			vals = append(vals,

+ 27 - 16
backends/p_redis.go

@@ -4,12 +4,29 @@ import (
 	"fmt"
 	"fmt"
 
 
 	"github.com/flashmob/go-guerrilla/envelope"
 	"github.com/flashmob/go-guerrilla/envelope"
-
 	"github.com/flashmob/go-guerrilla/response"
 	"github.com/flashmob/go-guerrilla/response"
+
 	"github.com/garyburd/redigo/redis"
 	"github.com/garyburd/redigo/redis"
 )
 )
 
 
+// ----------------------------------------------------------------------------------
+// Processor Name: redis
+// ----------------------------------------------------------------------------------
+// Description   : Saves the e.Data (email data) and e.DeliveryHeader together in redis
+//               : using the hash generated by the "hash" processor and stored in
+//               : e.Hashes
+// ----------------------------------------------------------------------------------
+// Config Options: redis_expire_seconds int - how many seconds to expiry
+//               : redis_interface string - <host>:<port> eg, 127.0.0.1:6379
+// --------------:-------------------------------------------------------------------
+// Input         : e.Data
+//               : e.DeliveryHeader generated by Header() processor
+//               :
+// ----------------------------------------------------------------------------------
+// Output        : No output, just saves to redis
+// ----------------------------------------------------------------------------------
 func init() {
 func init() {
+
 	Processors["redis"] = func() Decorator {
 	Processors["redis"] = func() Decorator {
 		return Redis()
 		return Redis()
 	}
 	}
@@ -70,29 +87,23 @@ func Redis() Decorator {
 	return func(c Processor) Processor {
 	return func(c Processor) Processor {
 		return ProcessorFunc(func(e *envelope.Envelope) (BackendResult, error) {
 		return ProcessorFunc(func(e *envelope.Envelope) (BackendResult, error) {
 			hash := ""
 			hash := ""
+
 			if len(e.Hashes) > 0 {
 			if len(e.Hashes) > 0 {
 				hash = e.Hashes[0]
 				hash = e.Hashes[0]
 
 
-				var cData *compressor
+				var stringer fmt.Stringer
 				// a compressor was set
 				// a compressor was set
 				if c, ok := e.Info["zlib-compressor"]; ok {
 				if c, ok := e.Info["zlib-compressor"]; ok {
-					cData = c.(*compressor)
+					stringer = c.(*compressor)
+				} else {
+					stringer = e
 				}
 				}
-
 				redisErr = redisClient.redisConnection(config.RedisInterface)
 				redisErr = redisClient.redisConnection(config.RedisInterface)
+
 				if redisErr == nil {
 				if redisErr == nil {
-					if cData != nil {
-						// send data is using the compressor
-						_, doErr := redisClient.conn.Do("SETEX", hash, config.RedisExpireSeconds, cData)
-						if doErr != nil {
-							redisErr = doErr
-						}
-					} else {
-						// not using compressor
-						_, doErr := redisClient.conn.Do("SETEX", hash, config.RedisExpireSeconds, e.Data.String())
-						if doErr != nil {
-							redisErr = doErr
-						}
+					_, doErr := redisClient.conn.Do("SETEX", hash, config.RedisExpireSeconds, stringer)
+					if doErr != nil {
+						redisErr = doErr
 					}
 					}
 				}
 				}
 				if redisErr != nil {
 				if redisErr != nil {

+ 5 - 0
envelope/envelope.go

@@ -96,6 +96,11 @@ func (e *Envelope) ParseHeaders() error {
 	return err
 	return err
 }
 }
 
 
+// String converts the email to string. Typically, you would want to use the compressor processor for more efficiency
+func (e *Envelope) String() string {
+	return e.DeliveryHeader + e.Data.String()
+}
+
 var mimeRegex, _ = regexp.Compile(`=\?(.+?)\?([QBqp])\?(.+?)\?=`)
 var mimeRegex, _ = regexp.Compile(`=\?(.+?)\?([QBqp])\?(.+?)\?=`)
 
 
 // Decode strings in Mime header format
 // Decode strings in Mime header format