2
2
3
3
![ ] ( https://github.com/sonatard/noctx/workflows/CI/badge.svg )
4
4
5
- ` noctx ` finds sending http request without context.Context.
5
+ ` noctx ` finds function calls without context.Context.
6
6
7
- You should use ` noctx ` if sending http request in your library .
8
- Passing ` context.Context ` enables library user to cancel http request, getting trace information and so on.
7
+ If you are using net/ http package, you should use noctx .
8
+ Passing ` context.Context ` enables library user to cancel request, getting trace information and so on.
9
9
10
10
## Usage
11
11
12
-
13
12
### noctx with go vet
14
13
15
14
go vet is a Go standard tool for analyzing source code.
@@ -19,7 +18,7 @@ go vet is a Go standard tool for analyzing source code.
19
18
$ go install github.com/sonatard/noctx/cmd/noctx@latest
20
19
```
21
20
22
- 2 . noctx execute
21
+ 2 . Execute noctx
23
22
``` sh
24
23
$ go vet -vettool=` which noctx` main.go
25
24
./main.go:6:11: net/http.Get must not be called
@@ -46,40 +45,28 @@ linters:
46
45
- xxx # Add unused linter to disable linters.
47
46
```
48
47
49
- 3 . noctx execute
48
+ 3 . Execute noctx
50
49
``` sh
51
50
# Use .golangci.yml
52
51
$ golangci-lint run
53
52
54
- # Only noctx execute
53
+ # Only execute noctx
55
54
golangci-lint run --enable-only noctx
56
55
```
57
56
58
- ## Detection rules
57
+ ## net/http package
58
+ ### Detection rules
59
59
60
- - Executing following functions
61
- - ` net/http.Get `
62
- - ` net/http.Head `
63
- - ` net/http.Post `
64
- - ` net/http.PostForm `
65
- - ` (*net/http.Client).Get `
66
- - ` (*net/http.Client).Head `
67
- - ` (*net/http.Client).Post `
68
- - ` (*net/http.Client).PostForm `
69
- - ` http.Request ` returned by ` http.NewRequest ` function and passes it to other function.
60
+ - Executing the following functions
61
+ https://github.com/sonatard/noctx/blob/9a514098df3f8a88e0fd6949320c4e0aa51b520c/ngfunc/main.go#L15-L26
70
62
71
- ## How to fix
63
+ ### How to fix
72
64
65
+ - use ` http.NewRequestWithContext ` function instead of using ` http.NewRequest ` function.
73
66
- Send http request using ` (*http.Client).Do(*http.Request) ` method.
74
- - In Go 1.13 and later, use ` http.NewRequestWithContext ` function instead of using ` http.NewRequest ` function.
75
- - In Go 1.12 and earlier, call ` (http.Request).WithContext(ctx) ` after ` http.NewRequest ` .
76
-
77
- ` (http.Request).WithContext(ctx) ` has a disadvantage of performance because it returns a copy of ` http.Request ` . Use ` http.NewRequestWithContext ` function if you only support Go1.13 or later.
78
-
79
67
80
68
If your library already provides functions that don't accept context, you define a new function that accepts context and make the existing function a wrapper for a new function.
81
69
82
-
83
70
``` go
84
71
// Before fix code
85
72
// Sending an HTTP request but not accepting context
@@ -106,7 +93,7 @@ func Send(body io.Reader) error {
106
93
107
94
// Sending an HTTP request and accepting context
108
95
func SendWithContext (ctx context .Context , body io .Reader ) error {
109
- // Change NewRequest to NewRequestWithContext and pass context it
96
+ // Change NewRequest to NewRequestWithContext and pass context to it
110
97
req , err := http.NewRequestWithContext (ctx, http.MethodPost , " http://example.com" , body)
111
98
if err != nil {
112
99
return err
@@ -120,56 +107,12 @@ func SendWithContext(ctx context.Context, body io.Reader) error {
120
107
}
121
108
```
122
109
123
- ## Detection sample
110
+ ### Detection sample
124
111
125
- ``` go
126
- package main
127
-
128
- import (
129
- " context"
130
- " net/http"
131
- )
132
-
133
- func main () {
134
- const url = " http://example.com"
135
- http.Get (url) // want `net/http\.Get must not be called`
136
- http.Head (url) // want `net/http\.Head must not be called`
137
- http.Post (url, " " , nil ) // want `net/http\.Post must not be called`
138
- http.PostForm (url, nil ) // want `net/http\.PostForm must not be called`
139
-
140
- cli := &http.Client {}
141
- cli.Get (url) // want `\(\*net/http\.Client\)\.Get must not be called`
142
- cli.Head (url) // want `\(\*net/http\.Client\)\.Head must not be called`
143
- cli.Post (url, " " , nil ) // want `\(\*net/http\.Client\)\.Post must not be called`
144
- cli.PostForm (url, nil ) // want `\(\*net/http\.Client\)\.PostForm must not be called`
145
-
146
- req , _ := http.NewRequest (http.MethodPost , url, nil ) // want `should rewrite http.NewRequestWithContext`
147
- cli.Do (req)
148
-
149
- ctx := context.Background ()
150
- req2 , _ := http.NewRequestWithContext (ctx, http.MethodPost , url, nil ) // OK
151
- cli.Do (req2)
152
-
153
- req3 , _ := http.NewRequest (http.MethodPost , url, nil ) // OK
154
- req3 = req3.WithContext (ctx)
155
- cli.Do (req3)
156
-
157
- f2 := func (req *http.Request , ctx context.Context ) *http.Request {
158
- return req
159
- }
160
- req4 , _ := http.NewRequest (http.MethodPost , url, nil ) // want `should rewrite http.NewRequestWithContext`
161
- req4 = f2 (req4, ctx)
162
- cli.Do (req4)
163
-
164
- req5 , _ := func () (*http.Request , error ) {
165
- return http.NewRequest (http.MethodPost , url, nil ) // want `should rewrite http.NewRequestWithContext`
166
- }()
167
- cli.Do (req5)
168
-
169
- }
170
- ```
112
+ https://github.com/sonatard/noctx/blob/9a514098df3f8a88e0fd6949320c4e0aa51b520c/testdata/src/http_client/http_client.go#L11
113
+ https://github.com/sonatard/noctx/blob/9a514098df3f8a88e0fd6949320c4e0aa51b520c/testdata/src/http_request/http_request.go#L17
171
114
172
- ## Reference
115
+ ### Reference
173
116
174
117
- [ net/http - NewRequest] ( https://pkg.go.dev/net/http#NewRequest )
175
118
- [ net/http - NewRequestWithContext] ( https://pkg.go.dev/net/http#NewRequestWithContext )
0 commit comments