s_header.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package backends
  2. import (
  3. "github.com/flashmob/go-guerrilla/mail"
  4. "io"
  5. "strings"
  6. "time"
  7. )
  8. // ----------------------------------------------------------------------------------
  9. // Processor Name: header
  10. // ----------------------------------------------------------------------------------
  11. // Description : Adds delivery information headers to e.DeliveryHeader
  12. // ----------------------------------------------------------------------------------
  13. // Config Options: primary_mail_host - string of the primary mail hostname
  14. // --------------:-------------------------------------------------------------------
  15. // Input : e.Helo
  16. // : e.RemoteAddress
  17. // : e.RcptTo
  18. // : e.Hashes
  19. // ----------------------------------------------------------------------------------
  20. // Output : Sets e.DeliveryHeader with additional delivery info
  21. // ----------------------------------------------------------------------------------
  22. func init() {
  23. Streamers["header"] = func() *StreamDecorator {
  24. return StreamHeader()
  25. }
  26. }
  27. type streamHeader struct {
  28. addHead []byte
  29. w io.Writer
  30. i int
  31. }
  32. func newStreamHeader(w io.Writer) *streamHeader {
  33. sc := new(streamHeader)
  34. sc.w = w
  35. return sc
  36. }
  37. func (sh *streamHeader) addHeader(e *mail.Envelope, config *headerConfig) {
  38. to := strings.TrimSpace(e.RcptTo[0].User) + "@" + config.PrimaryHost
  39. hash := "unknown"
  40. if len(e.Hashes) > 0 {
  41. hash = e.Hashes[0]
  42. }
  43. var addHead string
  44. addHead += "Delivered-To: " + to + "\n"
  45. addHead += "Received: from " + e.Helo + " (" + e.Helo + " [" + e.RemoteIP + "])\n"
  46. if len(e.RcptTo) > 0 {
  47. addHead += " by " + e.RcptTo[0].Host + " with SMTP id " + hash + "@" + e.RcptTo[0].Host + ";\n"
  48. }
  49. addHead += " " + time.Now().Format(time.RFC1123Z) + "\n"
  50. sh.addHead = []byte(addHead)
  51. }
  52. func StreamHeader() *StreamDecorator {
  53. hc := headerConfig{}
  54. sd := &StreamDecorator{}
  55. sd.Configure = func(cfg ConfigGroup) error {
  56. return sd.ExtractConfig(cfg, &hc)
  57. }
  58. sd.Decorate =
  59. func(sp StreamProcessor, a ...interface{}) StreamProcessor {
  60. var sh *streamHeader
  61. sd.Open = func(e *mail.Envelope) error {
  62. sh = newStreamHeader(sp)
  63. sh.addHeader(e, &hc)
  64. return nil
  65. }
  66. return StreamProcessWith(func(p []byte) (int, error) {
  67. if sh.i < len(sh.addHead) {
  68. for {
  69. if N, err := sh.w.Write(sh.addHead[sh.i:]); err != nil {
  70. return N, err
  71. } else {
  72. sh.i += N
  73. if sh.i >= len(sh.addHead) {
  74. break
  75. }
  76. }
  77. }
  78. }
  79. return sp.Write(p)
  80. })
  81. }
  82. return sd
  83. }