diff --git a/parsemail.go b/parsemail.go index 6a60192..b157cc0 100644 --- a/parsemail.go +++ b/parsemail.go @@ -46,9 +46,31 @@ func Parse(r io.Reader) (email Email, err error) { email.TextBody, email.HTMLBody, email.EmbeddedFiles, err = parseMultipartRelated(msg.Body, params["boundary"]) case contentTypeTextPlain: message, _ := ioutil.ReadAll(msg.Body) + var reader io.Reader + reader, err = decodeContent(strings.NewReader(string(message[:])), msg.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return + } + + message, err = ioutil.ReadAll(reader) + if err != nil { + return + } + email.TextBody = strings.TrimSuffix(string(message[:]), "\n") case contentTypeTextHtml: message, _ := ioutil.ReadAll(msg.Body) + var reader io.Reader + reader, err = decodeContent(strings.NewReader(string(message[:])), msg.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return + } + + message, err = ioutil.ReadAll(reader) + if err != nil { + return + } + email.HTMLBody = strings.TrimSuffix(string(message[:]), "\n") default: email.Content, err = decodeContent(msg.Body, msg.Header.Get("Content-Transfer-Encoding")) @@ -121,14 +143,26 @@ func parseMultipartRelated(msg io.Reader, boundary string) (textBody, htmlBody s switch contentType { case contentTypeTextPlain: - ppContent, err := ioutil.ReadAll(part) + message, _ := ioutil.ReadAll(part) + reader, err := decodeContent(strings.NewReader(string(message[:])), part.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return textBody, htmlBody, embeddedFiles, err + } + + ppContent, err := ioutil.ReadAll(reader) if err != nil { return textBody, htmlBody, embeddedFiles, err } textBody += strings.TrimSuffix(string(ppContent[:]), "\n") case contentTypeTextHtml: - ppContent, err := ioutil.ReadAll(part) + message, _ := ioutil.ReadAll(part) + reader, err := decodeContent(strings.NewReader(string(message[:])), part.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return textBody, htmlBody, embeddedFiles, err + } + + ppContent, err := ioutil.ReadAll(reader) if err != nil { return textBody, htmlBody, embeddedFiles, err } @@ -178,14 +212,26 @@ func parseMultipartAlternative(msg io.Reader, boundary string) (textBody, htmlBo switch contentType { case contentTypeTextPlain: - ppContent, err := ioutil.ReadAll(part) + message, _ := ioutil.ReadAll(part) + reader, err := decodeContent(strings.NewReader(string(message[:])), part.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return textBody, htmlBody, embeddedFiles, err + } + + ppContent, err := ioutil.ReadAll(reader) if err != nil { return textBody, htmlBody, embeddedFiles, err } textBody += strings.TrimSuffix(string(ppContent[:]), "\n") case contentTypeTextHtml: - ppContent, err := ioutil.ReadAll(part) + message, _ := ioutil.ReadAll(part) + reader, err := decodeContent(strings.NewReader(string(message[:])), part.Header.Get("Content-Transfer-Encoding")) + if err != nil { + return textBody, htmlBody, embeddedFiles, err + } + + ppContent, err := ioutil.ReadAll(reader) if err != nil { return textBody, htmlBody, embeddedFiles, err } @@ -361,6 +407,8 @@ func decodeContent(content io.Reader, encoding string) (io.Reader, error) { } return bytes.NewReader(dd), nil + case "8bit": + return content, nil case "": return content, nil default: diff --git a/parsemail_test.go b/parsemail_test.go index 109e734..a57533f 100644 --- a/parsemail_test.go +++ b/parsemail_test.go @@ -403,6 +403,31 @@ So, "Hello".`, htmlBody: "
Time for the egg.



", textBody: "Time for the egg.", }, + 14: { + contentType: "multipart/alternative; boundary=\"000000000000ab2e1f05a26de586\"", + mailData: base64Content, + subject: "Saying Hello", + from: []mail.Address{ + { + Name: "John Doe", + Address: "jdoe@machine.example", + }, + }, + sender: mail.Address{ + Name: "Michael Jones", + Address: "mjones@machine.example", + }, + to: []mail.Address{ + { + Name: "Mary Smith", + Address: "mary@example.net", + }, + }, + messageID: "1234@local.machine.example", + date: parseDate("Fri, 21 Nov 1997 09:55:06 -0600"), + htmlBody: "
👍
", + textBody: "👍", + }, } for index, td := range testData { @@ -946,3 +971,27 @@ Content-Disposition: attachment; --f403045f1dcc043a44054c8e6bbf-- ` + +var base64Content = `MIME-Version: 1.0 +From: John Doe +Sender: Michael Jones +To: Mary Smith +Subject: Saying Hello +Date: Fri, 21 Nov 1997 09:55:06 -0600 +Message-ID: <1234@local.machine.example> +Content-Type: multipart/alternative; boundary="000000000000ab2e1f05a26de586" + +--000000000000ab2e1f05a26de586 +Content-Type: text/plain; charset="UTF-8" +Content-Transfer-Encoding: base64 + +8J+RjQo= + +--000000000000ab2e1f05a26de586 +Content-Type: text/html; charset="UTF-8" +Content-Transfer-Encoding: base64 + +PGRpdiBkaXI9Imx0ciI+8J+RjTwvZGl2Pgo= + +--000000000000ab2e1f05a26de586-- +`