超文本传输协议(Hypertext Transfer Protocol、HTTP 协议)是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等.是今天使用最广泛的应用层协议,相信大家并不陌生.
Go 语言标准库通过 net/http
包提供 HTTP
的客户端和服务端实现.
Go 语言的 net/http
中同时包好了 HTTP
客户端和服务端的实现,为了支持更好的扩展性,它引入了 net/http.RoundTripper
和 net/http.Handler
两个接口。net/http.RoundTripper
是用来表示执行 HTTP
请求的接口,调用方将请求作为参数可以获取请求对应的响应,而 net/http.Handler
主要用于 HTTP
服务器响应客户端的请求
HTTP
请求的接收方可以实现 net/http.Handler
接口,其中实现了处理 HTTP
请求的逻辑,处理的过程中会调用 net/http.ResponseWriter
接口的方法构造 HTTP
响应,它提供的三个接口 Header
、Write
和 WriteHeader
分别会获取 HTTP
响应、将数据写入负载以及写入响应头
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type ResponseWriter interface {
Header() Header
Write([]byte) (int, error)
WriteHeader(statusCode int)
}
复制代码
客户端可以直接通过 net/http.Get
使用默认的客户端 net/http.DefaultClient
发起 HTTP
请求,也可以自己构建新的 net/http.Client
实现自定义的 HTTP
事务,在多数情况下使用默认的客户端都能满足我们的需求,不过需要注意的是使用默认客户端发出的请求没有超时时间,所以在某些场景下会一直等待下去。除了自定义 HTTP
事务之外,我们还可以实现自定义的 net/http.CookieJar
接口管理和使用 HTTP
请求中的 Cookie
持久的 TCP
连接会实现 net/http.persistConn.roundTrip
处理写入 HTTP
请求并在 select
语句中等待响应的返回
func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
writeErrCh := make(chan error, 1)
pc.writech <- writeRequest{req, writeErrCh, continueCh}
resc := make(chan responseAndError)
pc.reqch <- requestAndChan{
req: req.Request,
ch: resc,
}
for {
select {
case re := <-resc:
if re.err != nil {
return nil, pc.mapRoundTripError(req, startBytesWritten, re.err)
}
return re.res, nil
...
}
}
}
复制代码
标准库提供的 net/http.ListenAndServe
可以用来监听 TCP
连接并处理请求,该函数会使用传入的监听地址和处理器初始化一个 HTTP
服务器 net/http.Server
,调用该服务器的 net/http.Server.ListenAndServe
方法:
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}
复制代码