googleapi: try to hit EOF after decoding JSON response, before Close
Makes it more likely we'll reuse connections.
LGTM=adg
R=adg
CC=golang-codereviews
https://codereview.appspot.com/58630043
diff --git a/google-api-go-generator/gen.go b/google-api-go-generator/gen.go
index 7a9e17f..74f14ea 100644
--- a/google-api-go-generator/gen.go
+++ b/google-api-go-generator/gen.go
@@ -1162,7 +1162,7 @@
pn(`req.Header.Set("User-Agent", "google-api-go-client/` + goGenVersion + `")`)
pn("res, err := c.s.client.Do(req);")
pn("if err != nil { return %serr }", nilRet)
- pn("defer res.Body.Close()")
+ pn("defer googleapi.CloseBody(res)")
pn("if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet)
if retTypeComma == "" {
pn("return nil")
diff --git a/googleapi/googleapi.go b/googleapi/googleapi.go
index 8599b57..0aeedfd 100644
--- a/googleapi/googleapi.go
+++ b/googleapi/googleapi.go
@@ -264,3 +264,26 @@
u.Opaque = u.Scheme + ":" + u.Opaque
}
}
+
+// CloseBody is used to close res.Body.
+// Prior to calling Close, it also tries to Read a small amount to see an EOF.
+// Not seeing an EOF can prevent HTTP Transports from reusing connections.
+func CloseBody(res *http.Response) {
+ if res == nil || res.Body == nil {
+ return
+ }
+ // Justification for 3 byte reads: two for up to "\r\n" after
+ // a JSON/XML document, and then 1 to see EOF if we haven't yet.
+ // TODO(bradfitz): detect Go 1.3+ and skip these reads.
+ // See https://codereview.appspot.com/58240043
+ // and https://codereview.appspot.com/49570044
+ buf := make([]byte, 1)
+ for i := 0; i < 3; i++ {
+ _, err := res.Body.Read(buf)
+ if err != nil {
+ break
+ }
+ }
+ res.Body.Close()
+
+}