1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-10-25 10:27:01 +08:00

address comments from CR and fix random failures

License: MIT
Signed-off-by: Jeromy <jeromyj@gmail.com>
This commit is contained in:
Jeromy
2015-07-27 09:30:52 -07:00
parent 1ce310be8b
commit 23d41e0823
2 changed files with 29 additions and 19 deletions

View File

@ -30,10 +30,18 @@ type Client interface {
type client struct {
serverAddress string
httpClient http.Client
}
func NewClient(address string) Client {
return &client{address}
return &client{
serverAddress: address,
httpClient: http.Client{
Transport: &http.Transport{
DisableKeepAlives: true,
},
},
}
}
func (c *client) Send(req cmds.Request) (cmds.Response, error) {
@ -85,20 +93,20 @@ func (c *client) Send(req cmds.Request) (cmds.Response, error) {
// TODO extract string consts?
if fileReader != nil {
httpReq.Header.Set("Content-Type", "multipart/form-data; boundary="+fileReader.Boundary())
httpReq.Header.Set("Content-Disposition", "form-data: name=\"files\"")
httpReq.Header.Set(contentTypeHeader, "multipart/form-data; boundary="+fileReader.Boundary())
httpReq.Header.Set(contentDispHeader, "form-data: name=\"files\"")
} else {
httpReq.Header.Set("Content-Type", "application/octet-stream")
httpReq.Header.Set(contentTypeHeader, applicationOctetStream)
}
version := config.CurrentVersionNumber
httpReq.Header.Set("User-Agent", fmt.Sprintf("/go-ipfs/%s/", version))
httpReq.Header.Set(uaHeader, fmt.Sprintf("/go-ipfs/%s/", version))
ec := make(chan error, 1)
rc := make(chan cmds.Response, 1)
dc := req.Context().Done()
go func() {
httpRes, err := http.DefaultClient.Do(httpReq)
httpRes, err := c.httpClient.Do(httpReq)
if err != nil {
ec <- err
return
@ -182,24 +190,25 @@ func getResponse(httpRes *http.Response, req cmds.Request) (cmds.Response, error
res.SetLength(length)
}
res.SetCloser(httpRes.Body)
rr := &httpResponseReader{httpRes}
res.SetCloser(rr)
if contentType != "application/json" {
if contentType != applicationJson {
// for all non json output types, just stream back the output
res.SetOutput(&httpResponseReader{httpRes})
res.SetOutput(rr)
return res, nil
} else if len(httpRes.Header.Get(channelHeader)) > 0 {
// if output is coming from a channel, decode each chunk
outChan := make(chan interface{})
go readStreamedJson(req, httpRes, outChan)
go readStreamedJson(req, rr, outChan)
res.SetOutput((<-chan interface{})(outChan))
return res, nil
}
dec := json.NewDecoder(&httpResponseReader{httpRes})
dec := json.NewDecoder(rr)
// If we ran into an error
if httpRes.StatusCode >= http.StatusBadRequest {
@ -211,7 +220,7 @@ func getResponse(httpRes *http.Response, req cmds.Request) (cmds.Response, error
e.Message = "Command not found."
e.Code = cmds.ErrClient
case contentType == "text/plain":
case contentType == plainText:
// handle non-marshalled errors
buf := bytes.NewBuffer(nil)
io.Copy(buf, httpRes.Body)
@ -244,9 +253,9 @@ func getResponse(httpRes *http.Response, req cmds.Request) (cmds.Response, error
// read json objects off of the given stream, and write the objects out to
// the 'out' channel
func readStreamedJson(req cmds.Request, httpRes *http.Response, out chan<- interface{}) {
func readStreamedJson(req cmds.Request, rr io.Reader, out chan<- interface{}) {
defer close(out)
dec := json.NewDecoder(&httpResponseReader{httpRes})
dec := json.NewDecoder(rr)
outputType := reflect.TypeOf(req.Command().Type)
ctx := req.Context()
@ -254,9 +263,7 @@ func readStreamedJson(req cmds.Request, httpRes *http.Response, out chan<- inter
for {
v, err := decodeTypedVal(outputType, dec)
if err != nil {
// since we are just looping reading on the response, the only way to
// know we are 'done' is for the consumer to close the response body.
// doing so doesnt throw an io.EOF, but we want to treat it like one.
// reading on a closed response body is as good as an io.EOF here
if !(strings.Contains(err.Error(), "read on closed response body") || err == io.EOF) {
log.Error(err)
}
@ -268,7 +275,6 @@ func readStreamedJson(req cmds.Request, httpRes *http.Response, out chan<- inter
return
case out <- v:
}
}
}

View File

@ -36,10 +36,14 @@ const (
StreamErrHeader = "X-Stream-Error"
streamHeader = "X-Stream-Output"
channelHeader = "X-Chunked-Output"
uaHeader = "User-Agent"
contentTypeHeader = "Content-Type"
contentLengthHeader = "Content-Length"
contentDispHeader = "Content-Disposition"
transferEncodingHeader = "Transfer-Encoding"
applicationJson = "application/json"
applicationOctetStream = "application/octet-stream"
plainText = "text/plain"
)
var mimeTypes = map[string]string{
@ -156,7 +160,7 @@ func sendResponse(w http.ResponseWriter, req cmds.Request, res cmds.Response) {
return
}
status := 200
status := http.StatusOK
// if response contains an error, write an HTTP error status code
if e := res.Error(); e != nil {
if e.Code == cmds.ErrClient {