代码拉取完成,页面将自动刷新
package email
import (
"bytes"
"crypto/rand"
"encoding/base64"
)
// Message implements Internet Message as defined in RFC2822 and RFC2045 ~ RFC2049.
type Message struct {
Headers []Header
Body []byte // body for Content-Type: plain, image, audio, video or application.
BodyParts []Message // body for Content-Type: multipart or message.
}
type properties struct {
isComposite bool
isMultipart bool
multipartBoundary string
contentTransferEncoding string
}
// Bytes is the most important entrance func, it calls all the logic to convert a Message to bytes.
func (m *Message) Bytes() ([]byte, error) {
m.Headers = setupMIMEVersion(m.Headers)
buf := &bytes.Buffer{}
if err := m.write(buf); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func (m *Message) write(buf *bytes.Buffer) error {
p, err := m.getProperties()
if err != nil {
return err
}
if err := m.writeHeaders(&p, buf); err != nil {
return err
}
// write empty line seperator
if err := writeLine("", buf); err != nil {
return err
}
return m.writeBody(p, buf)
}
func (m *Message) writeHeaders(p *properties, buf *bytes.Buffer) error {
if err := validateHeaders(m.Headers); err != nil {
return err
}
if headers, err := setupEntityHeaders(m.Headers, p); err != nil {
return err
} else {
m.Headers = headers
}
return writeHeadersTo(m.Headers, buf)
}
func (m *Message) writeBody(p properties, buf *bytes.Buffer) error {
if len(m.BodyParts) > 0 {
return m.writeBodyParts(p, buf)
} else {
return writeBodyTo(m.Body, p, buf)
}
}
func (m *Message) writeBodyParts(p properties, buf *bytes.Buffer) error {
for _, bodyPart := range m.BodyParts {
if err := writeMultipartBoundary(p, false, buf); err != nil {
return err
}
if err := bodyPart.write(buf); err != nil {
return err
}
}
return writeMultipartBoundary(p, true, buf)
}
func (m *Message) getProperties() (properties, error) {
p := properties{
isComposite: len(m.BodyParts) > 0,
isMultipart: m.IsMultipart(),
}
if p.isMultipart {
if boundary, err := multipartBoundary(); err != nil {
return properties{}, err
} else {
p.multipartBoundary = boundary
}
}
return p, nil
}
// IsMultipart return if this is a multipart message.
func (m *Message) IsMultipart() bool {
switch len(m.BodyParts) {
case 0:
// When has no body parts, it must not be a multipart message.
return false
case 1:
// When has only one body part, it's a multipart message
// if the "Content-Type" Header is not provided or multipart.
h := findHeader(m.Headers, ContentType)
return h.isEmpty() || h.isMultipart()
default:
// When has more than one body parts, it must be a multipart message.
return true
}
}
func writeMultipartBoundary(p properties, end bool, buf *bytes.Buffer) error {
if !p.isMultipart {
return nil
}
line := "\n--" + p.multipartBoundary
if end {
line += "--"
}
return writeLine(line, buf)
}
func multipartBoundary() (string, error) {
var a [30]byte
b := a[:]
if _, err := rand.Read(b); err != nil {
return "", err
}
return "=_" + base64.URLEncoding.EncodeToString(b), nil
}
func writeLine(content string, buf *bytes.Buffer) error {
_, err := buf.WriteString(content + "\n")
return err
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。