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, "请求超时")) }
|