forked from timakin/bodyclose
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
788 additions
and
782 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,37 @@ | ||
linters-settings: | ||
govet: | ||
check-shadowing: true | ||
golint: | ||
min-confidence: 0 | ||
maligned: | ||
suggest-new: true | ||
dupl: | ||
threshold: 100 | ||
goconst: | ||
min-len: 2 | ||
min-occurrences: 2 | ||
misspell: | ||
locale: US | ||
lll: | ||
line-length: 140 | ||
gocritic: | ||
enabled-tags: | ||
- performance | ||
- style | ||
- experimental | ||
disabled-checks: | ||
- wrapperFunc | ||
|
||
linters: | ||
enable-all: true | ||
disable: | ||
- maligned | ||
- prealloc | ||
- gochecknoglobals | ||
|
||
run: | ||
timeout: 5m | ||
go: '1.19' | ||
skip-dirs: | ||
- passes/bodyclose/testdata | ||
- enterprise | ||
- event-schema | ||
|
||
issues: | ||
exclude-rules: | ||
- text: "weak cryptographic primitive" | ||
linters: | ||
- gosec | ||
linters: | ||
enable: | ||
- deadcode | ||
- errcheck | ||
- gosimple | ||
- govet | ||
- ineffassign | ||
- staticcheck | ||
- structcheck | ||
- typecheck | ||
- unused | ||
- varcheck | ||
- bodyclose | ||
- decorder | ||
- makezero | ||
- nilnil | ||
- nilerr | ||
- rowserrcheck | ||
- tenv | ||
- wastedassign | ||
- unparam | ||
- misspell | ||
- unconvert | ||
|
||
service: | ||
golangci-lint-version: 1.15.x # use the fixed version to not introduce new linters unexpectedly | ||
issues: | ||
exclude-use-default: true | ||
exclude-case-sensitive: false | ||
max-issues-per-linter: 50 | ||
max-same-issues: 10 | ||
new: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,70 @@ | ||
# bodyclose | ||
# reuseconn | ||
|
||
[![CircleCI](https://circleci.com/gh/timakin/bodyclose.svg?style=svg)](https://circleci.com/gh/timakin/bodyclose) | ||
|
||
`bodyclose` is a static analysis tool which checks whether `res.Body` is correctly closed. | ||
`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 `bodyclose` by `go get` command. | ||
You can get `reuseconn` by `go get` command. | ||
|
||
```bash | ||
$ go get -u github.com/timakin/bodyclose | ||
$ go get -u github.com/atzoum/reuseconn | ||
``` | ||
|
||
## How to use | ||
|
||
`bodyclose` run with `go vet` as below when Go is 1.12 and higher. | ||
`reuseconn` run with `go vet` as below. | ||
|
||
```bash | ||
$ go vet -vettool=$(which bodyclose) github.com/timakin/go_api/... | ||
# github.com/timakin/go_api | ||
$ 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 | ||
``` | ||
|
||
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`. | ||
|
||
```bash | ||
$ bodyclose github.com/timakin/go_api/... | ||
~/go/src/github.com/timakin/api/internal/httpclient/httpclient.go:13:13: response body must be closed | ||
$ reuseconn github.com/atzoum/go_api/... | ||
~/go/src/github.com/atzoum/api/internal/httpclient/httpclient.go:13:13: response body must be closed | ||
``` | ||
|
||
## Analyzer | ||
|
||
`bodyclose` validates whether [*net/http.Response](https://golang.org/pkg/net/http/#Response) of HTTP request calls method `Body.Close()` such as below code. | ||
`reuseconn` validates whether a [*net/http.Response](https://golang.org/pkg/net/http/#Response) of HTTP request is properly disposed after used. E.g. | ||
|
||
```go | ||
resp, err := http.Get("http://example.com/") // Wrong case | ||
if err != nil { | ||
// handle error | ||
func main() { | ||
resp, err := http.Get("http://example.com/") // Wrong case | ||
if err != nil { | ||
// handle error | ||
} | ||
body, err := ioutil.ReadAll(resp.Body) | ||
} | ||
body, err := ioutil.ReadAll(resp.Body) | ||
``` | ||
|
||
This code is wrong. You must call resp.Body.Close when finished reading 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. | ||
|
||
```go | ||
resp, err := http.Get("http://example.com/") | ||
if err != nil { | ||
// handle error | ||
|
||
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 closeResponseBody(resp) // OK | ||
if err != nil { | ||
// handle error | ||
} | ||
if resp2.StatusCode == http.StatusOK { | ||
body, _ := ioutil.ReadAll(resp.Body) | ||
} | ||
} | ||
defer resp.Body.Close() // OK | ||
body, err := ioutil.ReadAll(resp.Body) | ||
``` | ||
|
||
In the [GoDoc of Client.Do](https://golang.org/pkg/net/http/#Client.Do) this rule is clearly described. | ||
In the [GoDoc of http.Response](https://pkg.go.dev/net/http#Response) 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. | ||
> 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
module github.com/timakin/bodyclose | ||
module github.com/atzoum/reuseconn | ||
|
||
go 1.12 | ||
go 1.18 | ||
|
||
require ( | ||
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 | ||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89 | ||
github.com/gostaticanalysis/analysisutil v0.7.1 | ||
golang.org/x/tools v0.3.0 | ||
) | ||
|
||
require ( | ||
github.com/gostaticanalysis/comment v1.4.2 // indirect | ||
golang.org/x/mod v0.7.0 // indirect | ||
golang.org/x/sys v0.2.0 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,54 @@ | ||
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 h1:JVnpOZS+qxli+rgVl98ILOXVNbW+kb5wcxeGx8ShUIw= | ||
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= | ||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= | ||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= | ||
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= | ||
github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= | ||
github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= | ||
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4 h1:d2/eIbH9XjD1fFwD5SHv8x168fjbQ9PB8hvs8DSEC08= | ||
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= | ||
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= | ||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= | ||
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= | ||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= | ||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= | ||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= | ||
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= | ||
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= | ||
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= | ||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= | ||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= | ||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= | ||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= | ||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89 h1:iWXXYN3edZ3Nd/7I6Rt1sXrWVmhF9bgVtlEJ7BbH124= | ||
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= | ||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= | ||
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= | ||
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= | ||
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
// +build !go1.12 | ||
|
||
package main | ||
|
||
import ( | ||
"github.com/timakin/bodyclose/passes/bodyclose" | ||
"github.com/atzoum/reuseconn/reuseconn" | ||
"golang.org/x/tools/go/analysis/singlechecker" | ||
) | ||
|
||
func main() { singlechecker.Main(bodyclose.Analyzer) } | ||
func main() { singlechecker.Main(reuseconn.Analyzer) } |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.