@cryptotaxi247 / kubo / commits / 132e74025

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