Skip to content
forked from timakin/bodyclose

Analyzer: checks whether HTTP response body is closed and a re-use of TCP connection is not blocked.

License

Notifications You must be signed in to change notification settings

atzoum/reuseconn

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

reuseconn

reuseconn is a static analysis tool which checks whether res.Body is correctly closed and read so that the underlying TCP connection can be reused.

Install

You can get reuseconn by go get command.

$ go get -u github.com/atzoum/reuseconn

How to use

reuseconn run with go vet as below.

$ go vet -vettool=$(which reuseconn) github.com/atzoum/go_api/...
# github.com/atzoum/go_api
internal/httpclient/httpclient.go:13:13: response body must be closed

But it cannot accept some options such as --tags.

$ reuseconn github.com/atzoum/go_api/...
~/go/src/github.com/atzoum/api/internal/httpclient/httpclient.go:13:13: response body must be closed

Analyzer

reuseconn validates whether a *net/http.Response of HTTP request is properly disposed after used. E.g.

func main() {
	resp, err := http.Get("http://example.com/") // Wrong case
	if err != nil {
		// handle error
	}
	body, err := ioutil.ReadAll(resp.Body)
}

The above code is wrong. You must properly dispose resp.Body when done. To avoid a scenario where you forget to read the body in some scenarios and the connection is not reused, reuseconn enforces disposal to be performed within a single function which performs both operations.

func disposeResponseBody(resp *http.Response) {
	if resp != nil && resp.Body != nil {
		// if the body is already read in some scenarios, the below operation becomes a no-op
		_, _ = io.Copy(io.Discard, resp.Body) 
		_ = resp.Body.Close()
	}
}

func main() {
	resp, err := http.Get("http://example.com/")
	defer disposeResponseBody(resp) // OK
	if err != nil {
		// handle error
	}
	if resp2.StatusCode == http.StatusOK {
		body, _ := ioutil.ReadAll(resp.Body)
	}
}

In the GoDoc of http.Response this rule is clearly described.

It is the caller's responsibility to close Body. The default HTTP client's Transport may not reuse HTTP/1.x "keep-alive" TCP connections if the Body is not read to completion and closed.

About

Analyzer: checks whether HTTP response body is closed and a re-use of TCP connection is not blocked.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 100.0%