Пример #1
0
func TestEmailHeaders(t *testing.T) {
	var (
		from    = "*****@*****.**"
		to      = "*****@*****.**"
		bcc     = "*****@*****.**"
		subject = "Test"
	)
	_, body, err := emailToMessages(&Email{
		From:    from,
		To:      []string{to},
		Bcc:     []string{bcc},
		Subject: subject,
	})
	if err != nil {
		t.Fatal(err)
	}
	r := bytes.NewBuffer(body)
	m, err := mail.ReadMessage(r)
	if err != nil {
		t.Fatal(err)
	}
	if v := m.Header.Get("From"); v != from {
		t.Fatalf("%s != %s", v, from)
	}
	if v := m.Header.Get("To"); v != to {
		t.Fatalf("%s != %s", v, to)
	}
	if v := m.Header.Get("Bcc"); v != "" {
		t.Fatalf("%s != \"\"", v)
	}
	if v := m.Header.Get("Subject"); v != subject {
		t.Fatalf("%s != %s", v, subject)
	}
}
Пример #2
0
func testInlineAgainstStdLib(t *testing.T, msg *Message, rawBytes []byte) {
	// confirm stdlib can parse it too
	stdlibMsg, err := mail.ReadMessage(bytes.NewReader(rawBytes))
	if err != nil {
		t.Fatal("Standard Library could not parse message:", err)
	}

	// confirm stdlib headers match our headers
	// StandardLibrary is not decoding Q-encoded headers. TODO: Re-enable when GoLang does this.
	//if !reflect.DeepEqual(map[string][]string(msg.Header), map[string][]string(stdlibMsg.Header)) {
	//	t.Fatal("Message does not match its parsed counterpart")
	//}

	// confirm subsequent parts match
	mixedReader := multipart.NewReader(stdlibMsg.Body, boundary(map[string][]string(stdlibMsg.Header)))
	alternativePart, err := mixedReader.NextPart()
	if err != nil {
		t.Fatal("Couldn't get next part", err)
	}

	// test the multipart/alternative
	testMultipartInlineWithStdLib(t, msg.Parts[0], alternativePart)

	// test attachments
	attachmentPart, err := mixedReader.NextPart()
	if err != nil {
		t.Fatal("Couldn't get next part", err)
	}
	testBodyPartWithStdLib(t, msg.Parts[1], attachmentPart)

	// confirm EOF
	if _, err = mixedReader.NextPart(); err != io.EOF {
		t.Fatal("Should be EOF", err)
	}
}
Пример #3
0
func prepTemplate(parent *template.Template, fn, base string) error {
	t := parent.New(base)

	f, err := os.Open(fn)
	if err != nil {
		return err
	}
	defer f.Close()

	msg, err := mail.ReadMessage(f)
	if err != nil {
		return err
	}

	for k, v := range defaultHeaders {
		if msg.Header.Get(k) == "" {
			msg.Header[k] = v
		}
	}

	data := &bytes.Buffer{}

	// This is the only place I could find this method.  :/
	http.Header(msg.Header).Write(data)
	data.Write([]byte{'\r', '\n'})

	_, err = io.Copy(data, msg.Body)
	if err != nil {
		return err
	}

	_, err = t.Parse(data.String())
	return err
}
Пример #4
0
// Get parses the email and returns all relevant data
func Get(con *data.Context, m io.Reader) (*Email, error) {
	msg, err := mail.ReadMessage(m)
	if err != nil {
		return nil, fmt.Errorf("Error at mail.ReadMessage while parsing the email. Error: %v", err)
	}
	con.Log.Debugf("header: %v", msg.Header)

	// get body
	email, err := extract(con, msg.Header, msg.Body)
	if err != nil {
		return nil, fmt.Errorf("Error at extracting email. Error: %v", err)
	}
	//con.Log.Debugf("Received mail: %v", email)

	namespaces, err := getNamespaces(msg)
	if err != nil {
		return nil, fmt.Errorf("Error at parsing the receiver fields. Error: %v", err)
	}
	con.Log.Debugf("Detected namespaces: %v", namespaces)
	email.Namespaces = namespaces

	email.Subject, err = getSubject(msg)
	if err != nil {
		con.Log.Errorf("Could not decode subject. Error: %v", err)
		email.Subject = ""
	}

	return email, nil
}
Пример #5
0
func FetchMessages(c *imap.Client, uidSet *imap.SeqSet) (fetched []MsgData, err error) {
	cmd, errF := c.UIDFetch(uidSet, "RFC822")
	if errF != nil {
		err = errF
		return
	}

	for cmd.InProgress() {
		errC := c.Recv(-1)
		if errC != nil {
			return
		}
		for _, rsp := range cmd.Data {

			uid := imap.AsNumber(rsp.MessageInfo().Attrs["UID"])
			mime := imap.AsBytes(rsp.MessageInfo().Attrs["RFC822"])
			msg, errR := mail.ReadMessage(bytes.NewReader(mime))
			if errR != nil {
				continue
			}
			if msg != nil {
				msgdata := GetMessage(msg, uid)
				fetched = append(fetched, msgdata)
			}
		}
		cmd.Data = nil
	}

	return
}
Пример #6
0
// ReceiveMail will receive an e-mail and echo it back to the sender.
func ReceiveMail(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)

	m, err := mail.ReadMessage(r.Body)
	if err != nil {
		log.Errorf(ctx, "Failed reading a mail!")
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	err = echoMailFunc.Call(ctx, m)
	if err != nil {
		log.Errorf(ctx, "Failed enqueing handler for a mail!")
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	io.WriteString(w, "OK")

	// TODO(flowlo):
	//  1. Check whether range m.Header.AddressList("From")
	//     fits a registered customer
	//  2. Filter mail content for further e-mail addresses
	//  3. Create a Fingerprint
	//  4. Mail the Fingerprint URL to the other address
}
Пример #7
0
func main() {
	rawMessage := `From: Feather <*****@*****.**>
To: [email protected], [email protected]
Subject: =?utf-8?B?5rWL6K+V5Y+R6YCB?=
Date: Fri, 21 May 2010 08:54:49 +0800
Message-ID: <*****@*****.**>
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: plain

Hello Golang Mail`

	buf := bytes.NewBuffer([]byte(rawMessage))
	// parse mail message, buf may from net or somewhere.
	msg, err := mail.ReadMessage(buf)
	if err != nil {
		panic(err)
	}
	// mail body
	body, _ := ioutil.ReadAll(msg.Body)
	fmt.Printf("Mail Body:\n%s\n", body)

	fmt.Println("To Addresses:")
	printAddrs(msg, "to")

	fmt.Println("From Address:")
	printAddrs(msg, "From")

	// auto convert to golang time.Time
	date, _ := msg.Header.Date()
	fmt.Println("Date:", date)

	// mime header will ignore case
	fmt.Println("mime version:", msg.Header.Get("mime-version"))
}
Пример #8
0
func SaveMail(newmail chan *ServerMessage) {
	for {
		message := <-newmail
		parsedMessage, err := mail.ReadMessage(strings.NewReader(message.Body.String()))
		fmt.Println(parsedMessage, err)
	}
}
Пример #9
0
func main() {
	file, _ := os.Open("/Users/rbd/Temp/7ccaa5be-acf7-45c7-a289-c6bd2cb0492a.eml")
	msg, _ := mail.ReadMessage(file)     // Read email using Go's net/mail
	mime, _ := enmime.ParseMIMEBody(msg) // Parse message body with enmime

	// Headers are in the net/mail Message
	fmt.Printf("From: %v\n", msg.Header.Get("From"))

	fmt.Printf("From: %v\n", mime.GetHeader("From"))

	// enmime can decode quoted-printable headers
	fmt.Printf("Subject: %v\n", mime.GetHeader("Subject"))

	// The plain text body is available as mime.Text
	fmt.Printf("Text Body: %v chars\n", len(mime.Text))

	fmt.Printf("Text Body: %s\n", mime.Text)

	// The HTML body is stored in mime.Html
	fmt.Printf("HTML Body: %v chars\n", len(mime.Html))

	// mime.Inlines is a slice of inlined attacments
	fmt.Printf("Inlines: %v\n", len(mime.Inlines))

	// mime.Attachments contains the non-inline attachments
	fmt.Printf("Attachments: %v\n", len(mime.Attachments))
}
Пример #10
0
func UnpackMessage(eml string, errors chan error, wg *sync.WaitGroup) {

	if wg != nil {
		defer wg.Done()
	}

	f, err := os.Open(eml)
	if err != nil {
		errors <- MessageError(
			fmt.Sprintf(
				"Problem opening the %q message file for unpacking: %s",
				eml,
				err.Error()))
		return
	}
	defer f.Close()

	msg, err := mail.ReadMessage(f)
	if err != nil {
		errors <- MessageError(
			fmt.Sprintf(
				"Problem opening the %q message file for unpacking: %s",
				eml,
				err.Error()))
		return
	}

	partsIterate(msg.Header, msg.Body, cutExt(eml), errors)
}
Пример #11
0
func HandleMail(client_data string, client_rcpt_to string, gConfig map[string]string) {

	var to = client_rcpt_to[1 : len(client_rcpt_to)-1]

	addresses := strings.Split(to, ",")

	for _, address := range addresses {

		emailData := client_data[:len(client_data)-4]
		msg, err := mail.ReadMessage(bytes.NewBuffer([]byte(emailData)))

		if err != nil {
			sendErrorReport(err, emailData, address, gConfig)
			return
		}

		headers := make(map[string]string)
		for key, value := range msg.Header {
			headers[key] = value[0]
		}

		body, _ := ioutil.ReadAll(msg.Body)

		encryptedBody := encrypt(string(body), address, gConfig)

		sendEmail(headers, encryptedBody, address, gConfig)

	}

}
Пример #12
0
func main() {
	flag.Parse()

	if filename == nil || strings.TrimSpace(*filename) == "" {
		log.Fatal("--file is required")
	}

	fh, err := os.Open(*filename)
	if err != nil {
		log.Fatal(err)
	}

	msg, err := mail.ReadMessage(fh)
	if err != nil {
		log.Fatal(err)
	}

	m, err := mime.ParseMIMEBody(msg)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Fprintf(os.Stderr, "HTML=%d Text=%d\n", len(m.HTML), len(m.Text))
	if len(m.HTML) <= 0 {
		log.Fatalf("No HTML part found in %s\n", *filename)
	}

	w := bufio.NewWriter(os.Stdout)
	n, err := w.WriteString(m.HTML)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Fprintf(os.Stderr, "Wrote %d bytes to standard output\n", n)
	w.Flush()
}
Пример #13
0
func fetchAllHeaders(user, authToken, box string) ([]mail.Header, error) {
	c, err := imap.DialTLS("imap.gmail.com:993", nil)
	if err != nil {
		return nil, err
	}
	_, err = c.Auth(oauthSASL{user, authToken})
	if err != nil {
		return nil, err
	}
	c.Select(box, true)
	set, _ := imap.NewSeqSet("1:*")
	cmd, err := imap.Wait(c.Fetch(set, "BODY.PEEK[HEADER.FIELDS (DATE)]"))
	if err != nil {
		return nil, err
	}
	headers := make([]mail.Header, 0, len(cmd.Data))
	parseFailures := 0
	for _, rsp := range cmd.Data {
		header := imap.AsBytes(rsp.MessageInfo().Attrs["BODY[HEADER.FIELDS (DATE)]"]) // no peek
		if msg, _ := mail.ReadMessage(bytes.NewReader(header)); msg != nil {
			headers = append(headers, msg.Header)
		} else {
			parseFailures++
		}
	}
	log.Printf("Finished processing %d emails with %d parse failures.\n", len(headers), parseFailures)
	return headers, nil
}
Пример #14
0
func LoadMessage(path string) (*Message, error) {
	m := &Message{path: path}
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	fi, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	msg, err := mail.ReadMessage(f)
	if err != nil {
		return nil, err
	}
	m.From = mimedec(msg.Header.Get("From"))
	m.ReplyTo = mimedec(msg.Header.Get("reply-to"))
	m.CCs = mimedec(msg.Header.Get("cc"))
	m.To = mimedec(msg.Header.Get("To"))

	m.Subject = mimedec(msg.Header.Get("Subject"))
	m.Date, _ = msg.Header.Date()
	m.size = fi.Size()

	i := strings.LastIndex(path, ":2,")
	if i != -1 {
		m.Flags = parseFlags(path[i+3:])
	}
	return m, nil
}
Пример #15
0
func TestMessage(t *testing.T) {
	msg := &Message{}

	msg.SetFrom("Marc Weistroff", "*****@*****.**")
	msg.AddTo("Marc Weistroff", "*****@*****.**")
	msg.AddTo("Foo Bar", "*****@*****.**")
	msg.AddCc("Bar Foo", "*****@*****.**")
	msg.AddBcc("The Boss", "*****@*****.**")
	msg.Subject = "Lorem ipsum gollum"
	msg.Body = `Oy Mate!
Wanna drink a beer tonight?

Cheers`

	proof, _ := mail.ReadMessage(bytes.NewBuffer(msg.Bytes()))
	body, _ := ioutil.ReadAll(proof.Body)
	if string(body) != msg.Body {
		t.Log(string(body))
		t.FailNow()
	}

	from, _ := proof.Header.AddressList("From")
	if from[0].Name != "Marc Weistroff" || from[0].Address != "*****@*****.**" {
		t.Log(from[0])
		t.FailNow()
	}

	to, _ := proof.Header.AddressList("To")
	if len(to) != 2 {
		proof.Header.Get("To")
		t.Log(to)
		t.FailNow()
	}
	if to[0].Name != "Marc Weistroff" || to[0].Address != "*****@*****.**" {
		t.Log(to[0])
		t.FailNow()
	}
	if to[1].Name != "Foo Bar" || to[1].Address != "*****@*****.**" {
		t.Log(to[1])
		t.FailNow()
	}

	cc, _ := proof.Header.AddressList("Cc")
	if cc[0].Name != "Bar Foo" || cc[0].Address != "*****@*****.**" {
		t.Log(cc[0])
		t.FailNow()
	}

	bcc, _ := proof.Header.AddressList("Bcc")
	if bcc[0].Name != "The Boss" || bcc[0].Address != "*****@*****.**" {
		t.Log(bcc[0])
		t.FailNow()
	}

	subject := proof.Header.Get("Subject")
	if subject != msg.Subject {
		t.Log(subject)
		t.FailNow()
	}
}
Пример #16
0
// Top will return a varible number of lines for a given message as a
// mail.Message object.
func (c *Client) Top(msg int, n int) (m *mail.Message, err error) {
	if _, err = c.Cmd("%s %d %d\r\n", TOP, msg, n); err != nil {
		return
	}

	m, err = mail.ReadMessage(c.r)
	if err != nil {
		return
	}

	// mail.ReadMessage does not consume the message end dot in the buffer
	// so we must move the buffer along. Need to find a better way of
	// doing this.
	line, err := c.ReadLine()
	if err != nil {

		return
	}
	if line != "." {
		if err = c.r.UnreadByte(); err != nil {
			return
		}
	}
	return
}
Пример #17
0
func stringToMessage(mimestring string) *mail.Message {
	msg, err := mail.ReadMessage(strings.NewReader(mimestring))
	if err != nil {
		panic("err")
	}
	return msg
}
Пример #18
0
// looks into the specified detectiondir to find and parse all mails in that dir
func parse_mails(c map[string]string) []email {

	// get entries of directory
	files, _ := ioutil.ReadDir(c["Detectiondir"])

	// allocate space to store the parsed mails
	mails := make([]email, 0, len(files))

	// loop over all non-dir-files and try to parse mails
	// return a slice of those files that are parsable as mail
	for _, f := range files {

		if !f.IsDir() {

			// try parsing
			content, _ := ioutil.ReadFile(c["Detectiondir"] + "/" + f.Name())
			mail, err := mail.ReadMessage(bytes.NewReader(content))

			// save if parsable
			if err == nil {
				mails = append(mails, email{f.Name(), mail})
			}

		}

	}

	return mails
}
Пример #19
0
// ReceiveMail will receive an e-mail and echo it back to the sender.
func ReceiveMail(ctx context.Context, w http.ResponseWriter, r *http.Request) (int, error) {
	m, err := mail.ReadMessage(r.Body)
	if err != nil {
		log.Errorf(ctx, "Failed reading a mail!")
		return http.StatusInternalServerError, err
	}

	err = echoMailFunc.Call(ctx, m)
	if err != nil {
		log.Errorf(ctx, "Failed enqueing handler for a mail!")
		return http.StatusInternalServerError, err
	}

	if _, err = io.WriteString(w, "OK"); err != nil {
		return http.StatusInternalServerError, err
	}

	return http.StatusOK, nil

	// TODO(flowlo):
	//  1. Check whether range m.Header.AddressList("From")
	//     fits a registered customer
	//  2. Filter mail content for further e-mail addresses
	//  3. Create a Fingerprint
	//  4. Mail the Fingerprint URL to the other address
}
Пример #20
0
func WalkParts(r io.Reader, parse ParseFn, pc *ParserContext, maxDepth int) error {
	msg, err := mail.ReadMessage(r)
	if err != nil {
		return err
	}
	return partWalker(msg.Body, []int{}, msg.Header, parse, pc, maxDepth)
}
Пример #21
0
func main() {
	if len(os.Args) != 2 {
		log.Fatalln("pass mail file path")
	}

	r, err := os.Open(os.Args[1])
	if err != nil {
		log.Fatalln(err)
	}
	defer r.Close()

	msg, err := mail.ReadMessage(r)
	if err != nil {
		log.Fatalln(err)
	}

	for k, _ := range msg.Header {
		log.Printf("%s: %s\n", k, msg.Header.Get(k))
	}

	d, err := msg.Header.Date()
	if err != nil {
		log.Fatalln(err)
	}
	log.Println(d)

	log.Println(msg.Header.Get("subject"))
}
Пример #22
0
func Example() {
	file, _ := os.Open("test-data/mail/qp-utf8-header.raw")
	msg, _ := mail.ReadMessage(file)     // Read email using Go's net/mail
	mime, _ := enmime.ParseMIMEBody(msg) // Parse message body with enmime

	// Headers are in the net/mail Message
	fmt.Printf("From: %v\n", msg.Header.Get("From"))

	// enmime can decode quoted-printable headers
	fmt.Printf("Subject: %v\n", mime.GetHeader("Subject"))

	// The plain text body is available as mime.Text
	fmt.Printf("Text Body: %v chars\n", len(mime.Text))

	// The HTML body is stored in mime.Html
	fmt.Printf("HTML Body: %v chars\n", len(mime.Html))

	// mime.Inlines is a slice of inlined attacments
	fmt.Printf("Inlines: %v\n", len(mime.Inlines))

	// mime.Attachments contains the non-inline attachments
	fmt.Printf("Attachments: %v\n", len(mime.Attachments))

	// Output:
	// From: James Hillyerd <*****@*****.**>
	// Subject: MIME UTF8 Test ¢ More Text
	// Text Body: 1300 chars
	// HTML Body: 1736 chars
	// Inlines: 0
	// Attachments: 0
}
Пример #23
0
func (m *Message) parse(r io.Reader) error {
	msg, err := mail.ReadMessage(r)
	if err != nil {
		return err
	}
	m.Subject = msg.Header.Get("Subject")
	m.To = msg.Header.Get("To")

	mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
	if err != nil || !strings.HasPrefix(mediaType, "multipart/") {
		slurp, _ := ioutil.ReadAll(msg.Body)
		m.Body = string(slurp)
		return nil
	}
	if err := m.parseMultipart(msg.Body, params["boundary"]); err != nil {
		return err
	}
	// If we didn't find a text/plain body, pick the first body we did find.
	if m.Body == "" {
		for _, body := range m.bodies {
			if body != "" {
				m.Body = body
				break
			}
		}
	}
	return nil
}
Пример #24
0
func ExampleReadMessage() {
	msg := `Date: Mon, 23 Jun 2015 11:40:36 -0400
From: Gopher <*****@*****.**>
To: Another Gopher <*****@*****.**>
Subject: Gophers at Gophercon

Message body
`

	r := strings.NewReader(msg)
	m, err := mail.ReadMessage(r)
	if err != nil {
		log.Fatal(err)
	}

	header := m.Header
	fmt.Println("Date:", header.Get("Date"))
	fmt.Println("From:", header.Get("From"))
	fmt.Println("To:", header.Get("To"))
	fmt.Println("Subject:", header.Get("Subject"))

	body, err := ioutil.ReadAll(m.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", body)

	// Output:
	// Date: Mon, 23 Jun 2015 11:40:36 -0400
	// From: Gopher <*****@*****.**>
	// To: Another Gopher <*****@*****.**>
	// Subject: Gophers at Gophercon
	// Message body
}
Пример #25
0
func makeMailHandler(mandrillAPI *gochimp.MandrillAPI, sendLimiter *rerate.Limiter, spamLimiter *rerate.Limiter) func(smtpd.Peer, smtpd.Envelope) error {
	return func(peer smtpd.Peer, env smtpd.Envelope) error {
		// Validate data before sending them
		if _, err := mail.ReadMessage(bytes.NewReader(env.Data)); err != nil {
			return err
		}

		response, err := mandrillAPI.MessageSendRaw(string(env.Data), env.Recipients, gochimp.Recipient{Email: env.Sender}, false)
		if err != nil {
			log.WithFields(log.Fields{
				"peer":  peer,
				"error": err,
			}).Info("Error sending message")
			return smtpd.Error{Code: 451, Message: "Error with Remote API"}
		}
		if response[0].Status == "rejected" && response[0].RejectedReason == "spam" {
			log.WithFields(log.Fields{
				"peer":           peer,
				"RejectedReason": response[0].RejectedReason,
			}).Info("Message filtered as SPAM")

			if err := spamLimiter.Inc(peer.HeloName); err != nil {
				log.WithFields(log.Fields{
					"heloName": peer.HeloName,
					"error":    err,
				}).Warn("Can't increment send")
			}
			return smtpd.Error{Code: 451, Message: "Spam filtered, increment rate limit"}
		}

		return nil
	}
}
Пример #26
0
func TestTextEmail(t *testing.T) {
	m := NewMailer("", "username", "password", "host", "587")
	for _, info := range tests {

		msg := m.NewMessage(info.messageValues[0], info.messageValues[1], info.messageValues[2], info.messageValues[3], info.messageValues[4])

		// verifying length since date & boundary values will mess up the direct byte comparison
		if len(info.messageContent) != len(msg.Bytes()) {
			t.Error("Expected content length to match: \n" + string(msg.Bytes()) + "\n == \n" + string(info.messageContent))
		}

		if msg.IsText != info.isText || msg.IsHtml != info.isHtml {
			t.Error("Email should match text/html content expectations.")
		}

		// verify parts of the message explicitly
		check, _ := mail.ReadMessage(bytes.NewBuffer(msg.Bytes()))
		from, _ := check.Header.AddressList("From")
		if len(from) > 0 {
			if from[0].Name != info.messageValues[1] || from[0].Address != info.messageValues[1] {
				t.Error("From address to be: " + info.messageValues[1] + " got: " + from[0].Address)
			}
		}

		subject := check.Header.Get("Subject")
		if len(from) > 0 {
			if subject != info.messageValues[2] {
				t.Error("From address to be: " + info.messageValues[2] + " got: " + subject)
			}
		}

	}
}
Пример #27
0
func testBasicAgainstStdLib(t *testing.T, msg *Message, rawBytes []byte) {
	// confirm stdlib can parse it too
	stdlibMsg, err := mail.ReadMessage(bytes.NewReader(rawBytes))
	if err != nil {
		t.Fatal("Standard Library could not parse message:", err)
	}

	// confirm stdlib headers match our headers
	if !reflect.DeepEqual(map[string][]string(msg.Header), map[string][]string(stdlibMsg.Header)) {
		t.Fatal("Message does not match its parsed counterpart")
	}

	// confirm subsequent parts match
	mixedReader := multipart.NewReader(stdlibMsg.Body, boundary(map[string][]string(stdlibMsg.Header)))
	alternativePart, err := mixedReader.NextPart()
	if err != nil {
		t.Fatal("Couldn't get next part", err)
	}

	// test the multipart/alternative
	testMultipartAlternativeWithStdLib(t, msg.Parts[0], alternativePart)

	// confirm EOF
	if _, err = mixedReader.NextPart(); err != io.EOF {
		t.Fatal("Should be EOF", err)
	}
}
Пример #28
0
func readMail() (*mail.Message, error) {
	var buffer *bytes.Buffer

	buffer = bytes.NewBuffer(nil)
	io.Copy(buffer, os.Stdin)
	return mail.ReadMessage(buffer)
}
Пример #29
0
func getAddresses(fn string, results chan<- *Contact) {
	file, err := os.Open(fn)
	if err != nil {
		log.Fatalf("Failed to open %q: %s\n", fn, err)
	}

	msg, err := mail.ReadMessage(file)
	if err != nil {
		log.Printf("Failed to parse message %q: %s\n", fn, err)
		return
	}

	headers := []string{"to", "cc"}
	for _, header := range headers {
		addrs, err := msg.Header.AddressList(header)
		if err != nil {
			//log.Printf("Failed to parse %s: header in %q: %s", header, fn, err)
			continue
		}

		for _, addr := range addrs {
			c := &Contact{*addr, fn}
			results <- c
		}
	}
}
Пример #30
0
// parseMail reads a mailfile's content and parses it into a mail-struct if one of ours.
func parseMail(path string) (email, error) {
	// to date the mails found
	t := time.Now()

	// try parsing
	f, err := os.Open(path)
	if err != nil {
		return email{}, err
	}
	defer fileClose(f)

	mail, err := mail.ReadMessage(io.LimitReader(f, 8192))
	if err != nil {
		return email{}, err
	}

	payl, err := ioutil.ReadAll(mail.Body)
	if err != nil {
		return email{}, err
	}
	payloadbytes := bytes.TrimSpace(payl) // mostly for trailing "\n"

	p, err := decomposePayload(payloadbytes)
	// return if parsable
	// (non-parsable mails are not sent by us (or broken) and therefore not needed
	if err != nil {
		return email{}, errNotOurDept
	}

	return email{path, p.configname, p.token, time.Unix(0, p.timestamp), t}, nil
}