Skip to content

Commit

Permalink
fix: include content type in empty MIME parts
Browse files Browse the repository at this point in the history
Changes the MIME generation code to always include the "Content-Type"
header in each of the the MIME parts, even if the part is empty.

Previously an empty plain text or HTML body could cause some SMTP
servers to reject the mail due to the missing headers. Emails that
included both HTML and plain-text conent were not affected.

Fixes #61.
  • Loading branch information
domodwyer committed Feb 28, 2021
1 parent 78f7fef commit 299e395
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
28 changes: 26 additions & 2 deletions integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ func TestIntegration_TLS(t *testing.T) {
},
wantErr: nil,
},
{
name: "empty",
fn: func(m *MailYak) {
m.From("[email protected]")
m.FromName("From Example")
m.To("[email protected]")
m.Bcc("[email protected]", "[email protected]")
m.Subject("TLS empty")
m.ReplyTo("[email protected]")
},
wantErr: nil,
},
{
name: "authenticated",
auth: smtp.PlainAuth("ident", "user", "pass", "127.0.0.1"),
Expand Down Expand Up @@ -90,7 +102,7 @@ func TestIntegration_TLS(t *testing.T) {
m.To("[email protected]")
m.Subject("TLS Attachment test")
m.ReplyTo("[email protected]")
m.HTML().Set("Attachment MF5: " + hashString)
m.HTML().Set("Attachment MD5: " + hashString)
m.Attach("test.bin", bytes.NewReader(data))
},
wantErr: nil,
Expand Down Expand Up @@ -152,6 +164,18 @@ func TestIntegration_PlainText(t *testing.T) {
},
wantErr: nil,
},
{
name: "empty",
fn: func(m *MailYak) {
m.From("[email protected]")
m.FromName("From Example")
m.To("[email protected]")
m.Bcc("[email protected]", "[email protected]")
m.Subject("Plaintext empty")
m.ReplyTo("[email protected]")
},
wantErr: nil,
},
{
name: "authenticated",
auth: smtp.PlainAuth("ident", "user", "pass", "127.0.0.1"),
Expand Down Expand Up @@ -183,7 +207,7 @@ func TestIntegration_PlainText(t *testing.T) {
m.To("[email protected]")
m.Subject("PLAIN - Attachment test")
m.ReplyTo("[email protected]")
m.HTML().Set("Attachment MF5: " + hashString)
m.HTML().Set("Attachment MD5: " + hashString)
m.Attach("test.bin", bytes.NewReader(data))
},
wantErr: nil,
Expand Down
4 changes: 2 additions & 2 deletions mailyak_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ func TestMailYakDate(t *testing.T) {
mail.Subject("Test subject")

// send two emails at different times (discarding any errors)
_ = mail.Send()
_, _ = mail.MimeBuf()
dateOne := mail.date

time.Sleep(1 * time.Second)

_ = mail.Send()
_, _ = mail.MimeBuf()
dateTwo := mail.date

if dateOne == dateTwo {
Expand Down
2 changes: 1 addition & 1 deletion mime.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (m *MailYak) writeBody(w io.Writer, boundary string) error {

var err error
writePart := func(ctype string, data []byte) {
if len(data) == 0 || err != nil {
if err != nil {
return
}

Expand Down
26 changes: 13 additions & 13 deletions mime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,27 +217,27 @@ func TestMailYakWriteBody(t *testing.T) {
wantErr bool
}{
{
"Boundary name",
"Empty",
"",
"",
"test",
"\r\n--test--\r\n",
"--test\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--test\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--test--\r\n",
false,
},
{
"HTML",
"HTML",
"",
"t",
"--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\nHTML\r\n--t--\r\n",
"--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\nHTML\r\n--t--\r\n",
false,
},
{
"Plain text",
"",
"Plain",
"t",
"--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nPlain\r\n--t--\r\n",
"--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nPlain\r\n--t\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--t--\r\n",
false,
},
{
Expand Down Expand Up @@ -307,7 +307,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -319,7 +319,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\nHTML\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\nHTML\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -331,7 +331,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nPlain\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\nPlain\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -343,7 +343,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"reply",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nReply-To: reply\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nReply-To: reply\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -355,7 +355,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"name",
"",
"From: name <>\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: name <>\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -367,7 +367,7 @@ func TestMailYakBuildMime(t *testing.T) {
"addr",
"name",
"",
"From: name <addr>\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: name <addr>\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -379,7 +379,7 @@ func TestMailYakBuildMime(t *testing.T) {
"from",
"",
"",
"From: from\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: from\r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -391,7 +391,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: subject\r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: subject\r\nTo: \r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
{
Expand All @@ -403,7 +403,7 @@ func TestMailYakBuildMime(t *testing.T) {
"",
"",
"",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: one\r\nTo: two\r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
"From: \r\nMime-Version: 1.0\r\nDate: " + now + "\r\nSubject: \r\nTo: one\r\nTo: two\r\nContent-Type: multipart/mixed;\r\n\tboundary=\"mixed\"; charset=UTF-8\r\n\r\n--mixed\r\nContent-Type: multipart/alternative;\r\n\tboundary=\"alt\"\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n\r\n--alt\r\nContent-Transfer-Encoding: quoted-printable\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n\r\n--alt--\r\n\r\n--mixed--\r\n",
false,
},
}
Expand Down

0 comments on commit 299e395

Please sign in to comment.