Used the new quotedprintable package from the standard library
This commit is contained in:
parent
11b919ab49
commit
a7fe250544
59
export.go
59
export.go
|
@ -5,10 +5,9 @@ import (
|
|||
"encoding/base64"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"mime/quotedprintable"
|
||||
"net/mail"
|
||||
"time"
|
||||
|
||||
"gopkg.in/alexcesaro/quotedprintable.v2"
|
||||
)
|
||||
|
||||
// Export converts the message into a net/mail.Message.
|
||||
|
@ -169,8 +168,9 @@ func (w *messageWriter) writeBody(body []byte, enc Encoding) {
|
|||
} else if enc == Unencoded {
|
||||
subWriter.Write(body)
|
||||
} else {
|
||||
writer := quotedprintable.NewEncoder(newQpLineWriter(subWriter))
|
||||
writer := quotedprintable.NewWriter(subWriter)
|
||||
writer.Write(body)
|
||||
writer.Close()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,56 +207,3 @@ func (w *base64LineWriter) Write(p []byte) (int, error) {
|
|||
|
||||
return n + len(p), nil
|
||||
}
|
||||
|
||||
// qpLineWriter limits text encoded in quoted-printable to 76 characters per
|
||||
// line
|
||||
type qpLineWriter struct {
|
||||
w io.Writer
|
||||
lineLen int
|
||||
}
|
||||
|
||||
func newQpLineWriter(w io.Writer) *qpLineWriter {
|
||||
return &qpLineWriter{w: w}
|
||||
}
|
||||
|
||||
func (w *qpLineWriter) Write(p []byte) (int, error) {
|
||||
n := 0
|
||||
for len(p) > 0 {
|
||||
// If the text is not over the limit, write everything
|
||||
if len(p) < maxLineLen-w.lineLen {
|
||||
w.w.Write(p)
|
||||
w.lineLen += len(p)
|
||||
return n + len(p), nil
|
||||
}
|
||||
|
||||
i := bytes.IndexAny(p[:maxLineLen-w.lineLen+2], "\n")
|
||||
// If there is a newline before the limit, write the end of the line
|
||||
if i != -1 && (i != maxLineLen-w.lineLen+1 || p[i-1] == '\r') {
|
||||
w.w.Write(p[:i+1])
|
||||
p = p[i+1:]
|
||||
n += i + 1
|
||||
w.lineLen = 0
|
||||
continue
|
||||
}
|
||||
|
||||
// Quoted-printable text must not be cut between an equal sign and the
|
||||
// two following characters
|
||||
var toWrite int
|
||||
if maxLineLen-w.lineLen-2 >= 0 && p[maxLineLen-w.lineLen-2] == '=' {
|
||||
toWrite = maxLineLen - w.lineLen - 2
|
||||
} else if p[maxLineLen-w.lineLen-1] == '=' {
|
||||
toWrite = maxLineLen - w.lineLen - 1
|
||||
} else {
|
||||
toWrite = maxLineLen - w.lineLen
|
||||
}
|
||||
|
||||
// Insert the newline where it is needed
|
||||
w.w.Write(p[:toWrite])
|
||||
w.w.Write([]byte("=\r\n"))
|
||||
p = p[toWrite:]
|
||||
n += toWrite
|
||||
w.lineLen = 0
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
|
33
gomail.go
33
gomail.go
|
@ -11,8 +11,6 @@ import (
|
|||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gopkg.in/alexcesaro/quotedprintable.v2"
|
||||
)
|
||||
|
||||
// Message represents an email.
|
||||
|
@ -23,7 +21,7 @@ type Message struct {
|
|||
embedded []*File
|
||||
charset string
|
||||
encoding Encoding
|
||||
hEncoder *quotedprintable.HeaderEncoder
|
||||
hEncoder mime.WordEncoder
|
||||
}
|
||||
|
||||
type header map[string][]string
|
||||
|
@ -44,13 +42,11 @@ func NewMessage(settings ...MessageSetting) *Message {
|
|||
|
||||
msg.applySettings(settings)
|
||||
|
||||
var e quotedprintable.Encoding
|
||||
if msg.encoding == Base64 {
|
||||
e = quotedprintable.B
|
||||
msg.hEncoder = mime.BEncoding
|
||||
} else {
|
||||
e = quotedprintable.Q
|
||||
msg.hEncoder = mime.QEncoding
|
||||
}
|
||||
msg.hEncoder = e.NewHeaderEncoder(msg.charset)
|
||||
|
||||
return msg
|
||||
}
|
||||
|
@ -104,7 +100,7 @@ const (
|
|||
// SetHeader sets a value to the given header field.
|
||||
func (msg *Message) SetHeader(field string, value ...string) {
|
||||
for i := range value {
|
||||
value[i] = encodeHeader(msg.hEncoder, value[i])
|
||||
value[i] = msg.encodeHeader(value[i])
|
||||
}
|
||||
msg.header[field] = value
|
||||
}
|
||||
|
@ -134,16 +130,13 @@ func (msg *Message) FormatAddress(address, name string) string {
|
|||
buf := getBuffer()
|
||||
defer putBuffer(buf)
|
||||
|
||||
if !quotedprintable.NeedsEncoding(name) {
|
||||
enc := msg.encodeHeader(name)
|
||||
if enc == name {
|
||||
quote(buf, name)
|
||||
} else if hasSpecials(name) {
|
||||
buf.WriteString(mime.BEncoding.Encode(msg.charset, name))
|
||||
} else {
|
||||
var n string
|
||||
if hasSpecials(name) {
|
||||
n = encodeHeader(quotedprintable.B.NewHeaderEncoder(msg.charset), name)
|
||||
} else {
|
||||
n = encodeHeader(msg.hEncoder, name)
|
||||
}
|
||||
buf.WriteString(n)
|
||||
buf.WriteString(enc)
|
||||
}
|
||||
buf.WriteString(" <")
|
||||
buf.WriteString(address)
|
||||
|
@ -307,12 +300,8 @@ func hasSpecials(text string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func encodeHeader(enc *quotedprintable.HeaderEncoder, value string) string {
|
||||
if !quotedprintable.NeedsEncoding(value) {
|
||||
return value
|
||||
}
|
||||
|
||||
return enc.Encode(value)
|
||||
func (msg *Message) encodeHeader(value string) string {
|
||||
return msg.hEncoder.Encode(msg.charset, value)
|
||||
}
|
||||
|
||||
var bufPool = sync.Pool{
|
||||
|
|
|
@ -38,14 +38,14 @@ func TestMessage(t *testing.T) {
|
|||
"tobis@example.com",
|
||||
"cc@example.com",
|
||||
},
|
||||
content: "From: =?UTF-8?Q?Se=C3=B1or_From?= <from@example.com>\r\n" +
|
||||
"To: =?UTF-8?Q?Se=C3=B1or_To?= <to@example.com>, tobis@example.com\r\n" +
|
||||
content: "From: =?UTF-8?q?Se=C3=B1or_From?= <from@example.com>\r\n" +
|
||||
"To: =?UTF-8?q?Se=C3=B1or_To?= <to@example.com>, tobis@example.com\r\n" +
|
||||
"Cc: \"A, B\" <cc@example.com>\r\n" +
|
||||
"X-To: =?UTF-8?B?w6AsIGI=?= <ccbis@example.com>\r\n" +
|
||||
"X-To: =?UTF-8?b?w6AsIGI=?= <ccbis@example.com>\r\n" +
|
||||
"X-Date: Wed, 25 Jun 2014 17:46:00 +0000\r\n" +
|
||||
"X-Date-2: Wed, 25 Jun 2014 17:46:00 +0000\r\n" +
|
||||
"X-Headers: Test, =?UTF-8?Q?Caf=C3=A9?=\r\n" +
|
||||
"Subject: =?UTF-8?Q?=C2=A1Hola,_se=C3=B1or!?=\r\n" +
|
||||
"X-Headers: Test, =?UTF-8?q?Caf=C3=A9?=\r\n" +
|
||||
"Subject: =?UTF-8?q?=C2=A1Hola,_se=C3=B1or!?=\r\n" +
|
||||
"Content-Type: text/plain; charset=UTF-8\r\n" +
|
||||
"Content-Transfer-Encoding: quoted-printable\r\n" +
|
||||
"\r\n" +
|
||||
|
@ -90,7 +90,7 @@ func TestCustomMessage(t *testing.T) {
|
|||
to: []string{"to@example.com"},
|
||||
content: "From: from@example.com\r\n" +
|
||||
"To: to@example.com\r\n" +
|
||||
"Subject: =?ISO-8859-1?B?Q2Fmw6k=?=\r\n" +
|
||||
"Subject: =?ISO-8859-1?b?Q2Fmw6k=?=\r\n" +
|
||||
"Content-Type: text/html; charset=ISO-8859-1\r\n" +
|
||||
"Content-Transfer-Encoding: base64\r\n" +
|
||||
"\r\n" +
|
||||
|
@ -114,7 +114,7 @@ func TestUnencodedMessage(t *testing.T) {
|
|||
to: []string{"to@example.com"},
|
||||
content: "From: from@example.com\r\n" +
|
||||
"To: to@example.com\r\n" +
|
||||
"Subject: =?UTF-8?Q?Caf=C3=A9?=\r\n" +
|
||||
"Subject: =?UTF-8?q?Caf=C3=A9?=\r\n" +
|
||||
"Content-Type: text/html; charset=UTF-8\r\n" +
|
||||
"Content-Transfer-Encoding: 8bit\r\n" +
|
||||
"\r\n" +
|
||||
|
@ -439,13 +439,13 @@ func TestQpLineLength(t *testing.T) {
|
|||
msg.SetHeader("From", "from@example.com")
|
||||
msg.SetHeader("To", "to@example.com")
|
||||
msg.SetBody("text/plain",
|
||||
strings.Repeat("0", 77)+"\r\n"+
|
||||
strings.Repeat("0", 76)+"à\r\n"+
|
||||
strings.Repeat("0", 76)+"\r\n"+
|
||||
strings.Repeat("0", 75)+"à\r\n"+
|
||||
strings.Repeat("0", 74)+"à\r\n"+
|
||||
strings.Repeat("0", 73)+"à\r\n"+
|
||||
strings.Repeat("0", 76)+"\r\n"+
|
||||
strings.Repeat("0", 77)+"\n")
|
||||
strings.Repeat("0", 72)+"à\r\n"+
|
||||
strings.Repeat("0", 75)+"\r\n"+
|
||||
strings.Repeat("0", 76)+"\n")
|
||||
|
||||
want := message{
|
||||
from: "from@example.com",
|
||||
|
@ -455,13 +455,13 @@ func TestQpLineLength(t *testing.T) {
|
|||
"Content-Type: text/plain; charset=UTF-8\r\n" +
|
||||
"Content-Transfer-Encoding: quoted-printable\r\n" +
|
||||
"\r\n" +
|
||||
strings.Repeat("0", 76) + "=\r\n0\r\n" +
|
||||
strings.Repeat("0", 76) + "=\r\n=C3=A0\r\n" +
|
||||
strings.Repeat("0", 75) + "=\r\n0\r\n" +
|
||||
strings.Repeat("0", 75) + "=\r\n=C3=A0\r\n" +
|
||||
strings.Repeat("0", 74) + "=\r\n=C3=A0\r\n" +
|
||||
strings.Repeat("0", 73) + "=C3=\r\n=A0\r\n" +
|
||||
strings.Repeat("0", 76) + "\r\n" +
|
||||
strings.Repeat("0", 76) + "=\r\n0\n",
|
||||
strings.Repeat("0", 73) + "=\r\n=C3=A0\r\n" +
|
||||
strings.Repeat("0", 72) + "=C3=\r\n=A0\r\n" +
|
||||
strings.Repeat("0", 75) + "\r\n" +
|
||||
strings.Repeat("0", 75) + "=\r\n0\r\n",
|
||||
}
|
||||
|
||||
testMessage(t, msg, 0, want)
|
||||
|
|
Loading…
Reference in New Issue