Merge lp:~dave-cheney/goose/003-fix-fd-leak into lp:goose

Proposed by Dave Cheney
Status: Work in progress
Proposed branch: lp:~dave-cheney/goose/003-fix-fd-leak
Merge into: lp:goose
Diff against target: 121 lines (+12/-19)
3 files modified
http/client.go (+11/-15)
swift/live_test.go (+0/-2)
swift/swift.go (+1/-2)
To merge this branch: bzr merge lp:~dave-cheney/goose/003-fix-fd-leak
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+159772@code.launchpad.net

Description of the change

goose/http: always close response body

https://codereview.appspot.com/8804047/

To post a comment you must log in.

Unmerged revisions

86. By Dave Cheney

always close response body before returning from sendRequest

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'http/client.go'
2--- http/client.go 2013-04-17 04:38:44 +0000
3+++ http/client.go 2013-04-19 08:31:29 +0000
4@@ -50,7 +50,7 @@
5 RespValue interface{}
6 ReqReader io.Reader
7 ReqLength int
8- RespReader io.ReadCloser
9+ RespReader io.Reader
10 }
11
12 const (
13@@ -107,18 +107,11 @@
14 }
15 }
16 headers := createHeaders(reqData.ReqHeaders, contentTypeJSON, token)
17- respBody, err := c.sendRequest(
18+ respData, err := c.sendRequest(
19 method, url, bytes.NewReader(body), len(body), headers, reqData.ExpectedStatus, logger)
20 if err != nil {
21 return
22 }
23- defer respBody.Close()
24- respData, err := ioutil.ReadAll(respBody)
25- if err != nil {
26- err = errors.Newf(err, "failed reading the response body")
27- return
28- }
29-
30 if len(respData) > 0 {
31 if reqData.RespValue != nil {
32 err = json.Unmarshal(respData, &reqData.RespValue)
33@@ -150,7 +143,7 @@
34 return
35 }
36 if reqData.RespReader != nil {
37- reqData.RespReader = respBody
38+ reqData.RespReader = bytes.NewReader(respBody)
39 }
40 return
41 }
42@@ -161,19 +154,19 @@
43 // headers: HTTP headers to include with the request.
44 // expectedStatus: a slice of allowed response status codes.
45 func (c *Client) sendRequest(method, URL string, reqReader io.Reader, length int, headers http.Header,
46- expectedStatus []int, logger *log.Logger) (rc io.ReadCloser, err error) {
47+ expectedStatus []int, logger *log.Logger) (body []byte, err error) {
48 reqData := make([]byte, length)
49 if reqReader != nil {
50 nrRead, err := io.ReadFull(reqReader, reqData)
51 if err != nil {
52- err = errors.Newf(err, "failed reading the request data, read %v of %v bytes", nrRead, length)
53- return rc, err
54+ return nil, errors.Newf(err, "failed reading the request data, read %v of %v bytes", nrRead, length)
55 }
56 }
57 rawResp, err := c.sendRateLimitedRequest(method, URL, headers, reqData, logger)
58 if err != nil {
59 return
60 }
61+ defer rawResp.Body.Close()
62 foundStatus := false
63 if len(expectedStatus) == 0 {
64 expectedStatus = []int{http.StatusOK}
65@@ -186,10 +179,13 @@
66 }
67 if !foundStatus && len(expectedStatus) > 0 {
68 err = handleError(URL, rawResp)
69- rawResp.Body.Close()
70 return
71 }
72- return rawResp.Body, err
73+ body, err = ioutil.ReadAll(rawResp.Body)
74+ if err != nil {
75+ err = errors.Newf(err, "failed reading the response body")
76+ }
77+ return body, err
78 }
79
80 func (c *Client) sendRateLimitedRequest(method, URL string, headers http.Header, reqData []byte,
81
82=== modified file 'swift/live_test.go'
83--- swift/live_test.go 2013-02-20 02:30:14 +0000
84+++ swift/live_test.go 2013-04-19 08:31:29 +0000
85@@ -90,7 +90,6 @@
86 c.Check(err, IsNil)
87 readData, err := ioutil.ReadAll(r)
88 c.Check(err, IsNil)
89- r.Close()
90 c.Check(string(readData), Equals, data)
91 err = s.swift.DeleteObject(s.containerName, object)
92 c.Assert(err, IsNil)
93@@ -182,7 +181,6 @@
94 c.Check(err, IsNil)
95 readData, err := ioutil.ReadAll(r)
96 c.Check(err, IsNil)
97- r.Close()
98 c.Check(string(readData), Equals, data)
99 err = s.swift.DeleteObject(s.containerName, object)
100 c.Assert(err, IsNil)
101
102=== modified file 'swift/swift.go'
103--- swift/swift.go 2013-02-11 05:01:34 +0000
104+++ swift/swift.go 2013-04-19 08:31:29 +0000
105@@ -80,7 +80,6 @@
106 if err != nil {
107 return
108 }
109- defer rc.Close()
110 return ioutil.ReadAll(rc)
111 }
112
113@@ -93,7 +92,7 @@
114 }
115
116 // GetObject retrieves the specified object's data.
117-func (c *Client) GetReader(containerName, objectName string) (rc io.ReadCloser, err error) {
118+func (c *Client) GetReader(containerName, objectName string) (rc io.Reader, err error) {
119 requestData := goosehttp.RequestData{RespReader: &emptyReadCloser}
120 err = c.touchObject(&requestData, client.GET, containerName, objectName)
121 return requestData.RespReader, err

Subscribers

People subscribed via source and target branches