From ee2d5d66afca74ddd1f6fb845f5dc58c37cc0656 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Tue, 15 Jul 2014 09:04:04 -0700 Subject: [PATCH] v2_client: read whole response body before close Client have to read whole response bodies if they want the advantage of reusing TCP connections. https://code.google.com/p/go/source/detail?r=d4e1ec84876c0f5611ab86a03826da14b866efb2&name=release-branch.go1.1&path=/src/pkg/net/http/transport.go --- etcd/v2_client.go | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/etcd/v2_client.go b/etcd/v2_client.go index 2fb006d62..11b11bfb2 100644 --- a/etcd/v2_client.go +++ b/etcd/v2_client.go @@ -72,7 +72,7 @@ func (c *v2client) GetMachines(url string) ([]*machineMessage, *etcdErr.Error) { } msgs := new([]*machineMessage) - if uerr := c.parseJSONResponse(resp, msgs); uerr != nil { + if uerr := c.readJSONResponse(resp, msgs); uerr != nil { return nil, uerr } return *msgs, nil @@ -85,7 +85,7 @@ func (c *v2client) GetClusterConfig(url string) (*config.ClusterConfig, *etcdErr } config := new(config.ClusterConfig) - if uerr := c.parseJSONResponse(resp, config); uerr != nil { + if uerr := c.readJSONResponse(resp, config); uerr != nil { return nil, uerr } return config, nil @@ -102,20 +102,20 @@ func (c *v2client) AddMachine(url string, name string, info *context) *etcdErr.E if err != nil { return clientError(err) } - defer resp.Body.Close() - if err := c.checkErrorResponse(resp); err != nil { + if err := c.readErrorResponse(resp); err != nil { return err } return nil } -func (c *v2client) parseJSONResponse(resp *http.Response, val interface{}) *etcdErr.Error { - defer resp.Body.Close() - - if err := c.checkErrorResponse(resp); err != nil { +func (c *v2client) readJSONResponse(resp *http.Response, val interface{}) *etcdErr.Error { + if err := c.readErrorResponse(resp); err != nil { return err } + defer resp.Body.Close() + defer ioutil.ReadAll(resp.Body) + if err := json.NewDecoder(resp.Body).Decode(val); err != nil { log.Printf("Error parsing join response: %v", err) return clientError(err) @@ -123,16 +123,19 @@ func (c *v2client) parseJSONResponse(resp *http.Response, val interface{}) *etcd return nil } -func (c *v2client) checkErrorResponse(resp *http.Response) *etcdErr.Error { - if resp.StatusCode != http.StatusOK { - uerr := &etcdErr.Error{} - if err := json.NewDecoder(resp.Body).Decode(uerr); err != nil { - log.Printf("Error parsing response to etcd error: %v", err) - return clientError(err) - } - return uerr +func (c *v2client) readErrorResponse(resp *http.Response) *etcdErr.Error { + if resp.StatusCode == http.StatusOK { + return nil } - return nil + defer resp.Body.Close() + defer ioutil.ReadAll(resp.Body) + + uerr := &etcdErr.Error{} + if err := json.NewDecoder(resp.Body).Decode(uerr); err != nil { + log.Printf("Error parsing response to etcd error: %v", err) + return clientError(err) + } + return uerr } // put sends server side PUT request.