Add quoted-printable decoding to smtp server
Some e-mails are sent using quoted-printable encoding [0], resulting in notifications with weird characters. This commit adds support for this encoding, resulting in the following: **Before** ``` A =3D=3D=3D=3D=3D B =3D=3D=3D=3D=3D C ``` **After** ``` A ===== B ===== C ``` [0] https://www.rfc-editor.org/rfc/rfc2045.htmlpull/719/head
parent
5bc51eefd9
commit
5b8520b4e0
|
@ -9,6 +9,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"mime"
|
"mime"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
"mime/quotedprintable"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -265,6 +266,8 @@ func readMultipartMailBody(body io.Reader, params map[string]string, depth int)
|
||||||
func readPlainTextMailBody(reader io.Reader, transferEncoding string) (string, error) {
|
func readPlainTextMailBody(reader io.Reader, transferEncoding string) (string, error) {
|
||||||
if strings.ToLower(transferEncoding) == "base64" {
|
if strings.ToLower(transferEncoding) == "base64" {
|
||||||
reader = base64.NewDecoder(base64.StdEncoding, reader)
|
reader = base64.NewDecoder(base64.StdEncoding, reader)
|
||||||
|
} else if strings.ToLower(transferEncoding) == "quoted-printable" {
|
||||||
|
reader = quotedprintable.NewReader(reader)
|
||||||
}
|
}
|
||||||
body, err := io.ReadAll(reader)
|
body, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -303,6 +303,39 @@ BBBBBBBBBBBBBBBBBBBBBBBBB`
|
||||||
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSmtpBackend_Plaintext_QuotedPrintable(t *testing.T) {
|
||||||
|
email := `EHLO example.com
|
||||||
|
MAIL FROM: phil@example.com
|
||||||
|
RCPT TO: mytopic@ntfy.sh
|
||||||
|
DATA
|
||||||
|
Date: Tue, 28 Dec 2021 00:30:10 +0100
|
||||||
|
Message-ID: <CAAvm79YP0C=Rt1N=KWmSUBB87KK2rRChmdzKqF1vCwMEUiVzLQ@mail.gmail.com>
|
||||||
|
Subject: and one more
|
||||||
|
From: Phil <phil@example.com>
|
||||||
|
To: mytopic@ntfy.sh
|
||||||
|
Content-Type: text/plain; charset="UTF-8"
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
what's
|
||||||
|
=C3=A0&=C3=A9"'(-=C3=A8_=C3=A7=C3=A0)
|
||||||
|
=3D=3D=3D=3D=3D
|
||||||
|
up
|
||||||
|
.
|
||||||
|
`
|
||||||
|
s, c, conf, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, "/mytopic", r.URL.Path)
|
||||||
|
require.Equal(t, "and one more", r.Header.Get("Title"))
|
||||||
|
require.Equal(t, `what's
|
||||||
|
à&é"'(-è_çà)
|
||||||
|
=====
|
||||||
|
up`, readAll(t, r.Body))
|
||||||
|
})
|
||||||
|
conf.SMTPServerAddrPrefix = ""
|
||||||
|
defer s.Close()
|
||||||
|
defer c.Close()
|
||||||
|
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
||||||
|
}
|
||||||
|
|
||||||
func TestSmtpBackend_Unsupported(t *testing.T) {
|
func TestSmtpBackend_Unsupported(t *testing.T) {
|
||||||
email := `EHLO example.com
|
email := `EHLO example.com
|
||||||
MAIL FROM: phil@example.com
|
MAIL FROM: phil@example.com
|
||||||
|
@ -390,6 +423,50 @@ L0VOIj4KClRoaXMgaXMgYSB0ZXN0IG1lc3NhZ2UgZnJvbSBUcnVlTkFTIENPUkUuCg==
|
||||||
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func TestSmtpBackend_MultipartQuotedPrintable(t *testing.T) {
|
||||||
|
email := `EHLO example.com
|
||||||
|
MAIL FROM: phil@example.com
|
||||||
|
RCPT TO: ntfy-mytopic@ntfy.sh
|
||||||
|
DATA
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Date: Tue, 28 Dec 2021 00:30:10 +0100
|
||||||
|
Message-ID: <CAAvm79YP0C=Rt1N=KWmSUBB87KK2rRChmdzKqF1vCwMEUiVzLQ@mail.gmail.com>
|
||||||
|
Subject: and one more
|
||||||
|
From: Phil <phil@example.com>
|
||||||
|
To: ntfy-mytopic@ntfy.sh
|
||||||
|
Content-Type: multipart/alternative; boundary="000000000000f3320b05d42915c9"
|
||||||
|
|
||||||
|
--000000000000f3320b05d42915c9
|
||||||
|
Content-Type: text/html; charset="UTF-8"
|
||||||
|
|
||||||
|
html, ignore me
|
||||||
|
|
||||||
|
--000000000000f3320b05d42915c9
|
||||||
|
Content-Type: text/plain; charset="UTF-8"
|
||||||
|
Content-Transfer-Encoding: quoted-printable
|
||||||
|
|
||||||
|
what's
|
||||||
|
=C3=A0&=C3=A9"'(-=C3=A8_=C3=A7=C3=A0)
|
||||||
|
=3D=3D=3D=3D=3D
|
||||||
|
up
|
||||||
|
|
||||||
|
--000000000000f3320b05d42915c9--
|
||||||
|
.
|
||||||
|
`
|
||||||
|
s, c, _, scanner := newTestSMTPServer(t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, "/mytopic", r.URL.Path)
|
||||||
|
require.Equal(t, "and one more", r.Header.Get("Title"))
|
||||||
|
require.Equal(t, `what's
|
||||||
|
à&é"'(-è_çà)
|
||||||
|
=====
|
||||||
|
up`, readAll(t, r.Body))
|
||||||
|
})
|
||||||
|
defer s.Close()
|
||||||
|
defer c.Close()
|
||||||
|
writeAndReadUntilLine(t, email, c, scanner, "250 2.0.0 OK: queued")
|
||||||
|
}
|
||||||
|
|
||||||
func TestSmtpBackend_NestedMultipartBase64(t *testing.T) {
|
func TestSmtpBackend_NestedMultipartBase64(t *testing.T) {
|
||||||
email := `EHLO example.com
|
email := `EHLO example.com
|
||||||
MAIL FROM: test@mydomain.me
|
MAIL FROM: test@mydomain.me
|
||||||
|
|
Loading…
Reference in New Issue