1
0
mirror of https://github.com/axllent/mailpit.git synced 2025-05-21 22:33:29 +02:00

Chore: Minor speed & memory improvements when storing messages

This commit is contained in:
Ralph Slooten 2025-02-23 11:14:47 +13:00
parent 284e66f0ba
commit aafd2a20d9
3 changed files with 20 additions and 40 deletions

View File

@ -34,7 +34,7 @@ func mailHandler(origin net.Addr, from string, to []string, data []byte) (string
// SaveToDatabase will attempt to save a message to the database
func SaveToDatabase(origin net.Addr, from string, to []string, data []byte) (string, error) {
if !config.SMTPStrictRFCHeaders {
if !config.SMTPStrictRFCHeaders && bytes.Contains(data, []byte("\r\r\n")) {
// replace all <CR><CR><LF> (\r\r\n) with <CR><LF> (\r\n)
// @see https://github.com/axllent/mailpit/issues/87 & https://github.com/axllent/mailpit/issues/153
data = bytes.ReplaceAll(data, []byte("\r\r\n"), []byte("\r\n"))
@ -50,21 +50,9 @@ func SaveToDatabase(origin net.Addr, from string, to []string, data []byte) (str
// check / set the Return-Path based on SMTP from
returnPath := strings.Trim(msg.Header.Get("Return-Path"), "<>")
if returnPath != from {
if returnPath != "" {
// replace Return-Path
re := regexp.MustCompile(`(?i)(^|\n)(Return\-Path: .*\n)`)
replaced := false
data = re.ReplaceAllFunc(data, func(r []byte) []byte {
if replaced {
return r
}
replaced = true // only replace first occurrence
return re.ReplaceAll(r, []byte("${1}Return-Path: <"+from+">\r\n"))
})
} else {
// add Return-Path
data = append([]byte("Return-Path: <"+from+">\r\n"), data...)
data, err = tools.SetMessageHeader(data, "Return-Path", "<"+from+">")
if err != nil {
return "", err
}
}
@ -108,23 +96,15 @@ func SaveToDatabase(origin net.Addr, from string, to []string, data []byte) (str
// add missing email addresses to Bcc (eg: Laravel doesn't include these in the headers)
if len(missingAddresses) > 0 {
bccVal := strings.Join(missingAddresses, ", ")
if hasBccHeader {
// email already has Bcc header, add to existing addresses
re := regexp.MustCompile(`(?i)(^|\n)(Bcc: )`)
replaced := false
data = re.ReplaceAllFunc(data, func(r []byte) []byte {
if replaced {
return r
b := msg.Header.Get("Bcc")
bccVal = ", " + b
}
replaced = true // only replace first occurrence
return re.ReplaceAll(r, []byte("${1}Bcc: "+strings.Join(missingAddresses, ", ")+", "))
})
} else {
// prepend new Bcc header
bcc := []byte(fmt.Sprintf("Bcc: %s\r\n", strings.Join(missingAddresses, ", ")))
data = append(bcc, data...)
data, err = tools.SetMessageHeader(data, "Bcc", bccVal)
if err != nil {
return "", err
}
logger.Log().Debugf("[smtpd] added missing addresses to Bcc header: %s", strings.Join(missingAddresses, ", "))

View File

@ -58,8 +58,10 @@ func RemoveMessageHeaders(msg []byte, headers []string) ([]byte, error) {
return msg, nil
}
// UpdateMessageHeader scans a message for a header and updates its value if found.
func UpdateMessageHeader(msg []byte, header, value string) ([]byte, error) {
// SetMessageHeader scans a message for a header and updates its value if found.
// It does not consider multiple instances of the same header.
// If not found it will add the header to the beginning of the message.
func SetMessageHeader(msg []byte, header, value string) ([]byte, error) {
reader := bytes.NewReader(msg)
m, err := mail.ReadMessage(reader)
if err != nil {
@ -90,13 +92,11 @@ func UpdateMessageHeader(msg []byte, header, value string) ([]byte, error) {
}
}
if len(hdr) > 0 {
logger.Log().Debugf("[relay] replaced %s header", hdr)
msg = bytes.Replace(msg, hdr, []byte(header+": "+value+"\r\n"), 1)
}
return bytes.Replace(msg, hdr, []byte(header+": "+value+"\r\n"), 1), nil
}
return msg, nil
// no header, so add one to beginning
return append([]byte(header+": "+value+"\r\n"), msg...), nil
}
// OverrideFromHeader scans a message for the From header and replaces it with a different email address.

View File

@ -170,7 +170,7 @@ func ReleaseMessage(w http.ResponseWriter, r *http.Request) {
}
// update message date
msg, err = tools.UpdateMessageHeader(msg, "Date", time.Now().Format(time.RFC1123Z))
msg, err = tools.SetMessageHeader(msg, "Date", time.Now().Format(time.RFC1123Z))
if err != nil {
httpError(w, err.Error())
return
@ -179,7 +179,7 @@ func ReleaseMessage(w http.ResponseWriter, r *http.Request) {
// generate unique ID
uid := shortuuid.New() + "@mailpit"
// update Message-Id with unique ID
msg, err = tools.UpdateMessageHeader(msg, "Message-Id", "<"+uid+">")
msg, err = tools.SetMessageHeader(msg, "Message-Id", "<"+uid+">")
if err != nil {
httpError(w, err.Error())
return