http 包提供了 HTTP 客户端和服务端的实现.它提供了 HTTP 通信过程中各种对象的定义及实现.导入方式为 import "net/http"
对于客户端,它可以使用 Get,Head,Post和PostForm 等方法直接发送对应的 HTTP 请求,也可以通过 Client 类型自定义客户端,从而调用其中方法发送 HTTP 请求.
1 2 3 4 5 6
   |  resp, err := http.Get("http://example.com/") resp, err := http.PostForm("http://example.com/form",     url.Values{"key": {"Value"}, "id": {"123"}})
  defer resp.Body.Close()
 
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12
   |  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)
 
 
  | 
 
对于传输过程,它提供了支持代理,TLS 配置,keep-alive,压缩等传输方式的 Transport 类型
1 2 3 4 5 6 7 8
   |  tr := &http.Transport{     MaxIdleConns:       10,     IdleConnTimeout:    30 * time.Second,     DisableCompression: true, } client := &http.Client{Transport: tr} resp, err := client.Get("https://example.com")
 
  | 
 
对于服务端,它提供了 ListenAndServe 函数使用给定的地址和处理程序启动 HTTP 服务器,还提供了 Server 类型用于自定义服务端及处理请求的函数
1 2 3 4 5
   | 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))
  | 
 
1 2 3 4 5 6 7 8
   | s := &http.Server{     Addr:           ":8080",     Handler:        myHandler,     ReadTimeout:    10 * time.Second,     WriteTimeout:   10 * time.Second,     MaxHeaderBytes: 1 << 20, } log.Fatal(s.ListenAndServe())
  | 
 
http 包的 Transport 和 Server 类型对于简单的配置都自动支持 HTTP/2 协议.要使用更为复杂的 HTTP/2 协议,请直接导入 golang.org/x/net/http2,并使用其 ConfigureTransport 或 ConfigureServer 类型的相关函数.
常用类型定义
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
   |  type Client struct {          Transport RoundTripper               CheckRedirect func(req *Request, via []*Request) error     Jar CookieJar       Timeout time.Duration   }
 
  type Handler interface {     ServeHTTP(ResponseWriter, *Request) }
 
  type HandlerFunc func(ResponseWriter, *Request)
 
  type Header map[string][]string
 
  type Request struct {     Method string       URL *url.URL       Proto      string      Header Header       Body io.ReadCloser       GetBody func() (io.ReadCloser, error) // 获取请求体的方法     ContentLength int64       TransferEncoding []string     Close bool       Host string  
           Form url.Values       PostForm url.Values      MultipartForm *multipart.Form 
      RemoteAddr string       RequestURI string       TLS *tls.ConnectionState       Response *Response       }
  type Response struct {     Status     string      StatusCode int         Proto      string      Header Header       Body io.ReadCloser       ContentLength int64       Uncompressed bool      Request *Request       TLS *tls.ConnectionState  }
  type Server struct {     Addr string       Handler Handler      TLSConfig *tls.Config       ReadTimeout time.Duration       ReadHeaderTimeout time.Duration      WriteTimeout time.Duration       IdleTimeout time.Duration      MaxHeaderBytes int      ConnState func(net.Conn, ConnState) // 客户端连接状态更改时的回调函数     ErrorLog *log.Logger       }
 
  | 
 
常用常量及变量
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
   |  const (     StatusOK                   = 200      StatusNoContent            = 204 
      StatusMovedPermanently = 301      StatusFound            = 302      StatusTemporaryRedirect = 307      StatusPermanentRedirect = 308 
      StatusBadRequest                   = 400      StatusUnauthorized                 = 401      StatusPaymentRequired              = 402      StatusForbidden                    = 403      StatusNotFound                     = 404      StatusMethodNotAllowed             = 405      StatusRequestTimeout               = 408      StatusRequestEntityTooLarge        = 413      StatusRequestURITooLong            = 414      StatusUnsupportedMediaType         = 415      StatusTooManyRequests              = 429 
      StatusInternalServerError           = 500      StatusNotImplemented                = 501      StatusBadGateway                    = 502      StatusServiceUnavailable            = 503      StatusGatewayTimeout                = 504  )
  var DefaultTransport RoundTripper = &Transport{     Proxy: ProxyFromEnvironment,     DialContext: (&net.Dialer{         Timeout:   30 * time.Second,         KeepAlive: 30 * time.Second,         DualStack: true,     }).DialContext,     ForceAttemptHTTP2:     true,     MaxIdleConns:          100,     IdleConnTimeout:       90 * time.Second,     TLSHandshakeTimeout:   10 * time.Second,     ExpectContinueTimeout: 1 * time.Second, }
  var DefaultServeMux = &defaultServeMux
 
  | 
 
常用函数
http 包函数
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
   |  func Handle(pattern string, handler Handler) func HandleFunc(pattern string, handler func(ResponseWriter, *Request))
 
  func ListenAndServe(addr string, handler Handler) error func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error
 
  func Serve(l net.Listener, handler Handler) error func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error
 
  func NewRequest(method, url string, body io.Reader) (*Request, error) func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error)
 
  func NewServeMux() *ServeMux
 
 
  func FileServer(root FileSystem) Handler
  func NotFoundHandler() Handler
  func RedirectHandler(url string, code int) Handler
  func StripPrefix(prefix string, h Handler) Handler
  func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler
 
  func NotFound(w ResponseWriter, r *Request)
  func ServeFile(w ResponseWriter, r *Request, name string)
  func SetCookie(w ResponseWriter, cookie *Cookie)
 
  | 
 
