Add parsing of EML from string and reader

Added two new methods `EMLToMsgFromString` and `EMLToMsgFromReader` in "eml.go". They allow EML parsing directly from a given string and a reader object, increasing overall functionality and versatility of the EML parsing process. This will enable the users to parse EML documents more flexibly."
This commit is contained in:
Winni Neessen 2023-10-31 11:45:09 +01:00
parent 6bda5d1aaa
commit f9140ce90e
Signed by: wneessen
GPG key ID: 385AC9889632126E

46
eml.go
View file

@ -9,6 +9,7 @@ import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
"io"
"mime" "mime"
"mime/quotedprintable" "mime/quotedprintable"
nm "net/mail" nm "net/mail"
@ -16,9 +17,40 @@ import (
"strings" "strings"
) )
// EMLToMsg will open an parse a .eml file at a provided file path and return a // EMLToMsgFromString will parse a given EML string and returns a pre-filled Msg pointer
func EMLToMsgFromString(es string) (*Msg, error) {
eb := bytes.NewBufferString(es)
return EMLToMsgFromReader(eb)
}
// EMLToMsgFromReader will parse a reader that holds EML content and returns a pre-filled
// Msg pointer
func EMLToMsgFromReader(r io.Reader) (*Msg, error) {
m := &Msg{
addrHeader: make(map[AddrHeader][]*nm.Address),
genHeader: make(map[Header][]string),
preformHeader: make(map[Header]string),
mimever: MIME10,
}
pm, mbbuf, err := readEMLFromReader(r)
if err != nil || pm == nil {
return m, fmt.Errorf("failed to parse EML from reader: %w", err)
}
if err = parseEMLHeaders(&pm.Header, m); err != nil {
return m, fmt.Errorf("failed to parse EML headers: %w", err)
}
if err = parseEMLBodyParts(pm, mbbuf, m); err != nil {
return m, fmt.Errorf("failed to parse EML body parts: %w", err)
}
return m, nil
}
// EMLToMsgFromFile will open and parse a .eml file at a provided file path and returns a
// pre-filled Msg pointer // pre-filled Msg pointer
func EMLToMsg(fp string) (*Msg, error) { func EMLToMsgFromFile(fp string) (*Msg, error) {
m := &Msg{ m := &Msg{
addrHeader: make(map[AddrHeader][]*nm.Address), addrHeader: make(map[AddrHeader][]*nm.Address),
genHeader: make(map[Header][]string), genHeader: make(map[Header][]string),
@ -50,7 +82,12 @@ func readEML(fp string) (*nm.Message, *bytes.Buffer, error) {
defer func() { defer func() {
_ = fh.Close() _ = fh.Close()
}() }()
pm, err := nm.ReadMessage(fh) return readEMLFromReader(fh)
}
// readEMLFromReader uses net/mail to parse the header and body from a given io.Reader
func readEMLFromReader(r io.Reader) (*nm.Message, *bytes.Buffer, error) {
pm, err := nm.ReadMessage(r)
if err != nil { if err != nil {
return pm, nil, fmt.Errorf("failed to parse EML: %w", err) return pm, nil, fmt.Errorf("failed to parse EML: %w", err)
} }
@ -60,9 +97,6 @@ func readEML(fp string) (*nm.Message, *bytes.Buffer, error) {
return nil, nil, err return nil, nil, err
} }
if err = fh.Close(); err != nil {
return nil, nil, fmt.Errorf("failed to close EML file: %w", err)
}
return pm, &buf, nil return pm, &buf, nil
} }