Add option to convert CRLF to LF line endings for sendmail (#18075)
It appears that several versions of sendmail require that the mail is sent to them with LF line endings instead of CRLF endings - which of course they will then convert back to CRLF line endings to comply with the SMTP standard. This PR adds another setting SENDMAIL_CONVERT_CRLF which will pass the message writer through a filter. This will filter out and convert CRLFs to LFs before writing them out to sendmail. Fix #18024 Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
parent
bf7b083cfe
commit
1514e13bb8
4 changed files with 20 additions and 7 deletions
|
@ -1494,6 +1494,9 @@ PATH =
|
||||||
;;
|
;;
|
||||||
;; Timeout for Sendmail
|
;; Timeout for Sendmail
|
||||||
;SENDMAIL_TIMEOUT = 5m
|
;SENDMAIL_TIMEOUT = 5m
|
||||||
|
;;
|
||||||
|
;; convert \r\n to \n for Sendmail
|
||||||
|
;SENDMAIL_CONVERT_CRLF = true
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -667,6 +667,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
|
||||||
command or full path).
|
command or full path).
|
||||||
- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments.
|
- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments.
|
||||||
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
|
||||||
|
- `SENDMAIL_CONVERT_CRLF`: **true**: Most versions of sendmail prefer LF line endings rather than CRLF line endings. Set this to false if your version of sendmail requires CRLF line endings.
|
||||||
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`
|
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`
|
||||||
|
|
||||||
## Cache (`cache`)
|
## Cache (`cache`)
|
||||||
|
|
|
@ -40,6 +40,7 @@ type Mailer struct {
|
||||||
SendmailPath string
|
SendmailPath string
|
||||||
SendmailArgs []string
|
SendmailArgs []string
|
||||||
SendmailTimeout time.Duration
|
SendmailTimeout time.Duration
|
||||||
|
SendmailConvertCRLF bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -73,6 +74,7 @@ func newMailService() {
|
||||||
|
|
||||||
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
|
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
|
||||||
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
|
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
|
||||||
|
SendmailConvertCRLF: sec.Key("SENDMAIL_CONVERT_CRLF").MustBool(true),
|
||||||
}
|
}
|
||||||
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
MailService.From = sec.Key("FROM").MustString(MailService.User)
|
||||||
MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("")
|
MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("")
|
||||||
|
|
|
@ -290,13 +290,20 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if setting.MailService.SendmailConvertCRLF {
|
||||||
|
buf := &strings.Builder{}
|
||||||
|
_, err = msg.WriteTo(buf)
|
||||||
|
if err == nil {
|
||||||
|
_, err = strings.NewReplacer("\r\n", "\n").WriteString(pipe, buf.String())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
_, err = msg.WriteTo(pipe)
|
_, err = msg.WriteTo(pipe)
|
||||||
|
}
|
||||||
|
|
||||||
// we MUST close the pipe or sendmail will hang waiting for more of the message
|
// we MUST close the pipe or sendmail will hang waiting for more of the message
|
||||||
// Also we should wait on our sendmail command even if something fails
|
// Also we should wait on our sendmail command even if something fails
|
||||||
closeError = pipe.Close()
|
closeError = pipe.Close()
|
||||||
waitError = cmd.Wait()
|
waitError = cmd.Wait()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if closeError != nil {
|
} else if closeError != nil {
|
||||||
|
|
Reference in a new issue