Changed body content type from []byte to func(io.Writer) error
It allows streaming the message body when sending an email instead of buffering it to memory.
This commit is contained in:
parent
ac067c1594
commit
66c8b9ae4c
34
message.go
34
message.go
|
@ -28,7 +28,7 @@ type header map[string][]string
|
||||||
|
|
||||||
type part struct {
|
type part struct {
|
||||||
contentType string
|
contentType string
|
||||||
body *bytes.Buffer
|
copier func(io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMessage creates a new message. It uses UTF-8 and quoted-printable encoding
|
// NewMessage creates a new message. It uses UTF-8 and quoted-printable encoding
|
||||||
|
@ -170,12 +170,15 @@ func (msg *Message) SetBody(contentType, body string) {
|
||||||
msg.parts = []part{
|
msg.parts = []part{
|
||||||
part{
|
part{
|
||||||
contentType: contentType,
|
contentType: contentType,
|
||||||
body: bytes.NewBufferString(body),
|
copier: func(w io.Writer) error {
|
||||||
|
_, err := io.WriteString(w, body)
|
||||||
|
return err
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddAlternative adds an alternative body to the message. Commonly used to
|
// AddAlternative adds an alternative part to the message. Commonly used to
|
||||||
// send HTML emails that default to the plain text version for backward
|
// send HTML emails that default to the plain text version for backward
|
||||||
// compatibility.
|
// compatibility.
|
||||||
//
|
//
|
||||||
|
@ -189,29 +192,30 @@ func (msg *Message) AddAlternative(contentType, body string) {
|
||||||
msg.parts = append(msg.parts,
|
msg.parts = append(msg.parts,
|
||||||
part{
|
part{
|
||||||
contentType: contentType,
|
contentType: contentType,
|
||||||
body: bytes.NewBufferString(body),
|
copier: func(w io.Writer) error {
|
||||||
|
_, err := io.WriteString(w, body)
|
||||||
|
return err
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBodyWriter gets a writer that writes to the body. It can be useful with
|
// AddAlternativeWriter adds an alternative part to the message. It can be
|
||||||
// the templates from packages text/template or html/template.
|
// useful with the text/template and html/template packages.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
//
|
//
|
||||||
// w := msg.GetBodyWriter("text/plain")
|
|
||||||
// t := template.Must(template.New("example").Parse("Hello {{.}}!"))
|
// t := template.Must(template.New("example").Parse("Hello {{.}}!"))
|
||||||
// t.Execute(w, "Bob")
|
// msg.AddAlternativeWriter("text/plain", func(w io.Writer) error {
|
||||||
func (msg *Message) GetBodyWriter(contentType string) io.Writer {
|
// return t.Execute(w, "Bob")
|
||||||
buf := new(bytes.Buffer)
|
// })
|
||||||
msg.parts = append(msg.parts,
|
func (msg *Message) AddAlternativeWriter(contentType string, f func(io.Writer) error) {
|
||||||
|
msg.parts = []part{
|
||||||
part{
|
part{
|
||||||
contentType: contentType,
|
contentType: contentType,
|
||||||
body: buf,
|
copier: f,
|
||||||
},
|
},
|
||||||
)
|
}
|
||||||
|
|
||||||
return buf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A File represents a file that can be attached or embedded in an email.
|
// A File represents a file that can be attached or embedded in an email.
|
||||||
|
|
|
@ -66,8 +66,10 @@ func TestBodyWriter(t *testing.T) {
|
||||||
msg := NewMessage()
|
msg := NewMessage()
|
||||||
msg.SetHeader("From", "from@example.com")
|
msg.SetHeader("From", "from@example.com")
|
||||||
msg.SetHeader("To", "to@example.com")
|
msg.SetHeader("To", "to@example.com")
|
||||||
w := msg.GetBodyWriter("text/plain")
|
msg.AddAlternativeWriter("text/plain", func(w io.Writer) error {
|
||||||
w.Write([]byte("Test message"))
|
_, err := w.Write([]byte("Test message"))
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
want := &message{
|
want := &message{
|
||||||
from: "from@example.com",
|
from: "from@example.com",
|
||||||
|
|
15
writeto.go
15
writeto.go
|
@ -42,7 +42,7 @@ func (w *messageWriter) writeMessage(msg *Message) {
|
||||||
"Content-Type": []string{contentType},
|
"Content-Type": []string{contentType},
|
||||||
"Content-Transfer-Encoding": []string{string(msg.encoding)},
|
"Content-Transfer-Encoding": []string{string(msg.encoding)},
|
||||||
})
|
})
|
||||||
w.writeBody(part.body.Bytes(), msg.encoding)
|
w.writeBody(part.copier, msg.encoding)
|
||||||
}
|
}
|
||||||
if msg.hasAlternativePart() {
|
if msg.hasAlternativePart() {
|
||||||
w.closeMultipart()
|
w.closeMultipart()
|
||||||
|
@ -123,7 +123,10 @@ func (w *messageWriter) addFiles(files []*File, isAttachment bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w.writeHeaders(h)
|
w.writeHeaders(h)
|
||||||
w.writeBody(f.Content, Base64)
|
w.writeBody(func(w io.Writer) error {
|
||||||
|
_, err := w.Write(f.Content)
|
||||||
|
return err
|
||||||
|
}, Base64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +178,7 @@ func (w *messageWriter) writeHeaders(h map[string][]string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *messageWriter) writeBody(body []byte, enc Encoding) {
|
func (w *messageWriter) writeBody(f func(io.Writer) error, enc Encoding) {
|
||||||
var subWriter io.Writer
|
var subWriter io.Writer
|
||||||
if w.depth == 0 {
|
if w.depth == 0 {
|
||||||
w.writeString("\r\n")
|
w.writeString("\r\n")
|
||||||
|
@ -186,13 +189,13 @@ func (w *messageWriter) writeBody(body []byte, enc Encoding) {
|
||||||
|
|
||||||
if enc == Base64 {
|
if enc == Base64 {
|
||||||
wc := base64.NewEncoder(base64.StdEncoding, newBase64LineWriter(subWriter))
|
wc := base64.NewEncoder(base64.StdEncoding, newBase64LineWriter(subWriter))
|
||||||
wc.Write(body)
|
w.err = f(wc)
|
||||||
wc.Close()
|
wc.Close()
|
||||||
} else if enc == Unencoded {
|
} else if enc == Unencoded {
|
||||||
subWriter.Write(body)
|
w.err = f(subWriter)
|
||||||
} else {
|
} else {
|
||||||
wc := quotedprintable.NewWriter(subWriter)
|
wc := quotedprintable.NewWriter(subWriter)
|
||||||
wc.Write(body)
|
w.err = f(wc)
|
||||||
wc.Close()
|
wc.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue