Skip to content

Commit 4f9d59b

Browse files
authored
Sendmail should create a process on the gitea system and have a default timeout (#11256)
* Make sure that sendmail processes register with the process manager * Provide a timeout for these (initially of 5 minutes) * Add configurable value and tie in to documentation * Tie in to the admin config page. Signed-off-by: Andrew Thornton <[email protected]>
1 parent 319eb83 commit 4f9d59b

File tree

6 files changed

+25
-4
lines changed

6 files changed

+25
-4
lines changed

custom/conf/app.ini.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,8 @@ MAILER_TYPE = smtp
649649
SENDMAIL_PATH = sendmail
650650
; Specify any extra sendmail arguments
651651
SENDMAIL_ARGS =
652+
; Timeout for Sendmail
653+
SENDMAIL_TIMEOUT = 5m
652654

653655
[cache]
654656
; if the cache enabled

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ set name for unique queues. Individual queues will default to
410410
- Enabling dummy will ignore all settings except `ENABLED`, `SUBJECT_PREFIX` and `FROM`.
411411
- `SENDMAIL_PATH`: **sendmail**: The location of sendmail on the operating system (can be
412412
command or full path).
413+
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
413414
- ``IS_TLS_ENABLED`` : **false** : Decide if SMTP connections should use TLS.
414415

415416
## Cache (`cache`)

modules/setting/mailer.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package setting
66

77
import (
88
"net/mail"
9+
"time"
910

1011
"code.gitea.io/gitea/modules/log"
1112

@@ -35,8 +36,9 @@ type Mailer struct {
3536
IsTLSEnabled bool
3637

3738
// Sendmail sender
38-
SendmailPath string
39-
SendmailArgs []string
39+
SendmailPath string
40+
SendmailArgs []string
41+
SendmailTimeout time.Duration
4042
}
4143

4244
var (
@@ -69,7 +71,8 @@ func newMailService() {
6971
IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(),
7072
SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""),
7173

72-
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
74+
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
75+
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
7376
}
7477
MailService.From = sec.Key("FROM").MustString(MailService.User)
7578

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2119,6 +2119,7 @@ config.mailer_user = User
21192119
config.mailer_use_sendmail = Use Sendmail
21202120
config.mailer_sendmail_path = Sendmail Path
21212121
config.mailer_sendmail_args = Extra Arguments to Sendmail
2122+
config.mailer_sendmail_timeout = Sendmail Timeout
21222123
config.send_test_mail = Send Testing Email
21232124
config.test_mail_failed = Failed to send a testing email to '%s': %v
21242125
config.test_mail_sent = A testing email has been sent to '%s'.

services/mailer/mailer.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package mailer
77

88
import (
99
"bytes"
10+
"context"
1011
"crypto/tls"
1112
"fmt"
1213
"io"
@@ -20,6 +21,7 @@ import (
2021
"code.gitea.io/gitea/modules/base"
2122
"code.gitea.io/gitea/modules/graceful"
2223
"code.gitea.io/gitea/modules/log"
24+
"code.gitea.io/gitea/modules/process"
2325
"code.gitea.io/gitea/modules/queue"
2426
"code.gitea.io/gitea/modules/setting"
2527

@@ -244,7 +246,14 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
244246
args = append(args, setting.MailService.SendmailArgs...)
245247
args = append(args, to...)
246248
log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args)
247-
cmd := exec.Command(setting.MailService.SendmailPath, args...)
249+
250+
pm := process.GetManager()
251+
desc := fmt.Sprintf("SendMail: %s %v", setting.MailService.SendmailPath, args)
252+
253+
ctx, cancel := context.WithTimeout(graceful.GetManager().HammerContext(), setting.MailService.SendmailTimeout)
254+
defer cancel()
255+
256+
cmd := exec.CommandContext(ctx, setting.MailService.SendmailPath, args...)
248257
pipe, err := cmd.StdinPipe()
249258

250259
if err != nil {
@@ -255,12 +264,15 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
255264
return err
256265
}
257266

267+
pid := pm.Add(desc, cancel)
268+
258269
_, err = msg.WriteTo(pipe)
259270

260271
// we MUST close the pipe or sendmail will hang waiting for more of the message
261272
// Also we should wait on our sendmail command even if something fails
262273
closeError = pipe.Close()
263274
waitError = cmd.Wait()
275+
pm.Remove(pid)
264276
if err != nil {
265277
return err
266278
} else if closeError != nil {

templates/admin/config.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@
228228
<dd>{{.Mailer.SendmailPath}}</dd>
229229
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_args"}}</dt>
230230
<dd>{{.Mailer.SendmailArgs}}</dd>
231+
<dt>{{.i18n.Tr "admin.config.mailer_sendmail_timeout"}}</dt>
232+
<dd>{{.Mailer.SendmailTimeout}} {{.i18n.Tr "tool.raw_seconds"}}</dd>
231233
{{end}}
232234
<dt>{{.i18n.Tr "admin.config.mailer_user"}}</dt>
233235
<dd>{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}</dd><br>

0 commit comments

Comments
 (0)