fix: correctly close SMTP message and await response (#14495)

This commit is contained in:
Danny Kopping
2024-08-30 11:37:50 +02:00
committed by GitHub
parent 851df91991
commit c90be9b0c1
3 changed files with 27 additions and 1 deletions

View File

@ -183,7 +183,6 @@ func (s *SMTPHandler) dispatch(subject, htmlBody, plainBody, to string) Delivery
if err != nil {
return true, xerrors.Errorf("message transmission: %w", err)
}
defer message.Close()
// Create message headers.
msg := &bytes.Buffer{}
@ -251,6 +250,10 @@ func (s *SMTPHandler) dispatch(subject, htmlBody, plainBody, to string) Delivery
return false, xerrors.Errorf("write body buffer: %w", err)
}
if err = message.Close(); err != nil {
return true, xerrors.Errorf("delivery failure: %w", err)
}
// Returning false, nil indicates successful send (i.e. non-retryable non-error)
return false, nil
}

View File

@ -62,6 +62,7 @@ func TestSMTP(t *testing.T) {
expectedErr string
retryable bool
useTLS bool
failOnDataFn func() error
}{
/**
* LOGIN auth mechanism
@ -381,6 +382,21 @@ func TestSMTP(t *testing.T) {
toAddrs: []string{to},
expectedAuthMeth: sasl.Plain,
},
/**
* Other errors
*/
{
name: "Rejected on DATA",
cfg: codersdk.NotificationsEmailConfig{
Hello: hello,
From: from,
},
failOnDataFn: func() error {
return &smtp.SMTPError{Code: 501, EnhancedCode: smtp.EnhancedCode{5, 5, 4}, Message: "Rejected!"}
},
expectedErr: "SMTP error 501: Rejected!",
retryable: true,
},
}
// nolint:paralleltest // Reinitialization is not required as of Go v1.22.
@ -398,6 +414,8 @@ func TestSMTP(t *testing.T) {
AcceptedIdentity: tc.cfg.Auth.Identity.String(),
AcceptedUsername: username,
AcceptedPassword: password,
FailOnDataFn: tc.failOnDataFn,
})
// Create a mock SMTP server which conditionally listens for plain or TLS connections.

View File

@ -24,6 +24,7 @@ var (
type Config struct {
AuthMechanisms []string
AcceptedIdentity, AcceptedUsername, AcceptedPassword string
FailOnDataFn func() error
}
type Message struct {
@ -147,6 +148,10 @@ func (s *Session) Data(r io.Reader) error {
return err
}
if s.backend.cfg.FailOnDataFn != nil {
return s.backend.cfg.FailOnDataFn()
}
s.backend.lastMsg.Contents = string(b)
return nil