Skip to content

Commit

Permalink
insert linebreaks into base64 encoded blobs
Browse files Browse the repository at this point in the history
  • Loading branch information
laochailan committed Jun 23, 2015
1 parent 7567fc8 commit baf500a
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 4 deletions.
56 changes: 52 additions & 4 deletions mail.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,16 @@ func composeMail() *Mail {
func composeReply(m *Mail) *Mail {
reply := composeMail()

reply.Header["To"] = []string{m.Header.Get("From")}
reply.Header["From"] = []string{m.Header.Get("To")}
to, _, err := qp.DecodeHeader(m.Header.Get("From"))
if err != nil {
to = m.Header.Get("From")
}
from, _, err := qp.DecodeHeader(m.Header.Get("To"))
if err != nil {
from = m.Header.Get("To")
}
reply.Header["To"] = []string{to}
reply.Header["From"] = []string{from}
reply.Header["In-Reply-To"] = []string{m.Header.Get("Message-ID")}

refs := m.Header["References"]
Expand All @@ -186,7 +194,10 @@ func composeReply(m *Mail) *Mail {
newrefs = append(newrefs, m.Header.Get("Message-ID"))
reply.Header["References"] = newrefs

subj := m.Header.Get("Subject")
subj, _, err := qp.DecodeHeader(m.Header.Get("Subject"))
if err != nil {
subj = m.Header.Get("Subject")
}
if lower := strings.ToLower(subj); !strings.HasPrefix(lower, "re:") &&
!strings.HasPrefix(lower, "aw:") {
subj = "Re: " + subj
Expand Down Expand Up @@ -246,7 +257,8 @@ func (m *Mail) attachFile(filename string) error {
}

var buf bytes.Buffer
enc := base64.NewEncoder(base64.StdEncoding, &buf)
nlInsert := newNewlineInserter(&buf, 78)
enc := base64.NewEncoder(base64.StdEncoding, nlInsert)
_, err = io.Copy(enc, file)
if err != nil {
return err
Expand Down Expand Up @@ -406,3 +418,39 @@ func sendMail(m *Mail) error {

return nil
}

// inserts a newline character after lineLength bytes. only for ascii because in wider
// encoding runes could be chopped up.
type newlineInserter struct {
w io.Writer
lineLength int
counter int
}

func newNewlineInserter(w io.Writer, lineLength int) *newlineInserter {
return &newlineInserter{w, lineLength, 0}
}

func (n *newlineInserter) Write(data []byte) (int, error) {
written := 0
for n.counter+len(data) > n.lineLength {
num, err := n.w.Write(data[:n.lineLength-n.counter])
written += num
if err != nil {
return written, err
}
num, err = n.w.Write([]byte{'\n'})
written += num
if err != nil {
return written, err
}

data = data[n.lineLength-n.counter:]
n.counter = 0
}

num, err := n.w.Write(data)
written += num
n.counter += num
return written, err
}
18 changes: 18 additions & 0 deletions mail_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"bytes"
"fmt"
"testing"
)

func TestNewlineInserter(t *testing.T) {
var buf bytes.Buffer
ni := newNewlineInserter(&buf, 4)
ni.Write([]byte("aaaa"))
ni.Write([]byte("aaaaaaaaaa"))
fmt.Println(buf.String())
if buf.String() != "aaaa\naaaa\naaaa\naa" {
t.Fail()
}
}

0 comments on commit baf500a

Please sign in to comment.