Commit 40858b43 authored by Matt Bell's avatar Matt Bell Committed by Juan Batiz-Benet

commands/http: Added stream argument handling to client and request parser

parent 39c78fbe
......@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"os"
"strings"
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
......@@ -14,7 +15,7 @@ import (
cmds "github.com/jbenet/go-ipfs/commands"
)
const ApiPath = "/api/v0"
const ApiPath = "/api/v0" // TODO: make configurable
func Send(req cmds.Request) (cmds.Response, error) {
addr, err := ma.NewMultiaddr(req.Context().Config.Addresses.API)
......@@ -40,18 +41,33 @@ func Send(req cmds.Request) (cmds.Response, error) {
req.SetOption(cmds.EncLong, cmds.JSON)
}
// TODO: handle multiple files with multipart
var in io.Reader
query := "?"
for k, v := range req.Options() {
query += "&" + k + "=" + v.(string)
}
for _, arg := range req.Arguments() {
s, ok := arg.(string)
if ok {
query += "&arg=" + s
args := req.Arguments()
for i, arg := range args {
if req.Command().Arguments[i].Type == cmds.ArgString {
query += "&arg=" + arg.(string)
} else {
// TODO: multipart
if in != nil {
return nil, fmt.Errorf("Currently, only one file stream is possible per request")
}
in, err = os.Open(arg.(string))
if err != nil {
return nil, err
}
args[i] = in
}
}
httpRes, err := http.Post(url+query, "application/octet-stream", nil)
httpRes, err := http.Post(url+query, "application/octet-stream", in)
if err != nil {
return nil, err
}
......
......@@ -10,7 +10,7 @@ import (
// Parse parses the data in a http.Request and returns a command Request object
func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
path := strings.Split(r.URL.Path, "/")[3:]
args := make([]interface{}, 0)
stringArgs := make([]string, 0)
cmd, err := root.Get(path[:len(path)-1])
if err != nil {
......@@ -24,36 +24,48 @@ func Parse(r *http.Request, root *cmds.Command) (cmds.Request, error) {
// if the last string in the path isn't a subcommand, use it as an argument
// e.g. /objects/Qabc12345 (we are passing "Qabc12345" to the "objects" command)
args = append(args, path[len(path)-1])
stringArgs = append(stringArgs, path[len(path)-1])
path = path[:len(path)-1]
} else {
cmd = sub
}
opts, args2 := parseOptions(r)
args = append(args, args2...)
opts, stringArgs2 := parseOptions(r)
stringArgs = append(stringArgs, stringArgs2...)
// Note that the argument handling here is dumb, it does not do any error-checking.
// (Arguments are further processed when the request is passed to the command to run)
args := make([]interface{}, len(cmd.Arguments))
for i, arg := range cmd.Arguments {
if arg.Type == cmds.ArgString {
if len(stringArgs) > 0 {
args[i] = stringArgs[0]
stringArgs = stringArgs[1:]
}
} else {
// TODO: create multipart streams for file args
args[i] = r.Body
}
}
return cmds.NewRequest(path, opts, args, cmd), nil
}
func parseOptions(r *http.Request) (map[string]interface{}, []interface{}) {
func parseOptions(r *http.Request) (map[string]interface{}, []string) {
opts := make(map[string]interface{})
args := make([]interface{}, 0)
var args []string
query := r.URL.Query()
for k, v := range query {
if k == "arg" {
for _, s := range v {
args = append(args, interface{}(s))
}
args = v
} else {
opts[k] = v[0]
}
}
// TODO: create multipart streams for file args
// default to setting encoding to JSON
_, short := opts[cmds.EncShort]
_, long := opts[cmds.EncLong]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment