mirror of
https://github.com/wneessen/go-mail.git
synced 2024-12-23 02:50:39 +01:00
Add multipart message parsing in eml.go
This commit introduces the ability to handle multipart messages within the eml.go file. It reads individual parts of multipart messages, sets the encoding and content for each part, and implements error handling for potential issues like a missing boundary tag or difficulties acquiring the next part of a multipart message.
This commit is contained in:
parent
0d9ba278fe
commit
60222c95e7
1 changed files with 54 additions and 0 deletions
54
eml.go
54
eml.go
|
@ -11,6 +11,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"mime/quotedprintable"
|
||||
nm "net/mail"
|
||||
"os"
|
||||
|
@ -200,6 +201,59 @@ func parseEMLBodyParts(pm *nm.Message, mbbuf *bytes.Buffer, m *Msg) error {
|
|||
m.SetBodyString(TypeTextPlain, b64buf.String())
|
||||
break
|
||||
}
|
||||
case TypeMultipartAlternative.String():
|
||||
// TODO: Refactor in its own function
|
||||
b, ok := par["boundary"]
|
||||
if !ok {
|
||||
return fmt.Errorf("no boundary tag found in multipart body")
|
||||
}
|
||||
mpr := multipart.NewReader(mbbuf, b)
|
||||
mp, err := mpr.NextPart()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get next part of multipart message: %w", err)
|
||||
}
|
||||
for err == nil {
|
||||
// TODO: Clean up code
|
||||
mpd, mperr := io.ReadAll(mp)
|
||||
if mperr != nil {
|
||||
_ = mp.Close()
|
||||
return fmt.Errorf("failed to read multipart: %w", err)
|
||||
}
|
||||
mpctc, ok := mp.Header[HeaderContentType.String()]
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get content-type from part")
|
||||
}
|
||||
mpcts := strings.Split(mpctc[0], "; ")
|
||||
if len(mpcts) > 1 && strings.HasPrefix(strings.ToLower(mpcts[1]), "charset=") {
|
||||
vs := strings.Split(mpcts[1], "=")
|
||||
if len(vs) > 1 {
|
||||
// TODO: We probably want per-part charset instead
|
||||
m.SetCharset(Charset(vs[1]))
|
||||
}
|
||||
}
|
||||
mpcte, ok := mp.Header[HeaderContentTransferEnc.String()]
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to get content-transfer-encoding from part")
|
||||
}
|
||||
m.SetCharset(Charset(mpcts[1]))
|
||||
p := m.newPart(ContentType(mpcts[0]))
|
||||
switch {
|
||||
case strings.EqualFold(mpcte[0], EncodingB64.String()):
|
||||
p.SetEncoding(EncodingB64)
|
||||
cont, err := base64.StdEncoding.DecodeString(string(mpd))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode base64 part: %w", err)
|
||||
}
|
||||
p.SetContent(string(cont))
|
||||
}
|
||||
m.parts = append(m.parts, p)
|
||||
mp, err = mpr.NextPart()
|
||||
}
|
||||
if err != io.EOF {
|
||||
_ = mp.Close()
|
||||
return fmt.Errorf("failed to read multipart: %w", err)
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue