@cryptotaxi247 / kubo / commits / fdb71eb5d

commands: Added MultiFileReader (read a File as multipart data)

Matt Bell committed Nov 16, 2014 at 00:05 UTC fdb71eb5dc477d040e885921d3208dcd79664d97
1 file changed +75
commands/http/multifilereader.go new
+75
@@ -0,0 +1,75 @@
1 +package http
2 +
3 +import (
4 + "bytes"
5 + "io"
6 + "mime/multipart"
7 +
8 + cmds "github.com/jbenet/go-ipfs/commands"
9 +)
10 +
11 +type MultiFileReader struct {
12 + io.Reader
13 +
14 + files cmds.File
15 + currentFile cmds.File
16 + buf bytes.Buffer
17 + mpWriter *multipart.Writer
18 + closed bool
19 +}
20 +
21 +func NewMultiFileReader(file cmds.File) *MultiFileReader {
22 + mfr := &MultiFileReader{
23 + files: file,
24 + }
25 + mfr.mpWriter = multipart.NewWriter(&mfr.buf)
26 +
27 + return mfr
28 +}
29 +
30 +func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) {
31 + // if we are closed, end reading
32 + if mfr.closed && mfr.buf.Len() == 0 {
33 + return 0, io.EOF
34 + }
35 +
36 + // if the current file isn't set, advance to the next file
37 + if mfr.currentFile == nil {
38 + mfr.currentFile, err = mfr.files.NextFile()
39 + if err == io.EOF || (err == nil && mfr.currentFile == nil) {
40 + mfr.mpWriter.Close()
41 + mfr.closed = true
42 + } else if err != nil {
43 + return 0, err
44 + }
45 +
46 + if !mfr.closed {
47 + _, err := mfr.mpWriter.CreateFormFile("file", mfr.currentFile.FileName())
48 + if err != nil {
49 + return 0, err
50 + }
51 + }
52 + }
53 +
54 + var reader io.Reader
55 +
56 + if mfr.buf.Len() > 0 {
57 + // if the buffer has something in it, read from it
58 + reader = &mfr.buf
59 +
60 + } else if mfr.currentFile != nil {
61 + // otherwise, read from file data
62 + reader = mfr.currentFile
63 + }
64 +
65 + written, err = reader.Read(buf)
66 + if err == io.EOF && reader == mfr.currentFile {
67 + mfr.currentFile = nil
68 + return mfr.Read(buf)
69 + }
70 + return written, err
71 +}
72 +
73 +func (mfr *MultiFileReader) Boundary() string {
74 + return mfr.mpWriter.Boundary()
75 +}