envelope.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package smtpd
  2. import (
  3. "io"
  4. "net/mail"
  5. "strings"
  6. baseSmtpd "github.com/bradfitz/go-smtpd/smtpd"
  7. "github.com/go-xweb/log"
  8. )
  9. type DemoEnvelope struct {
  10. SmtpNetwork string `json:"-"`
  11. SmtpRemote string `json:"-"`
  12. MailFrom baseSmtpd.MailAddress `json:"mail_from"`
  13. RcptTo baseSmtpd.MailAddress `json:"rcpt_to"`
  14. Lines strings.Builder `json:"lines"`
  15. }
  16. func (d *DemoEnvelope) AddRecipient(rcpt baseSmtpd.MailAddress) error {
  17. log.Printf("Inbound email from %s for %s", d.MailFrom.Email(), rcpt)
  18. d.RcptTo = rcpt
  19. return nil
  20. }
  21. func (d *DemoEnvelope) BeginData() error {
  22. d.Lines = strings.Builder{}
  23. return nil
  24. }
  25. func (d *DemoEnvelope) Write(line []byte) error {
  26. d.Lines.Write(line)
  27. return nil
  28. }
  29. func (d *DemoEnvelope) Close() error {
  30. msg, err := d.Parse()
  31. if err == nil {
  32. d.Handle(*msg)
  33. }
  34. return nil
  35. }
  36. func (d DemoEnvelope) Handle(message mail.Message) {
  37. //for i, h := range message.Header {
  38. // first := h[0]
  39. // if len(h[1:]) > 0 {
  40. // log.Printf("%-10s %s(+more)\n", i, first)
  41. // } else {
  42. // log.Printf("%-10s %s\n", i, first)
  43. // }
  44. //}
  45. parser := mail.AddressParser{}
  46. from, err := parser.Parse(message.Header.Get("From"))
  47. if err != nil {
  48. log.Errorf("Error parsing From: header: %v\n", err)
  49. from = &mail.Address{}
  50. }
  51. if from.Name == "" {
  52. from.Name = "(no From name)"
  53. }
  54. to, err := parser.Parse(message.Header.Get("To"))
  55. if err != nil {
  56. log.Errorf("Error parsing To: header: %v\n", err)
  57. to = &mail.Address{}
  58. }
  59. if to.Name == "" {
  60. to.Name = "(no To name)"
  61. }
  62. subject := message.Header.Get("Subject")
  63. body, err := io.ReadAll(message.Body)
  64. if err != nil {
  65. log.Errorf("Error reading body: %v", err)
  66. }
  67. log.Printf("From: %-20s (%s)\n", from.Name, from.Address)
  68. log.Printf("To: %-20s (%s)\n", to.Name, to.Address)
  69. log.Printf("Subject: %s\n", subject)
  70. log.Printf("Message:\n%s\n", string(body))
  71. }
  72. func (d DemoEnvelope) Parse() (*mail.Message, error) {
  73. reader := strings.NewReader(d.Lines.String())
  74. message, err := mail.ReadMessage(reader)
  75. if err != nil {
  76. log.Errorf("Error reading submitted message: %v", err)
  77. return &mail.Message{}, err
  78. }
  79. return message, nil
  80. }