database/sql 包提供了保证SQL或类SQL数据库的泛用接口,常用的数据库驱动有 github.com/go-sql-driver/mysql
https://pkg.go.dev/database/sql
过滤请求方法
我们可以使用 http.Transport
的RoundTrip方法来定制HTTP请求。通过定义一个实现了http.RoundTripper接口的结构体,并在其中重写RoundTrip方法,我们可以对请求进行过滤和修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| type FilterTransport struct { Transport http.RoundTripper } func (t *FilterTransport) RoundTrip(req *http.Request) (*http.Response, error) { if req.Method == http.MethodGet { return nil, errors.New("Method Not Allowed") } return t.Transport.RoundTrip(req) } func main() { transport := &FilterTransport{ Transport: http.DefaultTransport, } client := &http.Client{ Transport: transport, } req, _ := http.NewRequest(http.MethodGet, "http://example.com", nil) resp, err := client.Do(req) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Response:", resp.Status) } }
|
过滤请求头
除了过滤请求方法,我们还可以对请求头进行过滤和修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| type HeaderFilterTransport struct { Transport http.RoundTripper } func (t *HeaderFilterTransport) RoundTrip(req *http.Request) (*http.Response, error) { req.Header.Del("User-Agent") req.Header.Set("User-Agent", "Custom User-Agent") return t.Transport.RoundTrip(req) } func main() { transport := &HeaderFilterTransport{ Transport: http.DefaultTransport, } client := &http.Client{ Transport: transport, } req, _ := http.NewRequest(http.MethodGet, "http://example.com", nil) resp, err := client.Do(req) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Response:", resp.Status) } }
|
请求拦截
除了过滤请求,我们还可以拦截请求,修改请求体或者对请求进行进一步处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| type BodyInterceptorTransport struct { Transport http.RoundTripper } func (t *BodyInterceptorTransport) RoundTrip(req *http.Request) (*http.Response, error) { if req.Method == http.MethodPost { body, err := ioutil.ReadAll(req.Body) if err != nil { return nil, err } req.Body.Close() newBody := bytes.NewReader([]byte("Modified Body")) req.Body = ioutil.NopCloser(newBody) req.Header.Set("Content-Type", "text/plain") } return t.Transport.RoundTrip(req) } func main() { transport := &BodyInterceptorTransport{ Transport: http.DefaultTransport, } client := &http.Client{ Transport: transport, } req, _ := http.NewRequest(http.MethodPost, "http://example.com", strings.NewReader("Original Body")) resp, err := client.Do(req) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("Response:", resp.Status) } }
|