MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / extractBodyParts

Function extractBodyParts

internal/outbound/forward.go:63–134  ·  view source on GitHub ↗

extractBodyParts walks a message body looking for the text/plain and text/html parts. Recurses into multipart/alternative and multipart/mixed. The body io.Reader is consumed in a single pass — for non-multipart bodies the entire reader is treated as a single part.

(body io.Reader, contentType, encoding string)

Source from the content-addressed store, hash-verified

61// multipart/mixed. The body io.Reader is consumed in a single pass — for
62// non-multipart bodies the entire reader is treated as a single part.
63func extractBodyParts(body io.Reader, contentType, encoding string) (textOut, htmlOut string) {
64 mediaType, params, err := mime.ParseMediaType(contentType)
65 if err != nil {
66 // No Content-Type or malformed — fall through and treat as
67 // text/plain. Cheaper than refusing the forward.
68 mediaType = "text/plain"
69 params = nil
70 }
71
72 if !strings.HasPrefix(mediaType, "multipart/") {
73 raw, err := io.ReadAll(body)
74 if err != nil {
75 return "", ""
76 }
77 decoded := decodeTransferEncoding(raw, encoding)
78 switch mediaType {
79 case "text/html":
80 return "", string(decoded)
81 default:
82 return string(decoded), ""
83 }
84 }
85
86 boundary := params["boundary"]
87 if boundary == "" {
88 return "", ""
89 }
90
91 mr := multipart.NewReader(body, boundary)
92 for {
93 part, err := mr.NextPart()
94 if err != nil {
95 break
96 }
97 partCT := part.Header.Get("Content-Type")
98 partEnc := part.Header.Get("Content-Transfer-Encoding")
99 partType, _, _ := mime.ParseMediaType(partCT)
100
101 if strings.HasPrefix(partType, "multipart/") {
102 nestedText, nestedHTML := extractBodyParts(part, partCT, partEnc)
103 if textOut == "" {
104 textOut = nestedText
105 }
106 if htmlOut == "" {
107 htmlOut = nestedHTML
108 }
109 _ = part.Close()
110 continue
111 }
112
113 raw, err := io.ReadAll(part)
114 _ = part.Close()
115 if err != nil {
116 continue
117 }
118 decoded := decodeTransferEncoding(raw, partEnc)
119 switch partType {
120 case "text/plain":

Callers 1

ExtractForwardContextFunction · 0.85

Calls 3

decodeTransferEncodingFunction · 0.85
GetMethod · 0.65
CloseMethod · 0.45

Tested by

no test coverage detected