jordan-wright / email

Robust and flexible email library for Go
MIT License
2.61k stars 324 forks source link

Old Content-Type headers are retained after email MIME content is generated with Bytes() #131

Open leucos opened 3 years ago

leucos commented 3 years ago

When parsing an email having a Content-Type and boundary, the old boundary value is still returned by the Email instance even though the call to Bytes() generates a new one.

Here is some sample code that demonstrate the issue:

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "net/textproto"

    "github.com/jordan-wright/email"
)

func main() {
    var content = []byte(`Content-Type: multipart/alternative; boundary="000000000000a8b374056d65d2cc"

--000000000000a8b374056d65d2cc
Content-Type: text/plain; charset="UTF-8"; format=flowed; delsp=yes

Hello world !

--000000000000a8b374056d65d2cc
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<html><body>Hello world !</body></html>
--000000000000a8b374056d65d2cc--
`)

    // Original CT headers, kept in 'e'
    e, _ := email.NewEmailFromReader(bytes.NewReader((content)))
    fmt.Println(e.Headers.Get("Content-Type"))

    // Generated headers when using bytes
    body, _ := e.Bytes()
    tp := textproto.NewReader(bufio.NewReader(bytes.NewReader(body)))
    hdrs, _ := tp.ReadMIMEHeader()
    fmt.Println(hdrs.Get("Content-Type"))

    // But e still holds old headers
    fmt.Println(e.Headers.Get("Content-Type"))
}

(try it on https://play.golang.org/p/Wa9nvCf5rz5).

$ go run test.go 
multipart/alternative; boundary="000000000000a8b374056d65d2cc"
multipart/alternative; boundary=1d6ee4a2d342ba18c1ecd4e7070573e9fb57ed43211843becbc7fb6635fe
multipart/alternative; boundary="000000000000a8b374056d65d2cc"

This is a bit misleading, and a somewhat detrimental in certain situations.

May be a call to e.Bytes() could replace MIME Headers with the new Content-Type/multipart value ?