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
+}