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:
parent
284e66f0ba
commit
aafd2a20d9
@ -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
|
// SaveToDatabase will attempt to save a message to the database
|
||||||
func SaveToDatabase(origin net.Addr, from string, to []string, data []byte) (string, error) {
|
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)
|
// 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
|
// @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"))
|
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
|
// check / set the Return-Path based on SMTP from
|
||||||
returnPath := strings.Trim(msg.Header.Get("Return-Path"), "<>")
|
returnPath := strings.Trim(msg.Header.Get("Return-Path"), "<>")
|
||||||
if returnPath != from {
|
if returnPath != from {
|
||||||
if returnPath != "" {
|
data, err = tools.SetMessageHeader(data, "Return-Path", "<"+from+">")
|
||||||
// replace Return-Path
|
if err != nil {
|
||||||
re := regexp.MustCompile(`(?i)(^|\n)(Return\-Path: .*\n)`)
|
return "", err
|
||||||
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...)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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)
|
// add missing email addresses to Bcc (eg: Laravel doesn't include these in the headers)
|
||||||
if len(missingAddresses) > 0 {
|
if len(missingAddresses) > 0 {
|
||||||
|
bccVal := strings.Join(missingAddresses, ", ")
|
||||||
if hasBccHeader {
|
if hasBccHeader {
|
||||||
// email already has Bcc header, add to existing addresses
|
b := msg.Header.Get("Bcc")
|
||||||
re := regexp.MustCompile(`(?i)(^|\n)(Bcc: )`)
|
bccVal = ", " + b
|
||||||
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}Bcc: "+strings.Join(missingAddresses, ", ")+", "))
|
data, err = tools.SetMessageHeader(data, "Bcc", bccVal)
|
||||||
})
|
if err != nil {
|
||||||
|
return "", err
|
||||||
} else {
|
|
||||||
// prepend new Bcc header
|
|
||||||
bcc := []byte(fmt.Sprintf("Bcc: %s\r\n", strings.Join(missingAddresses, ", ")))
|
|
||||||
data = append(bcc, data...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Log().Debugf("[smtpd] added missing addresses to Bcc header: %s", strings.Join(missingAddresses, ", "))
|
logger.Log().Debugf("[smtpd] added missing addresses to Bcc header: %s", strings.Join(missingAddresses, ", "))
|
||||||
|
@ -58,8 +58,10 @@ func RemoveMessageHeaders(msg []byte, headers []string) ([]byte, error) {
|
|||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateMessageHeader scans a message for a header and updates its value if found.
|
// SetMessageHeader scans a message for a header and updates its value if found.
|
||||||
func UpdateMessageHeader(msg []byte, header, value string) ([]byte, error) {
|
// 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)
|
reader := bytes.NewReader(msg)
|
||||||
m, err := mail.ReadMessage(reader)
|
m, err := mail.ReadMessage(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -90,13 +92,11 @@ func UpdateMessageHeader(msg []byte, header, value string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(hdr) > 0 {
|
return bytes.Replace(msg, hdr, []byte(header+": "+value+"\r\n"), 1), nil
|
||||||
logger.Log().Debugf("[relay] replaced %s header", hdr)
|
|
||||||
msg = bytes.Replace(msg, hdr, []byte(header+": "+value+"\r\n"), 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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.
|
// OverrideFromHeader scans a message for the From header and replaces it with a different email address.
|
||||||
|
@ -170,7 +170,7 @@ func ReleaseMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update message date
|
// 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 {
|
if err != nil {
|
||||||
httpError(w, err.Error())
|
httpError(w, err.Error())
|
||||||
return
|
return
|
||||||
@ -179,7 +179,7 @@ func ReleaseMessage(w http.ResponseWriter, r *http.Request) {
|
|||||||
// generate unique ID
|
// generate unique ID
|
||||||
uid := shortuuid.New() + "@mailpit"
|
uid := shortuuid.New() + "@mailpit"
|
||||||
// update Message-Id with unique ID
|
// 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 {
|
if err != nil {
|
||||||
httpError(w, err.Error())
|
httpError(w, err.Error())
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user