重叠的多部分 'no media type'
Overlapped multipart 'no media type'
我正在尝试提取邮件正文。
我创建了一个函数,当 Content-Type 为 'multipart' 时使用。
像这样:
func multipartFunc(w http.ResponseWriter, content string) string {
msg, err := mail.ReadMessage(bytes.NewBufferString(content))
var uDec []byte
mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
if err != nil {
log.Fatal("2 error: ", err)
}
if strings.HasPrefix(mediaType, "multipart/") {
mr := multipart.NewReader(msg.Body, params["boundary"])
for {
p, err := mr.NextPart()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
slurp, err := ioutil.ReadAll(p)
if err != nil {
log.Fatal(err)
}
encoding := p.Header.Get("Content-Transfer-Encoding\n")
if encoding == "" {
encoding = "7bit"
}
if strings.Contains(p.Header.Get("Content-Type"), "multipart") {
newContent := "\nMime-Version: 1.0\n" + "Message-ID: " + randomString(12) + "\nContent-Type: " + p.Header.Get("Content-Type") + "\nContent-Transfer-Encoding: " + encoding + ";\n" + string(slurp)
**ss := multipartFunc(w, newContent)**
return ss
}
if p.Header.Get("Content-Transfer-Encoding") == "base64" {
uDec, _ = base64.StdEncoding.DecodeString(string(slurp))
} else if p.Header.Get("Content-Transfer-Encoding") == "quoted-printable" {
uDec, _ = ioutil.ReadAll(quotedprintable.NewReader(strings.NewReader(string(slurp))))
} else {
uDec = []byte(string(slurp))
}
}
}
return string(uDec)
示例邮件:
From: <aa@aa.or.kr>
Date: Wed, 07 Oct 2020 09:25:49 +0900
Message-Id: <RWAA4Q95VBU4.esdqwe@ds4>
To: aa@aa.com
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-pm6oKFbVvZj4hXY1hoVA4g=="
--=-pm6oKFbVvZj4hXY1hoVA4g==
Content-Type: multipart/alternative; boundary="=-OM18H8UnjkvG1nNW6D77AQ=="
--=-OM18H8UnjkvG1nNW6D77AQ==
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
DQoNCg0KCQ0KICAgICAgICAgICAgICAgIA
--=-OM18H8UnjkvG1nNW6D77AQ==
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
PGh0bWwgbGFuZz0ia28iPg0KPG1ldGEgYLTgiPg0KDQoJPGRpdiBpZD0i
--=-OM18H8UnjkvG1nNW6D77AQ==--
--=-pm6oKFbVvZj4hXY1hoVA4g==--
但是如果我提取部分重叠的多部分并重新插入,
发生错误。 ('no media type' 或 'malformed MIME header: missing colon: %!q')
我不知道问题出在哪里。
您正在创建一条新消息:
newContent := "\nMime-Version: 1.0\n" + "Message-ID: " + ...
因此,示例消息可能是:
Mime-Version: 1.0
Message-ID: RANDOMSTRING
它以一个空行开始,这就是 header 与消息的分隔符,因此当消息被解析时,header 将是空白的(您可以通过添加 fmt.Printf("Header: %v\n", msg.Header)
在调用 mail.ReadMessage
).
之后
删除 \n
会导致另一个错误(如果您检查了错误就会发生这种情况 - 请记住在每次调用后进行检查)malformed MIME header: missing colon: "--=-OM18H8UnjkvG1nNW6D77AQ=="
。这是因为您没有在 header 的末尾添加空行。所以需要在最后再添加一个\n
... + encoding + ";\n\n" + string(slurp)
完成此代码后运行 see playground. Please note that I have only made the changes to get this running; I have not performed any further checks. I have left some debugging code in place (Printf
) to show you how I went about tracing the issue (if you raise further issues posting a Minimal, Reproducible Example 使此过程更容易)。
我正在尝试提取邮件正文。
我创建了一个函数,当 Content-Type 为 'multipart' 时使用。
像这样:
func multipartFunc(w http.ResponseWriter, content string) string {
msg, err := mail.ReadMessage(bytes.NewBufferString(content))
var uDec []byte
mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
if err != nil {
log.Fatal("2 error: ", err)
}
if strings.HasPrefix(mediaType, "multipart/") {
mr := multipart.NewReader(msg.Body, params["boundary"])
for {
p, err := mr.NextPart()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
slurp, err := ioutil.ReadAll(p)
if err != nil {
log.Fatal(err)
}
encoding := p.Header.Get("Content-Transfer-Encoding\n")
if encoding == "" {
encoding = "7bit"
}
if strings.Contains(p.Header.Get("Content-Type"), "multipart") {
newContent := "\nMime-Version: 1.0\n" + "Message-ID: " + randomString(12) + "\nContent-Type: " + p.Header.Get("Content-Type") + "\nContent-Transfer-Encoding: " + encoding + ";\n" + string(slurp)
**ss := multipartFunc(w, newContent)**
return ss
}
if p.Header.Get("Content-Transfer-Encoding") == "base64" {
uDec, _ = base64.StdEncoding.DecodeString(string(slurp))
} else if p.Header.Get("Content-Transfer-Encoding") == "quoted-printable" {
uDec, _ = ioutil.ReadAll(quotedprintable.NewReader(strings.NewReader(string(slurp))))
} else {
uDec = []byte(string(slurp))
}
}
}
return string(uDec)
示例邮件:
From: <aa@aa.or.kr>
Date: Wed, 07 Oct 2020 09:25:49 +0900
Message-Id: <RWAA4Q95VBU4.esdqwe@ds4>
To: aa@aa.com
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="=-pm6oKFbVvZj4hXY1hoVA4g=="
--=-pm6oKFbVvZj4hXY1hoVA4g==
Content-Type: multipart/alternative; boundary="=-OM18H8UnjkvG1nNW6D77AQ=="
--=-OM18H8UnjkvG1nNW6D77AQ==
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
DQoNCg0KCQ0KICAgICAgICAgICAgICAgIA
--=-OM18H8UnjkvG1nNW6D77AQ==
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
PGh0bWwgbGFuZz0ia28iPg0KPG1ldGEgYLTgiPg0KDQoJPGRpdiBpZD0i
--=-OM18H8UnjkvG1nNW6D77AQ==--
--=-pm6oKFbVvZj4hXY1hoVA4g==--
但是如果我提取部分重叠的多部分并重新插入, 发生错误。 ('no media type' 或 'malformed MIME header: missing colon: %!q')
我不知道问题出在哪里。
您正在创建一条新消息:
newContent := "\nMime-Version: 1.0\n" + "Message-ID: " + ...
因此,示例消息可能是:
Mime-Version: 1.0
Message-ID: RANDOMSTRING
它以一个空行开始,这就是 header 与消息的分隔符,因此当消息被解析时,header 将是空白的(您可以通过添加 fmt.Printf("Header: %v\n", msg.Header)
在调用 mail.ReadMessage
).
删除 \n
会导致另一个错误(如果您检查了错误就会发生这种情况 - 请记住在每次调用后进行检查)malformed MIME header: missing colon: "--=-OM18H8UnjkvG1nNW6D77AQ=="
。这是因为您没有在 header 的末尾添加空行。所以需要在最后再添加一个\n
... + encoding + ";\n\n" + string(slurp)
完成此代码后运行 see playground. Please note that I have only made the changes to get this running; I have not performed any further checks. I have left some debugging code in place (Printf
) to show you how I went about tracing the issue (if you raise further issues posting a Minimal, Reproducible Example 使此过程更容易)。