Example #1
0
func getSubject(msg *mail.Message) (string, error) {
	var dec mime.WordDecoder
	ret, err := dec.DecodeHeader(msg.Header.Get("Subject"))
	if err != nil {
		return "", err
	}
	return ret, nil
}
Example #2
0
// DecodeHeader (per RFC 2047) using Golang's mime.WordDecoder
func DecodeHeader(input string) string {
	if !strings.Contains(input, "=?") {
		// Don't scan if there is nothing to do here
		return input
	}

	dec := new(mime.WordDecoder)
	dec.CharsetReader = NewCharsetReader
	header, err := dec.DecodeHeader(input)
	if err != nil {
		return input
	}
	return header
}
Example #3
0
// NonASCII Decode non ASCII header string RFC 1342
func NonASCII(encoded string) string {

	regexRFC1342, _ := regexp.Compile(`=\?.*?\?=`)
	dec := new(mime.WordDecoder)
	dec.CharsetReader = charset.NewReader

	result := regexRFC1342.ReplaceAllStringFunc(encoded, func(encoded string) string {
		decoded, err := dec.Decode(encoded)
		if err != nil {
			log.Println("Error decode NonASCII", encoded, err)
			return encoded
		}
		return decoded
	})

	return result
}
Example #4
0
func parseAndDecodeHeader(rawMimeHeader textproto.MIMEHeader, target string,
	mHeader PMIMEHeader) string {
	if targetArray, ok := rawMimeHeader[target]; !ok && len(targetArray) == 0 {
		return ""
	} else {
		var (
			encodedValue string = strings.TrimPrefix(targetArray[0], " ")
			decoded      string
			dec          *mime.WordDecoder = new(mime.WordDecoder)
			err          error
		)
		if decoded, err = dec.DecodeHeader(encodedValue); err != nil {
			fmt.Printf("[watney] WARNING: Couldn't decode string: \n\t%s\n\t%s\n", encodedValue,
				err.Error())
			return encodedValue
		}
		return decoded
	}
}
Example #5
0
func ExampleWordDecoder_Decode() {
	dec := new(mime.WordDecoder)
	header, err := dec.Decode("=?utf-8?q?=C2=A1Hola,_se=C3=B1or!?=")
	if err != nil {
		panic(err)
	}
	fmt.Println(header)

	dec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
		switch charset {
		case "x-case":
			// Fake character set for example.
			// Real use would integrate with packages such
			// as code.google.com/p/go-charset
			content, err := ioutil.ReadAll(input)
			if err != nil {
				return nil, err
			}
			return bytes.NewReader(bytes.ToUpper(content)), nil
		default:
			return nil, fmt.Errorf("unhandled charset %q", charset)
		}
	}
	header, err = dec.Decode("=?x-case?q?hello!?=")
	if err != nil {
		panic(err)
	}
	fmt.Println(header)
	// Output:
	// ¡Hola, señor!
	// HELLO!
}
Example #6
0
func WordDecoder() *mime.WordDecoder {
	decoder := new(mime.WordDecoder)
	decoder.CharsetReader = CharsetReader
	return decoder
}
Example #7
0
// Parse parses a MIME encoded message.
func Parse(r io.Reader) (
	header *Header,
	subject string,
	message string,
	attachments []*Attachment,
	err error,
) {
	var h Header
	// read message
	msg, err := mail.ReadMessage(r)
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	}
	// parse 'From'
	h.From = msg.Header.Get("From")
	if h.From == "" {
		return nil, "", "", nil, log.Error("mime: 'From' not defined")
	}
	// parse 'To'
	h.To = msg.Header.Get("To")
	if h.To == "" {
		return nil, "", "", nil, log.Error("mime: 'To' not defined")
	}
	// parse 'Cc'
	addressList, err := msg.Header.AddressList("Cc")
	if err != nil && err != mail.ErrHeaderNotPresent {
		return nil, "", "", nil, log.Error(err)
	}
	if err != mail.ErrHeaderNotPresent {
		for _, address := range addressList {
			h.Cc = append(h.Cc, address.Address)
		}
	}
	// parse subject
	subj := msg.Header.Get("Subject")
	if subj == "" {
		return nil, "", "", nil, log.Error("mime: 'Subject' not defined")
	}
	dec := new(mime.WordDecoder)
	subject, err = dec.DecodeHeader(subj)
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	}
	// parse 'Message-ID'
	h.MessageID = msg.Header.Get("Message-ID")
	if h.MessageID == "" {
		return nil, "", "", nil, log.Error("mime: 'Message-ID' not defined")
	}
	// parse 'In-Reply-To'
	h.InReplyTo = msg.Header.Get("In-Reply-To")
	// parse 'MIME-Version'
	if msg.Header.Get("MIME-Version") != "1.0" {
		return nil, "", "", nil, log.Error("mime: wrong 'MIME-Version' header")
	}
	// parse 'Content-Type'
	mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	} else if mediaType != "multipart/mixed" {
		return nil, "", "", nil, log.Error("mime: wrong 'Content-Type' header ")
	}
	// read first MIME part (message)
	mr := multipart.NewReader(msg.Body, params["boundary"])
	p, err := mr.NextPart()
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	}
	// check 'Content-Type'
	if p.Header.Get("Content-Type") != "text/plain" {
		return nil, "", "", nil,
			log.Error("mime: expected 'text/plain' Content-Type")
	}
	// check 'Content-Transfer-Encoding'
	if p.Header.Get("Content-Transfer-Encoding") != "base64" {
		return nil, "", "", nil,
			log.Error("mime: expected 'base64' Content-Transfer-Encoding")
	}
	// read message
	enc, err := ioutil.ReadAll(p)
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	}
	content, err := base64.Decode(string(enc))
	if err != nil {
		return nil, "", "", nil, log.Error(err)
	}
	message = string(content)
	// read optional additional MIME parts (attachments)
	for {
		p, err := mr.NextPart()
		if err == io.EOF {
			break
		}
		// parse header
		contentType := p.Header.Get("Content-Type")
		if contentType == "" {
			return nil, "", "", nil,
				log.Error("mime: Content-Type undefined for attachment")
		}
		var filename string
		var inline bool
		for _, disposition := range p.Header["Content-Disposition"] {
			mediaType, params, err := mime.ParseMediaType(disposition)
			if err != nil {
				return nil, "", "", nil, log.Error(err)
			}
			switch mediaType {
			case "attachment":
				filename = params["filename"]
			case "inline":
				inline = true
			default:
				return nil, "", "", nil,
					log.Errorf("mime: unknown Content-Disposition in attachment: %s",
						mediaType)
			}
		}
		if filename == "" {
			log.Error("mime: filename undefined for attachment")
		}

		// parse body
		if err != nil {
			return nil, "", "", nil, log.Error(err)
		}
		enc, err := ioutil.ReadAll(p)
		if err != nil {
			return nil, "", "", nil, log.Error(err)
		}
		content, err := base64.Decode(string(enc))
		if err != nil {
			return nil, "", "", nil, log.Error(err)
		}
		// reconstruct attachment
		attachment := &Attachment{
			Filename:    filename,
			Reader:      bytes.NewBuffer(content),
			ContentType: contentType,
			Inline:      inline,
		}
		attachments = append(attachments, attachment)
	}

	header = &h
	return
}