mirror of
https://github.com/wneessen/go-mail.git
synced 2024-12-23 02:50:39 +01:00
Fixes a bug with attachments. Hopefully addresses #37 as well
By default, the encoding/base64 in Go does not add line breaks to its output. This patch introduces the Base64LineBreaker which satisfies the io.WriteCloser interface Attachments are now correctly broken up into maximum of 76 chars
This commit is contained in:
parent
a3a143de45
commit
701cbbf399
2 changed files with 64 additions and 1 deletions
56
base64_writer.go
Normal file
56
base64_writer.go
Normal file
|
@ -0,0 +1,56 @@
|
|||
package mail
|
||||
|
||||
import "io"
|
||||
|
||||
// Base64LineBreaker is a io.WriteCloser that writes Base64 encoded data streams
|
||||
// with line breaks at a given line length
|
||||
type Base64LineBreaker struct {
|
||||
line [MaxBodyLength]byte
|
||||
used int
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
var nl = []byte(SingleNewLine)
|
||||
|
||||
// Write writes the data stream and inserts a SingleNewLine when the maximum
|
||||
// line length is reached
|
||||
func (l *Base64LineBreaker) Write(b []byte) (n int, err error) {
|
||||
if l.used+len(b) < MaxBodyLength {
|
||||
copy(l.line[l.used:], b)
|
||||
l.used += len(b)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
n, err = l.out.Write(l.line[0:l.used])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
excess := MaxBodyLength - l.used
|
||||
l.used = 0
|
||||
|
||||
n, err = l.out.Write(b[0:excess])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
n, err = l.out.Write(nl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return l.Write(b[excess:])
|
||||
}
|
||||
|
||||
// Close closes the Base64LineBreaker and writes any access data that is still
|
||||
// unwritten in memory
|
||||
func (l *Base64LineBreaker) Close() (err error) {
|
||||
if l.used > 0 {
|
||||
_, err = l.out.Write(l.line[0:l.used])
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = l.out.Write(nl)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -22,6 +22,10 @@ import (
|
|||
// RFC 2047 suggests 76 characters
|
||||
const MaxHeaderLength = 76
|
||||
|
||||
// MaxBodyLength defines the maximum line length for the mail body
|
||||
// RFC 2047 suggests 76 characters
|
||||
const MaxBodyLength = 76
|
||||
|
||||
// SingleNewLine represents a new line that can be used by the msgWriter to issue a carriage return
|
||||
const SingleNewLine = "\r\n"
|
||||
|
||||
|
@ -277,12 +281,14 @@ func (mw *msgWriter) writeBody(f func(io.Writer) (int64, error), e Encoding) {
|
|||
w = mw.pw
|
||||
}
|
||||
wbuf := bytes.Buffer{}
|
||||
lb := Base64LineBreaker{}
|
||||
lb.out = &wbuf
|
||||
|
||||
switch e {
|
||||
case EncodingQP:
|
||||
ew = quotedprintable.NewWriter(&wbuf)
|
||||
case EncodingB64:
|
||||
ew = base64.NewEncoder(base64.StdEncoding, &wbuf)
|
||||
ew = base64.NewEncoder(base64.StdEncoding, &lb)
|
||||
case NoEncoding:
|
||||
_, mw.err = f(&wbuf)
|
||||
n, mw.err = io.Copy(w, &wbuf)
|
||||
|
@ -296,6 +302,7 @@ func (mw *msgWriter) writeBody(f func(io.Writer) (int64, error), e Encoding) {
|
|||
|
||||
_, mw.err = f(ew)
|
||||
mw.err = ew.Close()
|
||||
mw.err = lb.Close()
|
||||
n, mw.err = io.Copy(w, &wbuf)
|
||||
|
||||
// Since the part writer uses the WriteTo() method, we don't need to add the
|
||||
|
|
Loading…
Reference in a new issue