Пример #1
0
func (m *Message) writeMultipartStart(b *bytes.Buffer, writer *multipart.Writer) error {
	multipart := `
Content-Type: multipart/alternative; charset="UTF-8"; boundary="%s"
`
	_, err := b.WriteString(fmt.Sprintf(multipart, writer.Boundary()))
	return err
}
Пример #2
0
func SendMediaRequest(client *twittergo.Client, reqUrl string, params map[string]string, media []byte) (mediaResp twittergo.MediaResponse, err error) {
	var (
		req         *http.Request
		resp        *twittergo.APIResponse
		body        io.ReadWriter = bytes.NewBufferString("")
		mp          *multipart.Writer
		writer      io.Writer
		contentType string
	)
	mp = multipart.NewWriter(body)
	for key, value := range params {
		mp.WriteField(key, value)
	}
	if media != nil {
		if writer, err = mp.CreateFormField("media"); err != nil {
			return
		}
		writer.Write(media)
	}
	contentType = fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary())
	mp.Close()
	if req, err = http.NewRequest("POST", reqUrl, body); err != nil {
		return
	}
	req.Header.Set("Content-Type", contentType)
	if resp, err = client.SendRequest(req); err != nil {
		return
	}
	err = resp.Parse(&mediaResp)
	return
}
Пример #3
0
func (m *Message) writeMultipartEnd(b *bytes.Buffer, writer *multipart.Writer) error {
	multipart := `
--%s--

`
	_, err := b.WriteString(fmt.Sprintf(multipart, writer.Boundary()))
	return err
}
Пример #4
0
func (m *Message) writeContentTypeWithBoundary(b *bytes.Buffer, writer *multipart.Writer, contentType string) error {
	contentTypeFormat := `

--%s
Content-Type: %s; charset=UTF-8;
Content-Transfer-Encoding: 8bit

`
	_, err := b.WriteString(fmt.Sprintf(contentTypeFormat, writer.Boundary(), contentType))
	return err
}
Пример #5
0
func GetBody() (body io.ReadWriter, header string, err error) {
	var (
		mp     *multipart.Writer
		media  []byte
		writer io.Writer
	)
	body = bytes.NewBufferString("")
	mp = multipart.NewWriter(body)
	media, err = ioutil.ReadFile("tweet_media/media.png")
	if err != nil {
		return
	}
	mp.WriteField("status", fmt.Sprintf("Hello %v!", time.Now()))
	writer, err = mp.CreateFormFile("media[]", "media.png")
	if err != nil {
		return
	}
	writer.Write(media)
	header = fmt.Sprintf("multipart/form-data;boundary=%v", mp.Boundary())
	mp.Close()
	return
}
Пример #6
0
// Bytes gets the encoded MIME message.
func (m *Message) Bytes() ([]byte, error) {
	var buffer = &bytes.Buffer{}

	header := textproto.MIMEHeader{}

	var err error

	// Require To, Cc, or Bcc
	// We'll parse the slices into a list of addresses
	// and then make sure that list isn't empty.
	toAddrs := getAddressListString(m.To)
	ccAddrs := getAddressListString(m.Cc)
	bccAddrs := getAddressListString(m.Bcc)

	var hasTo = toAddrs != ""
	var hasCc = ccAddrs != ""
	var hasBcc = bccAddrs != ""

	if !hasTo && !hasCc && !hasBcc {
		return nil, ErrMissingRecipient
	}

	if hasTo {
		header.Add("To", toAddrs)
	}
	if hasCc {
		header.Add("Cc", ccAddrs)
	}
	// BCC header is excluded on purpose.
	// BCC recipients aren't included in the message
	// headers and are only used at the SMTP level.

	var emptyAddress mail.Address
	// Require From address
	if m.From == emptyAddress {
		return nil, ErrMissingFromAddress
	}
	header.Add("From", m.From.String())

	// Optional ReplyTo
	if m.ReplyTo != emptyAddress {
		header.Add("Reply-To", m.ReplyTo.String())
	}

	// Optional Subject
	if m.Subject != "" {
		quotedSubject := qEncodeAndWrap(m.Subject, 9 /* len("Subject: ") */)
		if quotedSubject[0] == '"' {
			// qEncode used simple quoting, which adds quote
			// characters to email subjects.
			quotedSubject = quotedSubject[1 : len(quotedSubject)-1]
		}
		header.Add("Subject", quotedSubject)
	}

	// Date
	if _, ok := m.Headers["Date"]; !ok {
		header.Add("Date", time.Now().UTC().Format(time.RFC822))
	}

	for k, v := range m.Headers {
		header[k] = v
	}

	header.Add("MIME-Version", "1.0")

	var mixedw *multipart.Writer
	var hasAttachments = m.Attachments != nil && len(m.Attachments) > 0
	if hasAttachments {
		// Top level multipart writer for our `multipart/mixed` body.
		// only needed if we have attachments
		mixedw = multipart.NewWriter(buffer)
		header.Add("Content-Type", fmt.Sprintf("multipart/mixed;%s boundary=%s", crlf, mixedw.Boundary()))
		err = writeHeader(buffer, header)
		if err != nil {
			return nil, err
		}
		header = textproto.MIMEHeader{}
		// Write the start of our `multipart/mixed` body.
		_, err = fmt.Fprintf(buffer, "--%s%s", mixedw.Boundary(), crlf)
		if err != nil {
			return nil, err
		}
	}

	var altw *multipart.Writer
	if m.Body != "" && m.HTMLBody != "" {
		// Nested multipart writer for our `multipart/alternative` body.
		altw = multipart.NewWriter(buffer)

		header.Add("Content-Type", fmt.Sprintf("multipart/alternative;%s boundary=%s", crlf, altw.Boundary()))
		err := writeHeader(buffer, header)
		if err != nil {
			return nil, err
		}
	}

	// Only include an empty plain text body if the html body is also empty.
	if m.Body != "" || m.Body == "" && m.HTMLBody == "" {
		if altw != nil {
			header = textproto.MIMEHeader{}
		}
		header.Add("Content-Type", "text/plain; charset=utf-8")
		header.Add("Content-Transfer-Encoding", "quoted-printable")
		//header.Add("Content-Transfer-Encoding", "base64")

		var writer io.Writer
		if altw != nil {
			partw, err := altw.CreatePart(header)
			if err != nil {
				return nil, err
			}
			writer = partw
		} else {
			writer = buffer
			err = writeHeader(buffer, header)
			if err != nil {
				return nil, err
			}
		}

		bodyBytes := []byte(m.Body)
		//encoder := NewBase64MimeEncoder(writer)
		encoder := qprintable.NewEncoder(qprintable.DetectEncoding(m.Body), writer)
		_, err = encoder.Write(bodyBytes)
		if err != nil {
			return nil, err
		}
		err = encoder.Close()
		if err != nil {
			return nil, err
		}
	}

	if m.HTMLBody != "" {
		if altw != nil {
			header = textproto.MIMEHeader{}
		}
		header.Add("Content-Type", "text/html; charset=utf-8")
		//header.Add("Content-Transfer-Encoding", "quoted-printable")
		header.Add("Content-Transfer-Encoding", "base64")

		var writer io.Writer
		if altw != nil {
			partw, err := altw.CreatePart(header)
			if err != nil {
				return nil, err
			}
			writer = partw
		} else {
			writer = buffer
			err = writeHeader(buffer, header)
			if err != nil {
				return nil, err
			}
		}

		htmlBodyBytes := []byte(m.HTMLBody)
		encoder := NewBase64MimeEncoder(writer)
		//encoder := qprintable.NewEncoder(qprintable.DetectEncoding(m.HTMLBody), writer)
		_, err = encoder.Write(htmlBodyBytes)
		if err != nil {
			return nil, err
		}
		err = encoder.Close()
		if err != nil {
			return nil, err
		}
	}

	if altw != nil {
		altw.Close()
	} else {
		_, err = fmt.Fprintf(buffer, "%s", crlf)
		if err != nil {
			return nil, err
		}
	}

	if hasAttachments {

		for _, attachment := range m.Attachments {

			contentType := attachment.ContentType
			if contentType == "" {
				contentType = mime.TypeByExtension(filepath.Ext(attachment.Name))
				if contentType == "" {
					contentType = "application/octet-stream"
				}
			}

			header := textproto.MIMEHeader{}
			header.Add("Content-Type", contentType)
			header.Add("Content-Disposition", fmt.Sprintf(`attachment;%s filename="%s"`, crlf, attachment.Name))
			header.Add("Content-Transfer-Encoding", "base64")

			attachmentPart, err := mixedw.CreatePart(header)
			if err != nil {
				return nil, err
			}

			if attachment.Data != nil {
				encoder := NewBase64MimeEncoder(attachmentPart)
				_, err = io.Copy(encoder, attachment.Data)
				if err != nil {
					return nil, err
				}
				err = encoder.Close()
				if err != nil {
					return nil, err
				}
			}
		}

		mixedw.Close()
	}

	return buffer.Bytes(), nil
}