multipart/mixed can contain multipart/related
diff --git a/parsemail.go b/parsemail.go
index 8a62e26..e0ab7a6 100644
--- a/parsemail.go
+++ b/parsemail.go
@@ -100,6 +100,63 @@
return mime.ParseMediaType(contentTypeHeader)
}
+func parseMultipartRelated(msg io.Reader, boundary string) (textBody, htmlBody string, embeddedFiles []EmbeddedFile, err error) {
+ pmr := multipart.NewReader(msg, boundary)
+ for {
+ part, err := pmr.NextPart()
+
+ if err == io.EOF {
+ break
+ } else if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ contentType, params, err := mime.ParseMediaType(part.Header.Get("Content-Type"))
+ if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ switch contentType {
+ case contentTypeTextPlain:
+ ppContent, err := ioutil.ReadAll(part)
+ if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ textBody += strings.TrimSuffix(string(ppContent[:]), "\n")
+ case contentTypeTextHtml:
+ ppContent, err := ioutil.ReadAll(part)
+ if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ htmlBody += strings.TrimSuffix(string(ppContent[:]), "\n")
+ case contentTypeMultipartAlternative:
+ tb, hb, ef, err := parseMultipartAlternative(part, params["boundary"])
+ if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ htmlBody += hb
+ textBody += tb
+ embeddedFiles = append(embeddedFiles, ef...)
+ default:
+ if isEmbeddedFile(part) {
+ ef, err := decodeEmbeddedFile(part)
+ if err != nil {
+ return textBody, htmlBody, embeddedFiles, err
+ }
+
+ embeddedFiles = append(embeddedFiles, ef)
+ } else {
+ return textBody, htmlBody, embeddedFiles, fmt.Errorf("Can't process multipart/related inner mime type: %s", contentType)
+ }
+ }
+ }
+
+ return textBody, htmlBody, embeddedFiles, err
+}
+
func parseMultipartAlternative(msg io.Reader, boundary string) (textBody, htmlBody string, embeddedFiles []EmbeddedFile, err error) {
pmr := multipart.NewReader(msg, boundary)
for {
@@ -177,6 +234,11 @@
if err != nil {
return textBody, htmlBody, attachments, embeddedFiles, err
}
+ } else if contentType == contentTypeMultipartRelated {
+ textBody, htmlBody, embeddedFiles, err = parseMultipartRelated(part, params["boundary"])
+ if err != nil {
+ return textBody, htmlBody, attachments, embeddedFiles, err
+ }
} else if isAttachment(part) {
at, err := decodeAttachment(part)
if err != nil {