Client结构体
type Client struct {
Transport RoundTripper
CheckRedirect func(req *Request, via []*Request) error
Jar CookieJar
Timeout time.Duration
}
四个字段分别是:
- Transport:表示 HTTP 事务,用于处理客户端的请求连接并等待服务端的响应;
- CheckRedirect:处理重定向的策略
- Jar:管理和存储请求中的 cookie
- Timeout:超时设置
Request结构体
type Request struct {
Method string
URL *url.URL
Header Header
Body io.ReadCloser
Host string
Response *Response
...
}
准备发送请求
构造好的Request结构req,会传入c.Do()方法。
我们看下发送请求过程调用了哪些方法,用下图表示下
func (c *Client) do(req *Request) (retres *Response, reterr error) {
...
for {
...
resp, didTimeout, err = send(req, deadline)
if err != nil {
return nil, didTimeout, err
}
}
...
}
//Client 调用 Do 方法处理发送请求最后会调用到 send 函数中
func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
resp, didTimeout, err = send(req, c.transport(), deadline)
if err != nil {
return nil, didTimeout, err
}
...
return resp, nil, nil
}
c.transport()方法是为了回去Transport的默认实例 DefaultTransport ,我们看下DefaultTransport长什么样。
var DefaultTransport RoundTripper = &Transport{
Proxy: ProxyFromEnvironment,
DialContext: defaultTransportDialContext(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}),
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
可以根据需要建立网络连接,并缓存它们以供后续调用重用,部分参数如下:
- MaxIdleConns:最大空闲连接数
- IdleConnTimeout:空闲连接超时时间
- ExpectContinueTimeout:预计继续超时
注意这里的RoundTripper是个接口,也就是说 Transport 实现 RoundTripper 接口,该接口方法接Request返回Response。
type RoundTripper interface {
RoundTrip(*Request) (*Response, error)
}