From bbd5d2673074151f8f92abe0865042d50751a2ff Mon Sep 17 00:00:00 2001 From: Thomas Kalka Date: Sun, 21 May 2023 09:57:48 +0200 Subject: [PATCH 1/2] make toQuotedPrintable independent from mailer --- processor/emailer/emailer.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/processor/emailer/emailer.go b/processor/emailer/emailer.go index 7f6b6f1..9c7e49b 100644 --- a/processor/emailer/emailer.go +++ b/processor/emailer/emailer.go @@ -101,7 +101,7 @@ func (e *Emailer) loadTemplate() (*template.Template, error) { // funcMap := template.FuncMap{ "env": env, - "quoteprintable": e.toQuotedPrintable, + "quoteprintable": toQuotedPrintable, "split": split, } @@ -115,7 +115,7 @@ func (e *Emailer) loadTemplate() (*template.Template, error) { // body. // // NOTE: We use this function both directly, and from within our template. -func (e *Emailer) toQuotedPrintable(s string) (string, error) { +func toQuotedPrintable(s string) (string, error) { var ac bytes.Buffer w := quotedprintable.NewWriter(&ac) _, err := w.Write([]byte(s)) @@ -186,11 +186,11 @@ func (e *Emailer) Sendmail(addresses []string, textstr string, htmlstr string) e // The real meat of the mail is the text & HTML // parts. They need to be encoded, unconditionally. - x.Text, err = e.toQuotedPrintable(textstr) + x.Text, err = toQuotedPrintable(textstr) if err != nil { return err } - x.HTML, err = e.toQuotedPrintable(html.UnescapeString(htmlstr)) + x.HTML, err = toQuotedPrintable(html.UnescapeString(htmlstr)) if err != nil { return err } From 590eb072ba86b19e6c5422cb4ed98516b36b6c24 Mon Sep 17 00:00:00 2001 From: Thomas Kalka Date: Sun, 21 May 2023 10:12:15 +0200 Subject: [PATCH 2/2] add ability to encode header * add encodeHeader function to template * update template to encode subject and tag in mail header * add documentation to template * adjust test for changed template --- processor/emailer/emailer.go | 13 +++++++++++++ template/template.txt | 3 ++- template/template_test.go | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/processor/emailer/emailer.go b/processor/emailer/emailer.go index 9c7e49b..bbaa718 100644 --- a/processor/emailer/emailer.go +++ b/processor/emailer/emailer.go @@ -103,6 +103,7 @@ func (e *Emailer) loadTemplate() (*template.Template, error) { "env": env, "quoteprintable": toQuotedPrintable, "split": split, + "encodeHeader": encodeHeader, } tmpl := template.Must(template.New("email.tmpl").Funcs(funcMap).Parse(string(content))) @@ -129,6 +130,18 @@ func toQuotedPrintable(s string) (string, error) { return ac.String(), nil } +// Encode email header entries to comply with the 7bit ASCII restriction +// of RFC 5322 according to RFC 2047. +// +// We use quotedprintable encoding only if necessary. +func encodeHeader(s string) string { + se, err := toQuotedPrintable(s) + if (err != nil) || (len(se) == len(s)) { + return s + } + return "=?utf-8?Q?" + strings.Replace(strings.Replace(se, "?", "=3F", -1), " ", "=20", -1) + "?=" +} + // Sendmail is a simple function that emails the given address. // // We send a MIME message with both a plain-text and a HTML-version of the diff --git a/template/template.txt b/template/template.txt index 5bb6571..193deb6 100644 --- a/template/template.txt +++ b/template/template.txt @@ -19,6 +19,7 @@ {{env "USER"}} -> Return the given environmental variable {{quoteprintable .Link}} -> Quote the specified field. + {{encodeHeader .Subject}} -> Quote the specified field to be used in mail header. {{split "STRING:HERE" ":"}} -> Split a string into an array by deliminator This comment will be stripped from the generated email. @@ -27,7 +28,7 @@ Content-Type: multipart/mixed; boundary=21ee3da964c7bf70def62adb9ee1a061747003c026e363e47231258c48f1 From: {{.From}} To: {{.To}} -Subject: [rss2email] {{if .Tag}}{{.Tag}} {{end}}{{.Subject}} +Subject: [rss2email] {{if .Tag}}{{encodeHeader .Tag}} {{end}}{{encodeHeader .Subject}} X-RSS-Link: {{.Link}} X-RSS-Feed: {{.Feed}} {{- if .Tag}} diff --git a/template/template_test.go b/template/template_test.go index 51b38ef..80834c0 100644 --- a/template/template_test.go +++ b/template/template_test.go @@ -6,7 +6,7 @@ func TestTemplate(t *testing.T) { // content and expected length content := EmailTemplate() - length := 2529 + length := 2645 if len(content) != length { t.Fatalf("unexpected template size %d != %d", length, len(content))