Compare commits

..

No commits in common. "b01e6776dc295475a5fe0eb6227e20447501c2ca" and "444e3d877eb8cce6efe14e9c62c5ba87d74fd4c8" have entirely different histories.

2 changed files with 45 additions and 62 deletions

View File

@ -38,6 +38,7 @@ Available env variables:
## TODO ## TODO
- Some emails are not rendering (it parses the header but not the content)
- Restart when either mail or web server dies - Restart when either mail or web server dies
- Handle attachments - Handle attachments
- Do not store the raw mail data in the DB, maybe use block storage (the provider can be a disk provider at first) - Do not store the raw mail data in the DB, maybe use block storage (the provider can be a disk provider at first)

View File

@ -55,11 +55,11 @@ func Parse_mime_format(s string) (MIMEType, bool) {
} }
switch { switch {
case strings.EqualFold(s, "html"): case strings.Compare(s, "html") == 0:
t = Html t = Html
case strings.EqualFold(s, "md"): case strings.Compare(s, "md") == 0:
t = Markdown t = Markdown
case strings.EqualFold(s, "text"): case strings.Compare(s, "text") == 0:
t = PlainText t = PlainText
default: default:
return t, false return t, false
@ -100,14 +100,8 @@ func Parse_mail(m_data []byte, header_only bool) (Mail_obj, error) {
} }
var body Mail_body var body Mail_body
body.MimeType = PlainText
mail_body, err := Parse_mail_part(mail_msg.Header, txt_bytes) body.Data = string(txt_bytes)
if err != nil {
return m, err
}
body.Data = mail_body.Data
body.MimeType = mail_body.MimeType
m.MediaType = NotMultipart m.MediaType = NotMultipart
m.Body = append(m.Body, body) m.Body = append(m.Body, body)
@ -123,7 +117,7 @@ func Parse_mail(m_data []byte, header_only bool) (Mail_obj, error) {
return m, errors.New("Not supported multipart type") return m, errors.New("Not supported multipart type")
} }
body, err := Parse_mail_multipart(mail_msg.Body, params["boundary"]) body, err := Parse_mail_part(mail_msg.Body, params["boundary"])
if err != nil { if err != nil {
return m, err return m, err
} }
@ -133,52 +127,7 @@ func Parse_mail(m_data []byte, header_only bool) (Mail_obj, error) {
return m, nil return m, nil
} }
type Header interface { func Parse_mail_part(mime_data io.Reader, boundary string) ([]Mail_body, error) {
Get(string) string
}
func Parse_mail_part(header Header, body []byte) (Mail_body, error) {
content_transfer_encoding := header.Get("Content-Transfer-Encoding")
content_type := header.Get("Content-Type")
var mail_body Mail_body
switch {
case strings.HasPrefix(content_type, "text/plain"):
mail_body.MimeType = PlainText
case strings.HasPrefix(content_type, "text/markdown"):
mail_body.MimeType = Markdown
case strings.HasPrefix(content_type, "text/html"):
mail_body.MimeType = Html
default:
return mail_body, errors.New("Content type not supported: " + content_type)
}
switch {
case strings.EqualFold(content_transfer_encoding, "BASE64"):
decoded_content, err := base64.StdEncoding.DecodeString(string(body))
if err != nil {
return mail_body, err
}
mail_body.Data = string(decoded_content)
case strings.EqualFold(content_transfer_encoding, "QUOTED-PRINTABLE"):
decoded_content, err := io.ReadAll(quotedprintable.NewReader(bytes.NewReader(body)))
if err != nil {
return mail_body, err
}
mail_body.Data = string(decoded_content)
default:
mail_body.Data = string(body)
}
return mail_body, nil
}
func Parse_mail_multipart(mime_data io.Reader, boundary string) ([]Mail_body, error) {
var body []Mail_body var body []Mail_body
reader := multipart.NewReader(mime_data, boundary) reader := multipart.NewReader(mime_data, boundary)
@ -203,7 +152,7 @@ func Parse_mail_multipart(mime_data io.Reader, boundary string) ([]Mail_body, er
} }
if strings.HasPrefix(mediaType, "multipart/") { if strings.HasPrefix(mediaType, "multipart/") {
body_part, err := Parse_mail_multipart(new_part, params["boundary"]) body_part, err := Parse_mail_part(new_part, params["boundary"])
if err != nil { if err != nil {
return body, err return body, err
} }
@ -216,10 +165,43 @@ func Parse_mail_multipart(mime_data io.Reader, boundary string) ([]Mail_body, er
if err != nil { if err != nil {
return body, err return body, err
} }
part_body, err := Parse_mail_part(new_part.Header, part_data) content_transfer_encoding := new_part.Header.Get("Content-Transfer-Encoding")
if err != nil { content_type := new_part.Header.Get("Content-Type")
return body, err
var part_body Mail_body
switch {
case strings.HasPrefix(content_type, "text/plain"):
part_body.MimeType = PlainText
case strings.HasPrefix(content_type, "text/markdown"):
part_body.MimeType = Markdown
case strings.HasPrefix(content_type, "text/html"):
part_body.MimeType = Html
default:
return body, errors.New("Content type not supported: " + content_type)
} }
switch {
case strings.Compare(content_transfer_encoding, "BASE64") == 0:
decoded_content, err := base64.StdEncoding.DecodeString(string(part_data))
if err != nil {
return body, err
}
part_body.Data = string(decoded_content)
case strings.Compare(content_transfer_encoding, "QUOTED-PRINTABLE") == 0:
decoded_content, err := io.ReadAll(quotedprintable.NewReader(bytes.NewReader(part_data)))
if err != nil {
return body, err
}
part_body.Data = string(decoded_content)
default:
part_body.Data = string(part_data)
}
body = append(body, part_body) body = append(body, part_body)
} }