s_mimeanalyzer.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package backends
  2. import (
  3. "github.com/flashmob/go-guerrilla/mail"
  4. "github.com/flashmob/go-guerrilla/mail/mimeparse"
  5. )
  6. // ----------------------------------------------------------------------------------
  7. // Name : Mime Analyzer
  8. // ----------------------------------------------------------------------------------
  9. // Description : Analyse the MIME structure of a stream.
  10. // : Headers of each part are unfolded and saved in a *mime.Parts struct.
  11. // : No decoding or any other processing.
  12. // ----------------------------------------------------------------------------------
  13. // Config Options:
  14. // --------------:-------------------------------------------------------------------
  15. // Input :
  16. // ----------------------------------------------------------------------------------
  17. // Output : MimeParts (of type *mime.Parts) stored in the envelope.MimeParts field
  18. // ----------------------------------------------------------------------------------
  19. func init() {
  20. Streamers["mimeanalyzer"] = func() *StreamDecorator {
  21. return StreamMimeAnalyzer()
  22. }
  23. }
  24. func StreamMimeAnalyzer() *StreamDecorator {
  25. sd := &StreamDecorator{}
  26. var (
  27. envelope *mail.Envelope
  28. mimeErr error
  29. parser *mimeparse.Parser
  30. )
  31. sd.Configure = func(cfg ConfigGroup) error {
  32. parser = mimeparse.NewMimeParser()
  33. return nil
  34. }
  35. sd.Shutdown = func() error {
  36. // assumed that parser has been closed, but we can call close again just to make sure
  37. _ = parser.Close()
  38. parser = nil
  39. return nil
  40. }
  41. sd.Decorate =
  42. func(sp StreamProcessor, a ...interface{}) StreamProcessor {
  43. sd.Open = func(e *mail.Envelope) error {
  44. parser.Open()
  45. envelope = e
  46. mimeErr = nil
  47. envelope.MimeError = nil
  48. return nil
  49. }
  50. sd.Close = func() error {
  51. closeErr := parser.Close()
  52. if mimeErr == nil {
  53. mimeErr = closeErr
  54. }
  55. envelope.MimeError = mimeErr
  56. if mimeErr != nil {
  57. Log().WithError(closeErr).Warn("mime parse error in mimeanalyzer on close")
  58. envelope.MimeError = nil
  59. if err, ok := mimeErr.(*mimeparse.Error); ok && err.ParseError() {
  60. // dont propagate parse errors && NotMime error
  61. return nil
  62. }
  63. }
  64. return mimeErr
  65. }
  66. return StreamProcessWith(func(p []byte) (int, error) {
  67. if envelope.MimeParts == nil {
  68. envelope.MimeParts = &parser.Parts
  69. }
  70. if mimeErr == nil {
  71. mimeErr = parser.Parse(p)
  72. if mimeErr != nil {
  73. Log().WithError(mimeErr).Warn("mime parse error in mimeanalyzer")
  74. }
  75. }
  76. return sp.Write(p)
  77. })
  78. }
  79. return sd
  80. }