mirror of
https://github.com/wneessen/go-mail.git
synced 2024-12-23 02:50:39 +01:00
Merge pull request #38 from wneessen/37-attachment-length
Fixes bug with attachment encoding
This commit is contained in:
commit
c6fe75f2d3
2 changed files with 68 additions and 1 deletions
60
base64_writer.go
Normal file
60
base64_writer.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
// SPDX-FileCopyrightText: 2022 Winni Neessen <winni@neessen.dev>
|
||||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
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