commands/http: Send req.Files() as multipart
Matt Bell committed
Nov 16, 2014 at 00:47 UTC
132e7402574f9a32768170101cc117ed59df2d98
1 file changed
+26
-20
commands/http/client.go
+26
-20
@@ -10,6 +10,7 @@ import (
10
"strings"
11
12
cmds "github.com/jbenet/go-ipfs/commands"
13
+ config "github.com/jbenet/go-ipfs/config"
14
u "github.com/jbenet/go-ipfs/util"
15
)
16
@@ -42,16 +43,35 @@ func (c *client) Send(req cmds.Request) (cmds.Response, error) {
43
// override with json to send to server
44
req.SetOption(cmds.EncShort, cmds.JSON)
45
45
- query, inputStream, err := getQuery(req)
46
+ query, err := getQuery(req)
47
if err != nil {
48
return nil, err
49
}
50
51
+ var fileReader *MultiFileReader
52
+ if req.Files() != nil {
53
+ fileReader = NewMultiFileReader(req.Files())
54
+ }
55
+
56
path := strings.Join(req.Path(), "/")
57
url := fmt.Sprintf(ApiUrlFormat, c.serverAddress, ApiPath, path, query)
58
53
- // TODO extract string const?
54
- httpRes, err := http.Post(url, "application/octet-stream", inputStream)
59
+ httpReq, err := http.NewRequest("POST", url, fileReader)
60
+ if err != nil {
61
+ return nil, err
62
+ }
63
+
64
+ // TODO extract string consts?
65
+ if fileReader != nil {
66
+ httpReq.Header.Set("Content-Type", "multipart/form-data; boundary="+fileReader.Boundary())
67
+ httpReq.Header.Set("Content-Disposition", "form-data: name=\"files\"")
68
+ } else {
69
+ httpReq.Header.Set("Content-Type", "application/octet-stream")
70
+ }
71
+ version := config.CurrentVersionNumber
72
+ httpReq.Header.Set("User-Agent", fmt.Sprintf("/go-ipfs/%s/", version))
73
+
74
+ httpRes, err := http.DefaultClient.Do(httpReq)
75
if err != nil {
76
return nil, err
77
}
@@ -72,10 +92,7 @@ func (c *client) Send(req cmds.Request) (cmds.Response, error) {
92
return res, nil
93
}
94
75
-func getQuery(req cmds.Request) (string, io.Reader, error) {
76
- // TODO: handle multiple files with multipart
77
- var inputStream io.Reader
78
-
95
+func getQuery(req cmds.Request) (string, error) {
96
query := url.Values{}
97
for k, v := range req.Options() {
98
str := fmt.Sprintf("%v", v)
@@ -94,24 +111,13 @@ func getQuery(req cmds.Request) (string, io.Reader, error) {
111
if argDef.Type == cmds.ArgString {
112
str, ok := arg.(string)
113
if !ok {
97
- return "", nil, u.ErrCast()
114
+ return "", u.ErrCast()
115
}
116
query.Add("arg", str)
100
-
101
- } else {
102
- // TODO: multipart
103
- if inputStream != nil {
104
- return "", nil, fmt.Errorf("Currently, only one file stream is possible per request")
105
- }
106
- var ok bool
107
- inputStream, ok = arg.(io.Reader)
108
- if !ok {
109
- return "", nil, u.ErrCast()
110
- }
117
}
118
}
119
114
- return query.Encode(), inputStream, nil
120
+ return query.Encode(), nil
121
}
122
123
// getResponse decodes a http.Response to create a cmds.Response