bodyclose
is a static analysis tool which checks whether res.Body
is correctly closed.
You can get bodyclose
by go get
command.
$ go get -u github.com/timakin/bodyclose
bodyclose
run with go vet
as below when Go is 1.12 and higher.
$ go vet -vettool=$(which bodyclose) github.com/timakin/go_api/...
# github.com/timakin/go_api
internal/httpclient/httpclient.go:13:13: response body must be closed
When Go is lower than 1.12, just run bodyclose
command with the package name (import path).
But it cannot accept some options such as --tags
.
$ bodyclose github.com/timakin/go_api/...
~/go/src/github.com/timakin/api/internal/httpclient/httpclient.go:13:13: response body must be closed
bodyclose
validates whether *net/http.Response of HTTP request calls method Body.Close()
such as below code.
resp, err := http.Get("http://example.com/") // Wrong case
if err != nil {
// handle error
}
body, err := ioutil.ReadAll(resp.Body)
This code is wrong. You must call resp.Body.Close when finished reading resp.Body.
resp, err := http.Get("http://example.com/")
if err != nil {
// handle error
}
defer resp.Body.Close() // OK
body, err := ioutil.ReadAll(resp.Body)
In the GoDoc of Client.Do this rule is clearly described.
If you forget this sentence, a HTTP client cannot re-use a persistent TCP connection to the server for a subsequent "keep-alive" request.