package smtpd import ( "io" "net/mail" "strings" baseSmtpd "github.com/bradfitz/go-smtpd/smtpd" "github.com/go-xweb/log" ) type DemoEnvelope struct { SmtpNetwork string `json:"-"` SmtpRemote string `json:"-"` MailFrom baseSmtpd.MailAddress `json:"mail_from"` RcptTo baseSmtpd.MailAddress `json:"rcpt_to"` Lines strings.Builder `json:"lines"` } func (d *DemoEnvelope) AddRecipient(rcpt baseSmtpd.MailAddress) error { log.Printf("Inbound email from %s for %s", d.MailFrom.Email(), rcpt) d.RcptTo = rcpt return nil } func (d *DemoEnvelope) BeginData() error { d.Lines = strings.Builder{} return nil } func (d *DemoEnvelope) Write(line []byte) error { d.Lines.Write(line) return nil } func (d *DemoEnvelope) Close() error { msg, err := d.Parse() if err == nil { d.Handle(*msg) } return nil } func (d DemoEnvelope) Handle(message mail.Message) { //for i, h := range message.Header { // first := h[0] // if len(h[1:]) > 0 { // log.Printf("%-10s %s(+more)\n", i, first) // } else { // log.Printf("%-10s %s\n", i, first) // } //} parser := mail.AddressParser{} from, err := parser.Parse(message.Header.Get("From")) if err != nil { log.Errorf("Error parsing From: header: %v\n", err) from = &mail.Address{} } if from.Name == "" { from.Name = "(no From name)" } to, err := parser.Parse(message.Header.Get("To")) if err != nil { log.Errorf("Error parsing To: header: %v\n", err) to = &mail.Address{} } if to.Name == "" { to.Name = "(no To name)" } subject := message.Header.Get("Subject") body, err := io.ReadAll(message.Body) if err != nil { log.Errorf("Error reading body: %v", err) } log.Printf("From: %-20s (%s)\n", from.Name, from.Address) log.Printf("To: %-20s (%s)\n", to.Name, to.Address) log.Printf("Subject: %s\n", subject) log.Printf("Message:\n%s\n", string(body)) } func (d DemoEnvelope) Parse() (*mail.Message, error) { reader := strings.NewReader(d.Lines.String()) message, err := mail.ReadMessage(reader) if err != nil { log.Errorf("Error reading submitted message: %v", err) return &mail.Message{}, err } return message, nil }