Skip to content

Commit

Permalink
executors/imap: proper support for Content-Transfer-Encoding header. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
wI2L authored and yesnault committed Sep 13, 2017
1 parent ab91fa1 commit 611c257
Showing 1 changed file with 54 additions and 43 deletions.
97 changes: 54 additions & 43 deletions executors/imap/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package imap
import (
"bytes"
"crypto/md5"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
Expand Down Expand Up @@ -34,61 +35,71 @@ func hash(in string) string {

func extract(rsp imap.Response, l venom.Logger) (*Mail, error) {
tm := &Mail{}
var params map[string]string

header := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.HEADER"])
tm.UID = imap.AsNumber((rsp.MessageInfo().Attrs["UID"]))
body := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822.TEXT"])
if mmsg, _ := mail.ReadMessage(bytes.NewReader(header)); mmsg != nil {
var errds error
tm.Subject, errds = decodeHeader(mmsg, "Subject")
if errds != nil {
log.Warnf("Cannot decode subject: %s", errds)
return nil, nil
}
var errdf error
tm.From, errdf = decodeHeader(mmsg, "From")
if errdf != nil {
log.Warnf("Cannot decode from: %s", errdf)
return nil, nil
}

var errpm error
_, params, errpm = mime.ParseMediaType(mmsg.Header.Get("Content-Type"))
if errpm != nil {
return nil, fmt.Errorf("Error while read Content-Type:%s", errpm)
}
mmsg, err := mail.ReadMessage(bytes.NewReader(header))
if err != nil {
return nil, err
}
tm.Subject, err = decodeHeader(mmsg, "Subject")
if err != nil {
log.Warnf("Cannot decode subject: %s", err)
return nil, nil
}
tm.From, err = decodeHeader(mmsg, "From")
if err != nil {
log.Warnf("Cannot decode from: %s", err)
return nil, nil
}

r := quotedprintable.NewReader(bytes.NewReader(body))
bodya, errra := ioutil.ReadAll(r)
if errra == nil {
tm.Body = string(bodya)
return tm, nil
} else if len(params) > 0 {
r := bytes.NewReader(body)
mr := multipart.NewReader(r, params["boundary"])
for {
p, err := mr.NextPart()
if err == io.EOF {
continue
}
if err != nil {
l.Debugf("Error while read Part:%s", err)
encoding := mmsg.Header.Get("Content-Transfer-Encoding")
var r io.Reader = bytes.NewReader(body)
switch encoding {
case "7bit", "8bit", "binary":
// noop, reader already initialized.
case "quoted-printable":
r = quotedprintable.NewReader(r)
case "base64":
r = base64.NewDecoder(base64.StdEncoding, r)
}
l.Debugf("Mail Content-Transfer-Encoding is %s ", encoding)

contentType, params, err := mime.ParseMediaType(mmsg.Header.Get("Content-Type"))
if err != nil {
return nil, fmt.Errorf("Error while reading Content-Type:%s", err)
}
if contentType == "multipart/mixed" || contentType == "multipart/alternative" {
if boundary, ok := params["boundary"]; ok {
mr := multipart.NewReader(r, boundary)
for {
p, errm := mr.NextPart()
if errm == io.EOF {
continue
}
if errm != nil {
l.Debugf("Error while read Part:%s", err)
break
}
slurp, errm := ioutil.ReadAll(p)
if errm != nil {
l.Debugf("Error while ReadAll Part:%s", err)
continue
}
tm.Body = string(slurp)
break
}
slurp, err := ioutil.ReadAll(p)
if err != nil {
l.Debugf("Error while ReadAll Part:%s", err)
continue
}
tm.Body = string(slurp)
break
}
} else {
body, err = ioutil.ReadAll(r)
if err != nil {
return nil, err
}
}

if tm.Body == "" {
tm.Body = string(bodya)
tm.Body = string(body)
}
return tm, nil
}

0 comments on commit 611c257

Please sign in to comment.