Remove unused fields, change way we generat message
j3s j3s@c3f.net
Thu, 16 Jan 2020 16:51:14 -0600
2 files changed,
47 insertions(+),
105 deletions(-)
M
mail/main.go
→
mail/main.go
@@ -2,18 +2,22 @@ package parsemail
import ( "bytes" - "fmt" "io" "io/ioutil" "mime" "net/mail" "strings" - "time" ) // Parse an email message read from io.Reader into parsemail.Email struct func Parse(r io.Reader) (email Email, err error) { - msg, err := mail.ReadMessage(r) + b, err := ioutil.ReadAll(r) + if err != nil { + return + } + + reader := bytes.NewReader(b) + msg, err := mail.ReadMessage(reader) if err != nil { return }@@ -23,8 +27,7 @@ if err != nil {
return } - body, _ := ioutil.ReadAll(msg.Body) - email.Body = string(body) + email.Bytes = b return }@@ -39,17 +42,6 @@ email.ReplyTo = hp.parseAddressList(header.Get("Reply-To"))
email.To = hp.parseAddressList(header.Get("To")) email.Cc = hp.parseAddressList(header.Get("Cc")) email.Bcc = hp.parseAddressList(header.Get("Bcc")) - email.Date = hp.parseTime(header.Get("Date")) - email.ResentFrom = hp.parseAddressList(header.Get("Resent-From")) - email.ResentSender = hp.parseAddress(header.Get("Resent-Sender")) - email.ResentTo = hp.parseAddressList(header.Get("Resent-To")) - email.ResentCc = hp.parseAddressList(header.Get("Resent-Cc")) - email.ResentBcc = hp.parseAddressList(header.Get("Resent-Bcc")) - email.ResentMessageID = hp.parseMessageId(header.Get("Resent-Message-ID")) - email.MessageID = hp.parseMessageId(header.Get("Message-ID")) - email.InReplyTo = hp.parseMessageIdList(header.Get("In-Reply-To")) - email.References = hp.parseMessageIdList(header.Get("References")) - email.ResentDate = hp.parseTime(header.Get("Resent-Date")) if hp.err != nil { err = hp.err@@ -135,53 +127,10 @@
return } -func (hp headerParser) parseTime(s string) (t time.Time) { - if hp.err != nil || s == "" { - return - } - - t, hp.err = time.Parse(time.RFC1123Z, s) - if hp.err == nil { - return t - } - - t, hp.err = time.Parse("Mon, 2 Jan 2006 15:04:05 -0700", s) - - return -} - -func (hp headerParser) parseMessageId(s string) string { - if hp.err != nil { - return "" - } - - return strings.Trim(s, "<> ") -} - -func (hp headerParser) parseMessageIdList(s string) (result []string) { - if hp.err != nil { - return - } - - for _, p := range strings.Split(s, " ") { - if strings.Trim(p, " \n") != "" { - result = append(result, hp.parseMessageId(p)) - } - } - - return -} - func (e *Email) ToBytes() []byte { var buf bytes.Buffer - - // print the headers in whatever darn order, who cares - for k, v := range e.Header { - fmt.Fprintf(&buf, "%s: %s\r\n", k, strings.Join(v, " ")) - } - - fmt.Fprintf(&buf, "\r\n%s", e.Body) - + buf.Write(e.PrefixBytes) + buf.Write(e.Bytes) return buf.Bytes() }@@ -189,6 +138,7 @@ // Email with fields for all the headers defined in RFC5322 with it's attachments and
type Email struct { Header mail.Header + // read-only Subject string Sender *mail.Address From []*mail.Address@@ -196,18 +146,8 @@ ReplyTo []*mail.Address
To []*mail.Address Cc []*mail.Address Bcc []*mail.Address - Date time.Time - MessageID string - InReplyTo []string - References []string - ResentFrom []*mail.Address - ResentSender *mail.Address - ResentTo []*mail.Address - ResentDate time.Time - ResentCc []*mail.Address - ResentBcc []*mail.Address - ResentMessageID string - - Body string + // read-write + PrefixBytes []byte + Bytes []byte // All bytes that can be replayed for a successful transmission }
M
main.go
→
main.go
@@ -6,9 +6,6 @@ "bytes"
"database/sql" "flag" "fmt" - "git.cyberia.club/cyberia-services/clist/mail" - _ "github.com/mattn/go-sqlite3" - "gopkg.in/ini.v1" "io" "log" "net/mail"@@ -17,6 +14,10 @@ "os"
"regexp" "strings" "time" + + parsemail "git.cyberia.club/cyberia-services/clist/mail" + _ "github.com/mattn/go-sqlite3" + "gopkg.in/ini.v1" ) type Config struct {@@ -66,7 +67,7 @@
if flag.Arg(0) == "message" { msg, err := parsemail.Parse(bufio.NewReader(os.Stdin)) if err != nil { - log.Printf("ERROR_PARSING_MESSAGE mail=%q msg=%q error=%q\n", os.Stdin, msg, err.Error()) + log.Printf("ERROR_PARSING_MESSAGE mail=%v msg=%q error=%q\n", os.Stdin, msg, err.Error()) os.Exit(0) } log.Printf("MESSAGE_RECEIVED From=%q To=%q Cc=%q Bcc=%q Subject=%q\n",@@ -296,20 +297,17 @@ }
func buildCommandEmail(e *parsemail.Email, t bytes.Buffer) *parsemail.Email { response := parsemail.Email{} - response.Bcc = e.From + response.Bcc = e.From // return to sender - header := make(map[string][]string) - header["Sender"] = []string{gConfig.CommandAddress} - header["From"] = []string{gConfig.CommandAddress} - header["To"] = []string{e.Header.Get("From")} - header["Subject"] = []string{"Re: " + e.Subject} - header["Date"] = []string{time.Now().Format("Mon, 2 Jan 2006 15:04:05 -0700")} - header["Precedence"] = []string{"list"} - header["List-Help"] = []string{"<mailto:" + gConfig.CommandAddress + "?subject=help>"} - response.Header = header - response.Bcc = e.From - response.Body = t.String() - log.Printf("%q", response) + mail := "Sender: " + gConfig.CommandAddress + "\r\n" + + "From: " + gConfig.CommandAddress + "\r\n" + + "To: " + e.Header.Get("From") + "\r\n" + + "Precedence: list\r\n" + + "Subject: Re: " + e.Subject + "\r\n" + + "Date: " + time.Now().Format("Mon, 2 Jan 2006 15:04:05 -0700") + "\r\n\r\n" + + t.String() + + response.Bytes = []byte(mail) return &response }@@ -327,23 +325,27 @@ // Build recipient list, stripping garbage
var recipients []*mail.Address for _, subscriber := range fetchSubscribers(l.Id) { if !badAddress(subscriber, e) { - recipients = append(recipients, &mail.Address{"", subscriber}) + recipients = append(recipients, &mail.Address{Name: "", Address: subscriber}) } } + email := e + email.Bcc = recipients - post := e - post.Bcc = recipients - post.Header["Sender"] = []string{l.Address} - post.Header["Return-Path"] = []string{"bounce-" + l.Address} - post.Header["Precedence"] = []string{"list"} - post.Header["List-Id"] = []string{"<" + strings.Replace(l.Address, "@", ".", -1) + ">"} - post.Header["List-Post"] = []string{"<mailto:" + l.Address + ">"} - post.Header["List-Help"] = []string{"<mailto:" + l.Address + "?subject=help>"} - post.Header["List-Subscribe"] = []string{"<mailto:" + gConfig.CommandAddress + "?subject=subscribe%20" + l.Id + ">"} - post.Header["List-Unsubscribe"] = []string{"<mailto:" + gConfig.CommandAddress + "?subject=unsubscribe%20" + l.Id + ">"} - post.Header["List-Archive"] = []string{"<" + l.Archive + ">"} - post.Header["List-Owner"] = []string{"<" + l.Owner + ">"} - return post + // Set extra headers + xtra := "Sender: " + l.Address + "\r\n" + + "Return-Path: bounce-" + l.Address + "\r\n" + + "Precedence: list\r\n" + + "List-Id: <" + strings.Replace(l.Address, "@", ".", -1) + ">\r\n" + + "List-Post: <mailto:" + l.Address + ">\r\n" + + "List-Subscribe: <mailto:" + gConfig.CommandAddress + "?subject=subscribe%20" + l.Id + ">\r\n" + + "List-Unsubscribe: <mailto:" + gConfig.CommandAddress + "?subject=unsubscribe%20" + l.Id + ">\r\n" + + "List-Help: <mailto:" + l.Address + "?subject=help>\r\n" + + "List-Archive: <" + l.Archive + ">\r\n" + + "List-Owner: <" + l.Owner + ">\r\n" + + email.PrefixBytes = []byte(xtra) + + return email } func send(e *parsemail.Email) {