s_header.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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. var hc *HeaderConfig
  54. Svc.AddInitializer(InitializeWith(func(backendConfig BackendConfig) error {
  55. configType := BaseConfig(&HeaderConfig{})
  56. bcfg, err := Svc.ExtractConfig(backendConfig, configType)
  57. if err != nil {
  58. return err
  59. }
  60. hc = bcfg.(*HeaderConfig)
  61. return nil
  62. }))
  63. sd := &StreamDecorator{}
  64. sd.Decorate =
  65. func(sp StreamProcessor, a ...interface{}) StreamProcessor {
  66. var sh *streamHeader
  67. sd.Open = func(e *mail.Envelope) error {
  68. sh = newStreamHeader(sp)
  69. sh.addHeader(e, hc)
  70. return nil
  71. }
  72. return StreamProcessWith(func(p []byte) (int, error) {
  73. if sh.i < len(sh.addHead) {
  74. for {
  75. if N, err := sh.w.Write(sh.addHead[sh.i:]); err != nil {
  76. return N, err
  77. } else {
  78. sh.i += N
  79. if sh.i >= len(sh.addHead) {
  80. break
  81. }
  82. }
  83. }
  84. }
  85. return sp.Write(p)
  86. })
  87. }
  88. return sd
  89. }