92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
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
|
|
}
|