Update vendor/
This commit is contained in:
116
vendor/github.com/emersion/go-message/writer.go
generated
vendored
Normal file
116
vendor/github.com/emersion/go-message/writer.go
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/textproto"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// From https://golang.org/src/mime/multipart/writer.go?s=2140:2215#L76
|
||||
func writeHeader(w io.Writer, header Header) error {
|
||||
keys := make([]string, 0, len(header))
|
||||
for k := range header {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
for _, v := range header[k] {
|
||||
if _, err := io.WriteString(w, formatHeaderField(k, v)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := io.WriteString(w, "\r\n")
|
||||
return err
|
||||
}
|
||||
|
||||
// A Writer formats entities.
|
||||
type Writer struct {
|
||||
w io.Writer
|
||||
c io.Closer
|
||||
mw *multipart.Writer
|
||||
}
|
||||
|
||||
// newWriter creates a new Writer writing to w with the provided header. Nothing
|
||||
// is written to w when it is called. header is modified in-place.
|
||||
func newWriter(w io.Writer, header Header) *Writer {
|
||||
ww := &Writer{w: w}
|
||||
|
||||
mediaType, mediaParams, _ := header.ContentType()
|
||||
if strings.HasPrefix(mediaType, "multipart/") {
|
||||
ww.mw = multipart.NewWriter(ww.w)
|
||||
|
||||
// Do not set ww's io.Closer for now: if this is a multipart entity but
|
||||
// CreatePart is not used (only Write is used), then the final boundary
|
||||
// is expected to be written by the user too. In this case, ww.Close
|
||||
// shouldn't write the final boundary.
|
||||
|
||||
if mediaParams["boundary"] != "" {
|
||||
ww.mw.SetBoundary(mediaParams["boundary"])
|
||||
} else {
|
||||
mediaParams["boundary"] = ww.mw.Boundary()
|
||||
header.SetContentType(mediaType, mediaParams)
|
||||
}
|
||||
|
||||
header.Del("Content-Transfer-Encoding")
|
||||
} else {
|
||||
wc := encodingWriter(header.Get("Content-Transfer-Encoding"), ww.w)
|
||||
ww.w = wc
|
||||
ww.c = wc
|
||||
}
|
||||
|
||||
return ww
|
||||
}
|
||||
|
||||
// CreateWriter creates a new Writer writing to w. If header contains an
|
||||
// encoding, data written to the Writer will automatically be encoded with it.
|
||||
func CreateWriter(w io.Writer, header Header) (*Writer, error) {
|
||||
ww := newWriter(w, header)
|
||||
if err := writeHeader(w, header); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ww, nil
|
||||
}
|
||||
|
||||
// Write implements io.Writer.
|
||||
func (w *Writer) Write(b []byte) (int, error) {
|
||||
return w.w.Write(b)
|
||||
}
|
||||
|
||||
// Close implements io.Closer.
|
||||
func (w *Writer) Close() error {
|
||||
if w.c != nil {
|
||||
return w.c.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreatePart returns a Writer to a new part in this multipart entity. If this
|
||||
// entity is not multipart, it fails. The body of the part should be written to
|
||||
// the returned io.WriteCloser.
|
||||
func (w *Writer) CreatePart(header Header) (*Writer, error) {
|
||||
if w.mw == nil {
|
||||
return nil, errors.New("cannot create a part in a non-multipart message")
|
||||
}
|
||||
|
||||
if w.c == nil {
|
||||
// We know that the user calls CreatePart so Close should write the final
|
||||
// boundary
|
||||
w.c = w.mw
|
||||
}
|
||||
|
||||
// cw -> ww -> pw -> w.mw -> w.w
|
||||
|
||||
ww := &struct{ io.Writer }{nil}
|
||||
cw := newWriter(ww, header)
|
||||
pw, err := w.mw.CreatePart(textproto.MIMEHeader(header))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ww.Writer = pw
|
||||
return cw, nil
|
||||
}
|
Reference in New Issue
Block a user