summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go')
-rw-r--r--vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go101
1 files changed, 101 insertions, 0 deletions
diff --git a/vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go b/vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go
new file mode 100644
index 00000000..26d8e850
--- /dev/null
+++ b/vendor/github.com/technoweenie/multipartstreamer/multipartstreamer.go
@@ -0,0 +1,101 @@
+/*
+Package multipartstreamer helps you encode large files in MIME multipart format
+without reading the entire content into memory. It uses io.MultiReader to
+combine an inner multipart.Reader with a file handle.
+*/
+package multipartstreamer
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "os"
+ "path/filepath"
+)
+
+type MultipartStreamer struct {
+ ContentType string
+ bodyBuffer *bytes.Buffer
+ bodyWriter *multipart.Writer
+ closeBuffer *bytes.Buffer
+ reader io.Reader
+ contentLength int64
+}
+
+// New initializes a new MultipartStreamer.
+func New() (m *MultipartStreamer) {
+ m = &MultipartStreamer{bodyBuffer: new(bytes.Buffer)}
+
+ m.bodyWriter = multipart.NewWriter(m.bodyBuffer)
+ boundary := m.bodyWriter.Boundary()
+ m.ContentType = "multipart/form-data; boundary=" + boundary
+
+ closeBoundary := fmt.Sprintf("\r\n--%s--\r\n", boundary)
+ m.closeBuffer = bytes.NewBufferString(closeBoundary)
+
+ return
+}
+
+// WriteFields writes multiple form fields to the multipart.Writer.
+func (m *MultipartStreamer) WriteFields(fields map[string]string) error {
+ var err error
+
+ for key, value := range fields {
+ err = m.bodyWriter.WriteField(key, value)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// WriteReader adds an io.Reader to get the content of a file. The reader is
+// not accessed until the multipart.Reader is copied to some output writer.
+func (m *MultipartStreamer) WriteReader(key, filename string, size int64, reader io.Reader) (err error) {
+ m.reader = reader
+ m.contentLength = size
+
+ _, err = m.bodyWriter.CreateFormFile(key, filename)
+ return
+}
+
+// WriteFile is a shortcut for adding a local file as an io.Reader.
+func (m *MultipartStreamer) WriteFile(key, filename string) error {
+ fh, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+
+ stat, err := fh.Stat()
+ if err != nil {
+ return err
+ }
+
+ return m.WriteReader(key, filepath.Base(filename), stat.Size(), fh)
+}
+
+// SetupRequest sets up the http.Request body, and some crucial HTTP headers.
+func (m *MultipartStreamer) SetupRequest(req *http.Request) {
+ req.Body = m.GetReader()
+ req.Header.Add("Content-Type", m.ContentType)
+ req.ContentLength = m.Len()
+}
+
+func (m *MultipartStreamer) Boundary() string {
+ return m.bodyWriter.Boundary()
+}
+
+// Len calculates the byte size of the multipart content.
+func (m *MultipartStreamer) Len() int64 {
+ return m.contentLength + int64(m.bodyBuffer.Len()) + int64(m.closeBuffer.Len())
+}
+
+// GetReader gets an io.ReadCloser for passing to an http.Request.
+func (m *MultipartStreamer) GetReader() io.ReadCloser {
+ reader := io.MultiReader(m.bodyBuffer, m.reader, m.closeBuffer)
+ return ioutil.NopCloser(reader)
+}