Selaa lähdekoodia

Added check for default Content-Type
Added check for non-multipart emails

Fixes #25
Fixes #26

Jordan Wright 9 vuotta sitten
vanhempi
commit
48c3347cb8
2 muutettua tiedostoa jossa 45 lisäystä ja 2 poistoa
  1. 14 2
      email.go
  2. 31 0
      email_test.go

+ 14 - 2
email.go

@@ -22,8 +22,8 @@ import (
 )
 
 const (
-	// MaxLineLength is the maximum line length per RFC 2045
-	MaxLineLength = 76
+	MaxLineLength      = 76                             // MaxLineLength is the maximum line length per RFC 2045
+	defaultContentType = "text/plain; charset=us-ascii" // defaultContentType is the default Content-Type according to RFC 2045, section 5.2
 )
 
 // ErrMissingBoundary is returned when there is no boundary given for a multipart entity
@@ -119,10 +119,15 @@ func NewEmailFromReader(r io.Reader) (*Email, error) {
 // careful when parsing unknown MIME structures!
 func parseMIMEParts(hs textproto.MIMEHeader, b io.Reader) ([]*part, error) {
 	var ps []*part
+	// If no content type is given, set it to the default
+	if _, ok := hs["Content-Type"]; !ok {
+		hs.Set("Content-Type", defaultContentType)
+	}
 	ct, params, err := mime.ParseMediaType(hs.Get("Content-Type"))
 	if err != nil {
 		return ps, err
 	}
+	// If it's a multipart email, recursively parse the parts
 	if strings.HasPrefix(ct, "multipart/") {
 		if _, ok := params["boundary"]; !ok {
 			return ps, ErrMissingBoundary
@@ -153,6 +158,13 @@ func parseMIMEParts(hs textproto.MIMEHeader, b io.Reader) ([]*part, error) {
 				ps = append(ps, &part{body: buf.Bytes(), header: p.Header})
 			}
 		}
+	} else {
+		// If it is not a multipart email, parse the body content as a single "part"
+		var buf bytes.Buffer
+		if _, err := io.Copy(&buf, b); err != nil {
+			return ps, err
+		}
+		ps = append(ps, &part{body: buf.Bytes(), header: hs})
 	}
 	return ps, nil
 }

+ 31 - 0
email_test.go

@@ -12,6 +12,7 @@ import (
 	"mime/quotedprintable"
 	"net/mail"
 	"net/smtp"
+	"net/textproto"
 )
 
 func TestEmailTextHtmlAttachment(t *testing.T) {
@@ -152,6 +153,36 @@ d-printable decoding.</div>
 
 }
 
+func TestNonMultipartEmailFromReader(t *testing.T) {
+	ex := &Email{
+		Text:    []byte("This is a test message!"),
+		Subject: "Example Subject (no MIME Type)",
+		Headers: textproto.MIMEHeader{},
+	}
+	ex.Headers.Add("Content-Type", "text/plain; charset=us-ascii")
+	ex.Headers.Add("Message-ID", "<foobar@example.com>")
+	raw := []byte(`From: "Foo Bar" <foobar@example.com>
+Content-Type: text/plain
+To: foobar@example.com 
+Subject: Example Subject (no MIME Type)
+Message-ID: <foobar@example.com>
+
+This is a test message!`)
+	e, err := NewEmailFromReader(bytes.NewReader(raw))
+	if err != nil {
+		t.Fatalf("Error creating email %s", err.Error())
+	}
+	if ex.Subject != e.Subject {
+		t.Errorf("Incorrect subject. %#q != %#q\n", ex.Subject, e.Subject)
+	}
+	if !bytes.Equal(ex.Text, e.Text) {
+		t.Errorf("Incorrect body. %#q != %#q\n", ex.Text, e.Text)
+	}
+	if ex.Headers.Get("Message-ID") != e.Headers.Get("Message-ID") {
+		t.Errorf("Incorrect message ID. %#q != %#q\n", ex.Headers.Get("Message-ID"), e.Headers.Get("Message-ID"))
+	}
+}
+
 func ExampleGmail() {
 	e := NewEmail()
 	e.From = "Jordan Wright <test@gmail.com>"