git » chasquid » commit a5edd90

queue: Make DSN tidier, especially in handling multi-line errors

author Alberto Bertogli
2019-05-04 20:23:40 UTC
committer Alberto Bertogli
2019-05-04 20:28:07 UTC
parent cac1e161aca1dbc56d89fe18b9eed8171e8c8a69

queue: Make DSN tidier, especially in handling multi-line errors

This patch contains some changes to generate tidier DSNs, which should
make them slightly more readable.

In particular, it also makes it able to handle multi-line errors much
better than before.

internal/queue/dsn.go +21 -8
internal/queue/dsn_test.go +40 -5
test/t-05-null_address/expected_dsr +1 -0

diff --git a/internal/queue/dsn.go b/internal/queue/dsn.go
index 96783be..c859f83 100644
--- a/internal/queue/dsn.go
+++ b/internal/queue/dsn.go
@@ -3,6 +3,7 @@ package queue
 import (
 	"bytes"
 	"net/mail"
+	"strings"
 	"text/template"
 	"time"
 )
@@ -84,8 +85,18 @@ type dsnInfo struct {
 	Boundary string
 }
 
+// indent s with the given number of spaces.
+func indent(sp int, s string) string {
+	pad := strings.Repeat(" ", sp)
+	return strings.Replace(s, "\n", "\n"+pad, -1)
+}
+
 var dsnTemplate = template.Must(
-	template.New("dsn").Parse(
+	template.New("dsn").Funcs(
+		template.FuncMap{
+			"indent": indent,
+			"trim":   strings.TrimSpace,
+		}).Parse(
 		`From: Mail Delivery System <postmaster-dsn@{{.OurDomain}}>
 To: <{{.Destination}}>
 Subject: Mail delivery failed: returning message to sender
@@ -108,17 +119,17 @@ Content-Transfer-Encoding: 8bit
 
 Delivery of your message to the following recipient(s) failed permanently:
 
-  {{range .FailedTo -}} - {{.}}
-  {{- end}}
+{{range .FailedTo}}  - {{.}}
+{{end}}
 
 Technical details:
 {{- range .FailedRecipients}}
 - "{{.Address}}" ({{.Type}}) failed permanently with error:
-    {{.LastFailureMessage}}
+    {{.LastFailureMessage | trim | indent 4}}
 {{- end}}
 {{- range .PendingRecipients}}
 - "{{.Address}}" ({{.Type}}) failed repeatedly and timed out, last error:
-    {{.LastFailureMessage}}
+    {{.LastFailureMessage | trim | indent 4}}
 {{- end}}
 
 
@@ -134,14 +145,16 @@ Original-Recipient: utf-8; {{.OriginalAddress}}
 Final-Recipient: utf-8; {{.Address}}
 Action: failed
 Status: 5.0.0
-Diagnostic-Code: smtp; {{.LastFailureMessage}}
-{{end}}
+Diagnostic-Code: smtp; {{.LastFailureMessage | trim | indent 4}}
+
+{{end -}}
 {{range .PendingRecipients -}}
 Original-Recipient: utf-8; {{.OriginalAddress}}
 Final-Recipient: utf-8; {{.Address}}
 Action: failed
 Status: 4.0.0
-Diagnostic-Code: smtp; {{.LastFailureMessage}}
+Diagnostic-Code: smtp; {{.LastFailureMessage | trim | indent 4}}
+
 {{end}}
 
 --{{.Boundary}}
diff --git a/internal/queue/dsn_test.go b/internal/queue/dsn_test.go
index 8e1cff4..70edabc 100644
--- a/internal/queue/dsn_test.go
+++ b/internal/queue/dsn_test.go
@@ -7,6 +7,17 @@ import (
 	"testing"
 )
 
+const multilineErr = `550 5.7.1 [11:22:33:44::1] Our system has detected that this
+5.7.1 message is likely unsolicited mail. To reduce the amount of spam sent
+5.7.1 to BlahMail, this message has been blocked. Please visit
+5.7.1  https://support.blah/mail/?p=UnsolicitedMessageError
+5.7.1  for more information. a1b2c3a1b2c3a1b.123 - bsmtp`
+
+const data = `Message-ID: <msgid-123@zaraza>
+
+Data ñaca.
+`
+
 func TestDSN(t *testing.T) {
 	item := &Item{
 		Message: Message{
@@ -16,12 +27,14 @@ func TestDSN(t *testing.T) {
 			Rcpt: []*Recipient{
 				{"poe@rcpt", Recipient_EMAIL, Recipient_FAILED,
 					"oh! horror!", "ñaca@africa.org"},
+				{"muchos@rcpt", Recipient_EMAIL, Recipient_FAILED,
+					multilineErr, "pepe@africa.org"},
 				{"newman@rcpt", Recipient_EMAIL, Recipient_PENDING,
 					"oh! the humanity!", "ñaca@africa.org"},
 				{"ant@rcpt", Recipient_EMAIL, Recipient_SENT,
 					"", "negra@sosa.org"},
 			},
-			Data: []byte("data ñaca"),
+			Data: []byte(data),
 		},
 	}
 
@@ -42,9 +55,9 @@ To: <from@from.org>
 Subject: Mail delivery failed: returning message to sender
 Message-ID: <chasquid-dsn-???????????@dsnDomain>
 Date: *
-In-Reply-To: *
-References: *
-X-Failed-Recipients: ñaca@africa.org, 
+In-Reply-To: <msgid-123@zaraza>
+References: <msgid-123@zaraza>
+X-Failed-Recipients: pepe@africa.org, ñaca@africa.org, 
 Auto-Submitted: auto-replied
 MIME-Version: 1.0
 Content-Type: multipart/report; report-type=delivery-status;
@@ -59,11 +72,19 @@ Content-Transfer-Encoding: 8bit
 
 Delivery of your message to the following recipient(s) failed permanently:
 
+  - pepe@africa.org
   - ñaca@africa.org
 
+
 Technical details:
 - "poe@rcpt" (EMAIL) failed permanently with error:
     oh! horror!
+- "muchos@rcpt" (EMAIL) failed permanently with error:
+    550 5.7.1 [11:22:33:44::1] Our system has detected that this
+    5.7.1 message is likely unsolicited mail. To reduce the amount of spam sent
+    5.7.1 to BlahMail, this message has been blocked. Please visit
+    5.7.1  https://support.blah/mail/?p=UnsolicitedMessageError
+    5.7.1  for more information. a1b2c3a1b2c3a1b.123 - bsmtp
 - "newman@rcpt" (EMAIL) failed repeatedly and timed out, last error:
     oh! the humanity!
 
@@ -81,6 +102,16 @@ Action: failed
 Status: 5.0.0
 Diagnostic-Code: smtp; oh! horror!
 
+Original-Recipient: utf-8; pepe@africa.org
+Final-Recipient: utf-8; muchos@rcpt
+Action: failed
+Status: 5.0.0
+Diagnostic-Code: smtp; 550 5.7.1 [11:22:33:44::1] Our system has detected that this
+    5.7.1 message is likely unsolicited mail. To reduce the amount of spam sent
+    5.7.1 to BlahMail, this message has been blocked. Please visit
+    5.7.1  https://support.blah/mail/?p=UnsolicitedMessageError
+    5.7.1  for more information. a1b2c3a1b2c3a1b.123 - bsmtp
+
 Original-Recipient: utf-8; ñaca@africa.org
 Final-Recipient: utf-8; newman@rcpt
 Action: failed
@@ -88,12 +119,16 @@ Status: 4.0.0
 Diagnostic-Code: smtp; oh! the humanity!
 
 
+
 --???????????
 Content-Type: message/rfc822
 Content-Description: Undelivered Message
 Content-Transfer-Encoding: 8bit
 
-data ñaca
+Message-ID: <msgid-123@zaraza>
+
+Data ñaca.
+
 
 --???????????--
 `
diff --git a/test/t-05-null_address/expected_dsr b/test/t-05-null_address/expected_dsr
index b95611e..9639134 100644
--- a/test/t-05-null_address/expected_dsr
+++ b/test/t-05-null_address/expected_dsr
@@ -23,6 +23,7 @@ Delivery of your message to the following recipient(s) failed permanently:
 
   - fail@testserver
 
+
 Technical details:
 - "false" (PIPE) failed permanently with error:
     exit status 1