net/http包在编写golang web应用中有很重要的作用,它主要提供了基于HTTP协议进行工作的client实现和server实现,可用于编写HTTP服务端和客户端。
其使用方法也跟其他面向对象语言很相似,我们可以先从它的一些基础用法来感受一下:
以下是示例客户端代码:
// 用http包中默认的Client进行请求(因为没有指定Client)
resp, err := http.Get("http://example.com/")
...
resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://example.com/form",
url.Values{
"key": {
"Value"}, "id": {
"123"}})
// 用自定义的Client进行请求
client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...
客户端主要是利用了http.Client对象来进行各种请求的发送。上面两个用法中,第一个相对直接,它可以直接用Get函数或Post函数来发出请求,而第二个用法则是分步来完成请求过程:
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
先是用http.NewRequest方法指定了请求方法以及请求url构造请求对象req,并进一步对req的Header进行设置,最后再通过Client.Do方法将请求发出去。
再来看看以下服务端示例代码:
// 这里没有指定server,所以是用http包中默认的server来处理客户端请求
http.Handle("/foo", fooHandler)
http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})
log.Fatal(http.ListenAndServe(":8080", nil))
// 自定义server
s := &http.Server{
Addr: ":8080",
Handler: myHandler,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
log.Fatal(s.ListenAndServe())
服务端代码主要是用http.Server对象来进行请求的处理,第一种用法中并没有构造Server对象,而是使用http提供的缺省Server对象,通过http.Handle指定了匹配"/foo"的请求的Handler,通过HandleFunc方法来指定匹配“/bar”的请求的处理函数。最后通过http.ListenAndServe方法启动缺省的Server对象,并在8080端口监听客户端请求。而第二种方法通过创建Server对象对一些属性进行了指定。
Server对象的实现
我们以net/http/server.go为例来分析Server对象。Server的对象的定义如下:
// A Server defines parameters for running an HTTP server.
// The zero value for Server is a valid configuration.
type Server struct {
Addr string // TCP address to listen on, ":http" if empty
Handler Handler // handler to invoke, http.DefaultServeMux if nil
// TLSConfig optionally provides a TLS configuration for use
// by ServeTLS and ListenAndServeTLS. Note that this value is
// cloned by ServeTLS and ListenAndServeTLS, so it's not
// possible to modify the configuration with methods like
// tls.Config.SetSessionTicketKeys. To use
// SetSessionTicketKeys, use Server.Serve with a TLS Listener
// instead.
TLSConfig *tls.Config
// ReadTimeout is the maximum duration for reading the entire
// request, including the body.
//
// Because ReadTimeout does not let Handlers make per-request
// decisions on each request body's acceptable deadline or
// upload rate, most users will prefer to use
// ReadHeaderTimeout. It is valid to use them both.
ReadTimeout time.Duration
// ReadHeaderTimeout is the amount of time allowed to read
// request headers. The connection's read deadline is reset
// after reading the headers and the Handler can decide what
// is considered too slow for the body.
ReadHeaderTimeout time.Duration
// WriteTimeout is the maximum duration before timing out
// writes of the response. It is reset whenever a new
// request's header is read. Like ReadTimeout, it does not
// let Handlers make decisions on a per-request basis.
WriteTimeout time.Duration
// IdleTimeout is the maximum amount of time to wait for the
// next request when keep-alives are enabled. If IdleTimeout
// is zero, the value of ReadTimeout is used. If both are
// zero, ReadHeaderTimeout is used.
IdleTimeout time.Duration