客户端的内容将是如何发送请求和接收响应,走完客户端就把整个流程就完整的串联起来了!
这次我把调用的核心方法和流程走读的函数也贴出来,这样看应该更有逻辑感,重要部分用红色标记了一下,可以着重看下。
图片
先了解下核心数据结构Client和Request。
type Client struct { Transport RoundTripper CheckRedirect func(req *Request, via []*Request) error Jar CookieJar Timeout time.Duration}
四个字段分别是:
Request字段较多,这里就列举一下常见的一些字段
type Request struct { Method string URL *url.URL Header Header Body io.ReadCloser Host string Response *Response ...}
var DefaultClient = &Client{}func Get(url string) (resp *Response, err error) { return DefaultClient.Get(url)}
示例HTTP 的 Get方法会调用到 DefaultClient 的 Get 方法,,然后调用到 Client 的 Get 方法。
DefaultClient 是 Client 的一个空实例(跟DefaultServeMux有点子相似)
图片
Client.Get
func (c *Client) Get(url string) (resp *Response, err error) { req, err := NewRequest("GET", url, nil) if err != nil { return nil, err } return c.Do(req)}func NewRequest(method, url string, body io.Reader) (*Request, error) { return NewRequestWithContext(context.Background(), method, url, body)}
Client.Get() 根据用户的入参,请求参数 NewRequest使用上下文包装NewRequestWithContext ,接着通过 Client.Do 方法,处理这个请求。
NewRequestWithContext
func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) { ... // 解析url u, err := urlpkg.Parse(url) ... rc, ok := body.(io.ReadCloser) if !ok && body != nil { rc = ioutil.NopCloser(body) } u.Host = removeEmptyPort(u.Host) req := &Request{ ctx: ctx, Method: method, URL: u, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Header: make(Header), Body: rc, Host: u.Host, } ... return req, nil}
NewRequestWithContext 函数主要是功能是将请求封装成一个 Request 结构体并返回,这个结构体的名称是req。
构造好的Request结构req,会传入c.Do()方法。
我们看下发送请求过程调用了哪些方法,用下图表示下
图片
本文链接:http://www.28at.com/showinfo-26-73789-0.html图文讲透Golang标准库 net/http实现原理 - 客户端
声明:本网页内容旨在传播知识,不代表本站观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。