Client 结构体方法
1 2 3 4 5 6 7 8 9 10 11
   |  func (c *Client) CloseIdleConnections()
  func (c *Client) Do(req *Request) (*Response, error)
  func (c *Client) Get(url string) (resp *Response, err error) func (c *Client) Head(url string) (resp *Response, err error) func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error)
 
  func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)
 
  | 
 
1 2 3 4 5 6 7 8
   | func (h Header) Add(key, value string) func (h Header) Clone() Header func (h Header) Del(key string) func (h Header) Get(key string) string func (h Header) Set(key, value string) func (h Header) Values(key string) []string func (h Header) Write(w io.Writer) error func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error
   | 
 
Request 结构体方法
1 2 3 4 5 6 7 8 9 10 11 12 13
   | func (r *Request) AddCookie(c *Cookie)  // 添加 cookie func (r *Request) BasicAuth() (username, password string, ok bool) // 返回请求基本认证中的用户名密码 func (r *Request) Cookie(name string) (*Cookie, error) // 返回指定名称的 Cookie func (r *Request) Cookies() []*Cookie  // 返回所有 cookie
  func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) func (r *Request) FormValue(key string) string // 返回表单中 key 的值 func (r *Request) ParseForm() error  // 解析表单 func (r *Request) ParseMultipartForm(maxMemory int64) error // 解析带有文件的表单 func (r *Request) Referer() string  // 返回引用 URL func (r *Request) SetBasicAuth(username, password string)  // 设置基本认证请求的用户名密码 func (r *Request) UserAgent() string // 返回请求的客户端代理 func (r *Request) Write(w io.Writer) error // 将请求写入文件
   | 
 
Response 结构体方法
1 2
   | func (r *Response) Cookies() []*Cookie  // 响应的 cookie func (r *Response) Location() (*url.URL, error) // 返回响应的`Location` 响应头
   | 
 
ServeMux 结构体方法
1 2 3 4 5
   |  func (mux *ServeMux) Handle(pattern string, handler Handler) func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
  func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)
 
  | 
 
Server 结构体方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   |  func (srv *Server) Close() error   func (srv *Server) ListenAndServe() error func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error
  func (srv *Server) RegisterOnShutdown(f func())
  func (srv *Server) Serve(l net.Listener) error func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error
  func (srv *Server) SetKeepAlivesEnabled(v bool)
  func (srv *Server) Shutdown(ctx context.Context) error
 
  | 
 
示例
文件服务器
1 2 3 4 5 6 7 8 9
   | import "net/http"
  func main() {          
           http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))) }
   | 
 
调用 PostForm 发送请求及数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | import (     "fmt"     "net/http"     "net/url" )
  func main() {     data := url.Values{         "name": []string{"name"},         "age":  []string{"20"},         "addr": []string{"beijing", "shanghai", "guangzhou"},     }     res, _ := http.PostForm("http://www.httpbin.org/post", data)     defer res.Body.Close()     buf := make([]byte, 1024)     n, _ := res.Body.Read(buf)     fmt.Println(string(buf[:n]))
   | 
 
Handle 与 HandleFunc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | import (     "io"     "net/http" )
  func main() {     h1 := func(w http.ResponseWriter, _ *http.Request) {         io.WriteString(w, "Hello from a HandleFunc #1!\n")     h2 := func(w http.ResponseWriter, _ *http.Request) {         io.WriteString(w, "Hello from a HandleFunc #2!\n")     }     http.HandleFunc("/h1", h1)     http.HandleFunc("/h2", h2)     http.Handle("/notfount", http.NotFoundHandler())     http.ListenAndServe(":8080", nil) }
   | 
 
自定义Handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | import (     "fmt"     "net/http"     "net/url"     "time" )
  type CustomHandler struct {     name string }
  func (c CustomHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {     time.Sleep(time.Second)     fmt.Fprintf(w, "respose: %v", c.name)      http.ServeFile(w, req, c.name)   }
  func main() {     handler := CustomHandler{"index.html"}     http.ListenAndServe(":80", http.TimeoutHandler(handler, time.Nanosecond, "请求超时")) }
   |