version: 1.10

package http

import "net/http"

概述

http 包提供 HTTP 客户端和服务器的实现。

使用 Get、Head、Post 和 PostForm 发起 HTTP(或 HTTPS)请求:

  1. resp, err := http.Get("http://example.com/")
  2. ...
  3. resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
  4. ...
  5. resp, err := http.PostForm("http://example.com/form",
  6. url.Values{"key": {"Value"}, "id": {"123"}})

客户端必须在使用后手动关闭响应的 body:

  1. resp, err := http.Get("http://example.com/")
  2. if err != nil {
  3. // handle error
  4. }
  5. defer resp.Body.Close()
  6. body, err := ioutil.ReadAll(resp.Body)
  7. // ...

手动创建 Client 可以自定义 HTTP 请求头,重定向策略和其他设置:

  1. client := &http.Client{
  2. CheckRedirect: redirectPolicyFunc,
  3. }
  4. resp, err := client.Get("http://example.com")
  5. // ...
  6. req, err := http.NewRequest("GET", "http://example.com", nil)
  7. // ...
  8. req.Header.Add("If-None-Match", `W/"wyzzy"`)
  9. resp, err := client.Do(req)
  10. // ...

手动创建 Transport 可以自定义代理、TLS 、keep-alive、压缩和其他配置:

  1. tr := &http.Transport{
  2. MaxIdleConns: 10,
  3. IdleConnTimeout: 30 * time.Second,
  4. DisableCompression: true,
  5. }
  6. client := &http.Client{Transport: tr}
  7. resp, err := client.Get("https://example.com")

Client 和 Transport 都可以安全的被多个 goroutine 同时使用,所以我们应该只创建一个实例并多次复用。

ListenAndServe 启动指定地址和处理函数的 HTTP 服务器。处理函数通常为 nil(这时默认使用 DefaultServeMux)。Handle 和 HandleFunc 为 DefaultServeMux 添加处理函数:

  1. http.Handle("/foo", fooHandler)
  2. http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
  3. fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
  4. })
  5. log.Fatal(http.ListenAndServe(":8080", nil))

通过创建自定义 Server 可以更好的控制服务器的行为:

  1. s := &http.Server{
  2. Addr: ":8080",
  3. Handler: myHandler,
  4. ReadTimeout: 10 * time.Second,
  5. WriteTimeout: 10 * time.Second,
  6. MaxHeaderBytes: 1 << 20,
  7. }
  8. log.Fatal(s.ListenAndServe())

从 Go 1.6 开始 http 包在使用 HTTPS 时支持 HTTP/2 协议。如果程序需要禁用 HTTPS 可以设置 Transport.TLSNextProto(客户端)或 Server.TLSNextProto(服务端)为一个空 map(非 nil)。或者使用目前支持的以下 GODEBUG 环境变量:

  1. GODEBUG=http2client=0 # 禁用 HTTP/2 客户端支持
  2. GODEBUG=http2server=0 # 禁用 HTTP/2 服务端支持
  3. GODEBUG=http2debug=1 # 开启 HTTP/2 调试日志
  4. GODEBUG=http2debug=2 # 更多参数

不是所有的 Go API 都兼容 GODEBUG 环境变量。如果在使用前有任何问题请在 https://golang.org/s/http2bug 提出。

http 包的 Transport 和 Server 都可以通过简单配置自动支持 HTTP/2。如果需要配置更复杂的 HTTP/2 属性、使用 HTTP/2 的底层功能或想用 Go 的 http2 较新版本的包可以直接使用 “golang.org/x/net/http2” 包中的 ConfigureTransport 和 ConfigureServer。通过 golang.org/x/net/http2 进行手动配置会覆盖 net/http 包的内建 HTTP/2 支持。

索引

例子

文件

client.go cookie.go doc.go filetransport.go fs.go h2_bundle.go header.go http.go jar.go method.go request.go response.go server.go sniff.go status.go transfer.go transport.go

Constants

  1. const (
  2. MethodGet = "GET"
  3. MethodHead = "HEAD"
  4. MethodPost = "POST"
  5. MethodPut = "PUT"
  6. MethodPatch = "PATCH" // RFC 5789
  7. MethodDelete = "DELETE"
  8. MethodConnect = "CONNECT"
  9. MethodOptions = "OPTIONS"
  10. MethodTrace = "TRACE"
  11. )

常见的 HTTP 方法。

除非有特别声明否则所有方法都定义在 RFC 7231 第 4.3 章。

  1. const (
  2. StatusContinue = 100 // RFC 7231, 6.2.1
  3. StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2
  4. StatusProcessing = 102 // RFC 2518, 10.1
  5.  
  6. StatusOK = 200 // RFC 7231, 6.3.1
  7. StatusCreated = 201 // RFC 7231, 6.3.2
  8. StatusAccepted = 202 // RFC 7231, 6.3.3
  9. StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4
  10. StatusNoContent = 204 // RFC 7231, 6.3.5
  11. StatusResetContent = 205 // RFC 7231, 6.3.6
  12. StatusPartialContent = 206 // RFC 7233, 4.1
  13. StatusMultiStatus = 207 // RFC 4918, 11.1
  14. StatusAlreadyReported = 208 // RFC 5842, 7.1
  15. StatusIMUsed = 226 // RFC 3229, 10.4.1
  16.  
  17. StatusMultipleChoices = 300 // RFC 7231, 6.4.1
  18. StatusMovedPermanently = 301 // RFC 7231, 6.4.2
  19. StatusFound = 302 // RFC 7231, 6.4.3
  20. StatusSeeOther = 303 // RFC 7231, 6.4.4
  21. StatusNotModified = 304 // RFC 7232, 4.1
  22. StatusUseProxy = 305 // RFC 7231, 6.4.5
  23.  
  24. StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7
  25. StatusPermanentRedirect = 308 // RFC 7538, 3
  26.  
  27. StatusBadRequest = 400 // RFC 7231, 6.5.1
  28. StatusUnauthorized = 401 // RFC 7235, 3.1
  29. StatusPaymentRequired = 402 // RFC 7231, 6.5.2
  30. StatusForbidden = 403 // RFC 7231, 6.5.3
  31. StatusNotFound = 404 // RFC 7231, 6.5.4
  32. StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5
  33. StatusNotAcceptable = 406 // RFC 7231, 6.5.6
  34. StatusProxyAuthRequired = 407 // RFC 7235, 3.2
  35. StatusRequestTimeout = 408 // RFC 7231, 6.5.7
  36. StatusConflict = 409 // RFC 7231, 6.5.8
  37. StatusGone = 410 // RFC 7231, 6.5.9
  38. StatusLengthRequired = 411 // RFC 7231, 6.5.10
  39. StatusPreconditionFailed = 412 // RFC 7232, 4.2
  40. StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11
  41. StatusRequestURITooLong = 414 // RFC 7231, 6.5.12
  42. StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13
  43. StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4
  44. StatusExpectationFailed = 417 // RFC 7231, 6.5.14
  45. StatusTeapot = 418 // RFC 7168, 2.3.3
  46. StatusUnprocessableEntity = 422 // RFC 4918, 11.2
  47. StatusLocked = 423 // RFC 4918, 11.3
  48. StatusFailedDependency = 424 // RFC 4918, 11.4
  49. StatusUpgradeRequired = 426 // RFC 7231, 6.5.15
  50. StatusPreconditionRequired = 428 // RFC 6585, 3
  51. StatusTooManyRequests = 429 // RFC 6585, 4
  52. StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5
  53. StatusUnavailableForLegalReasons = 451 // RFC 7725, 3
  54.  
  55. StatusInternalServerError = 500 // RFC 7231, 6.6.1
  56. StatusNotImplemented = 501 // RFC 7231, 6.6.2
  57. StatusBadGateway = 502 // RFC 7231, 6.6.3
  58. StatusServiceUnavailable = 503 // RFC 7231, 6.6.4
  59. StatusGatewayTimeout = 504 // RFC 7231, 6.6.5
  60. StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6
  61. StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1
  62. StatusInsufficientStorage = 507 // RFC 4918, 11.5
  63. StatusLoopDetected = 508 // RFC 5842, 7.2
  64. StatusNotExtended = 510 // RFC 2774, 7
  65. StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
  66. )

HTTP 状态码依据 IANA 注册。请看:http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

  1. const DefaultMaxHeaderBytes = 1 << 20 // 1 MB

DefaultMaxHeaderBytes 代表 HTTP 请求头允许的最大字节数。该属性可以用 Server.MaxHeaderBytes 覆盖。

  1. const DefaultMaxIdleConnsPerHost = 2

DefaultMaxIdleConnsPerHost 是 Transport.MaxIdleConnsPerHost 的默认值。

  1. const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"

TimeFormat 是 HTTP 头里面的时间格式。它和 time.RFC1123 相似只不过固定使用 GMT 时区。被格式化的时间必须是 UTC 格式才能保证产生正确的格式化结果。

关于解析这种时间格式,请看 ParseTime。

  1. const TrailerPrefix = "Trailer:"

TrailerPrefix 是 ResponseWriter.Header map 的键的魔法前缀,如果存在,就意味着这个 map 实体其实是响应 trailer 而不是响应头。ServeHTTP 调用完成后会去掉这个前缀并把送入 trailer。

这个机制仅在写入头部时还不知道 trailer 的相关信息的情况下使用。如果 trailer 是固定的或者在写入头部时就可以确定,推荐使用正常的 Go trailer 机制:

  1. https://golang.org/pkg/net/http/#ResponseWriter
  2. https://golang.org/pkg/net/http/#example_ResponseWriter_trailers

Variables

  1. var (
  2. // 当 Pusher 的实现提示不支持 HTTP/2 的 Push 方法时返回 ErrNotSupported/span>
  3. ErrNotSupported = &ProtocolError{"feature not supported"}
  4. // 当服务器返回了一个 Trailer 头但是没有分块数据的时候,Transport 返回 ErrUnexpectedTrailer
  5. ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
  6. // 当请求的 Content-Type 不包含 boundary 参数时 Request.MultipartReader 返回 ErrMissingBoundary
  7. ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
  8. // 当请求的 Content-Type 不是 multipart/form-data 时 Request.MultipartReader 返回 ErrNotMultipart
  9. ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
  10. // 弃用: ErrHeaderTooLong 不再使用。
  11. ErrHeaderTooLong = &ProtocolError{"header too long"}
  12. // 弃用: ErrShortBody 不再使用。
  13. ErrShortBody = &ProtocolError{"entity body too short"}
  14. // 弃用: ErrMissingContentLength 不再使用。
  15. ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
  16. )
  1. var (
  2. // 当 HTTP 方法或响应码不包含请求体时,ResponseWriter.Write 返回 ErrBodyNotAllowed
  3. ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
  4.  
  5. // 当底层链接被 Hijacker 劫持的时候 ResponseWriter.Write 返回 ErrHijacked。
  6. // 在劫持链接中写入0字节也会返回 ErrHijacked。
  7. ErrHijacked = errors.New("http: connection has been hijacked")
  8.  
  9. // 当处理函数写入了 Content-Length 响应头却企图发送字节大于该值的内容时返回 ErrContentLength。
  10. ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
  11.  
  12. // 弃用: ErrWriteAfterFlush 不再使用。
  13. ErrWriteAfterFlush = errors.New("unused")
  14. )

HTTP 服务器使用的错误。

  1. var (
  2. // ServerContextKey 是一个 context key。它能在 HTTP 处理函数中获取其对应的服务器实例。对应值类型为 *Server。
  3. ServerContextKey = &contextKey{"http-server"}
  4.  
  5. // LocalAddrContextKey 是一个 context key。它能在 HTTP 处理函数中获取链接到达的本地地址。
  6. // 对应值类型为 net.Addr。
  7. LocalAddrContextKey = &contextKey{"local-addr"}
  8. )
  1. var DefaultClient = &Client{}

DefaultClient 是 http 包中的默认 Client, Get、Head 和 Post 方法都使用这个 Client。

  1. var DefaultServeMux = &defaultServeMux

DefaultServeMux 是 Serve 默认使用的 ServeMux。

  1. var ErrAbortHandler = errors.New("net/http: abort Handler")

ErrAbortHandler 会监听处理函数中的 panic 事件。当 ServeHTTP 方法发生 panic 并中止响应的时候 ErrAbortHandler 会记录栈信息到服务器的错误日志。

  1. var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")

ErrBodyReadAfterClose 会在读取一个已经关闭的 Request 或 Response 的 Body 时返回。比如在 HTTP 处理函数在调用 ResponseWriter 的 WriteHeader 或 Write 后读取 Body。

  1. var ErrHandlerTimeout = errors.New("http: Handler timeout")

在超时以后调用 ResponseWriter 的 Write 返回 ErrHandlerTimeout。

  1. var ErrLineTooLong = internal.ErrLineTooLong

ErrLineTooLong 读取请求体或响应体遇到不正确的分块信息时返回 ErrLineTooLong。

  1. var ErrMissingFile = errors.New("http: no such file")

FromFile 在文件名不存在于请求中或不是文件名时返回 ErrMissingFile。

  1. var ErrNoCookie = errors.New("http: named cookie not present")

请求的 Cookie 方法没有找到 cookie 时返回 ErrNoCookie。

  1. var ErrNoLocation = errors.New("http: no Location header in response")

没有 Location 头部的时候调用响应的 Location 方法返回 ErrNoLocation。

  1. var ErrServerClosed = errors.New("http: Server closed")

在服务器 Close 或者 Shutdown 以后调用 Serve,ServeTLS,ListenAndServe 和 ListenAndServeTLS 方法返回 ErrServerClosed。

  1. var ErrSkipAltProtocol = errors.New("net/http: skip alternate protocol")

ErrSkipAltProtocol 是一个被 Transport.RegisterProtocol 定义的监听错误。

  1. var ErrUseLastResponse = errors.New("net/http: use last response")

Client.CheckRedirect 返回 ErrUseLastResponse 和控制重定向过程有关。如果返回 ErrUseLastResponse,就不会发送下一个请求,并返回最近一次的响应(不关闭其 body)。

  1. var NoBody = noBody{}

NoBody 是一个 0 字节的 io.ReadCloser。Read 一直返回 EOF,Close 一直返回 nil。他可以被用来明确表示一个 0 字节的外部请求。另一种相对简单的方法是直接把 Body 设置为 nil。

func CanonicalHeaderKey

  1. func CanonicalHeaderKey(s string) string

CanonicalHeaderKey 返回头部键 s 的权威格式。它会把 s 的首字母和连字符后的字母转换成大写,其他部分小写。例如 “accept-encoding” 会变成 “Accept-Encoding”。如果含有空格或者非法字节不对 s 做变动。

func DetectContentType

  1. func DetectContentType(data []byte) string

DetectContentType 实现了 http://mimesniff.spec.whatwg.org/ 所述判断数据 Content-Type 类型的算法。该算法会分析数据的前 512 个字节。DetectContentType 一直返回有效的 MIME 类型。如果找不到一个适合的类型会返回 application/octet-stream

func Error

  1. func Error(w ResponseWriter, error string, code int)

Error 以指定错误信息和 HTTP 状态码响应客户端请求。它不会以其他方式结束请求。在此之后不能再向 w 中写入信息。错误信息必须是纯文本。

func Handle

  1. func Handle(pattern string, handler Handler)

Handle 将指定 URI pattern 的处理函数 handler 注册进 DefaultServeMux。ServeMux 的文档会说明 patterns 的匹配方式。

func HandleFunc

  1. func HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc 将指定 URI pattern 的处理函数 handler 注册进 DefaultServeMux。ServeMux 的文档会说明 patterns 的匹配方式。

func ListenAndServe

  1. func ListenAndServe(addr string, handler Handler) error

ListenAndServe 开始在 TCP 网络地址 addr 上进行监听,然后会在接收到的链接上调用处理函数的 Serve 处理请求。接收到的链接会启用 keep-alives。在 Handler 为 nil 的时候使用 DefaultServeMux。

一个简单的例子:

  1. package main
  2. import (
  3. "io"
  4. "net/http"
  5. "log"
  6. )
  7. // hello world, the web server
  8. func HelloServer(w http.ResponseWriter, req *http.Request) {
  9. io.WriteString(w, "hello, world!\n")
  10. }
  11. func main() {
  12. http.HandleFunc("/hello", HelloServer)
  13. log.Fatal(http.ListenAndServe(":12345", nil))
  14. }

ListenAndServe 总会返回一个非 nil 的错误。

func ListenAndServeTLS

  1. func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error

ListenAndServeTLS 与 ListenAndServe 相同除了它接受的是 HTTPS 的链接。此外,必须提供服务器的证书文件和私钥。如果证书由证书颁发机构签署,certFile 就应该是包含服务器证书,任何中间证书和 CA 证书的串。

一个简单的例子:

  1. import (
  2. "log"
  3. "net/http"
  4. )
  5. func handler(w http.ResponseWriter, req *http.Request) {
  6. w.Header().Set("Content-Type", "text/plain")
  7. w.Write([]byte("This is an example server.\n"))
  8. }
  9. func main() {
  10. http.HandleFunc("/", handler)
  11. log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
  12. err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
  13. log.Fatal(err)
  14. }

可以使用 crypto/tls 中的 generate_cert.go 来创建 cert.pem 和 key.pem。

ListenAndServeTLS 总会返回非 nil 错误。

func MaxBytesReader

  1. func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser

MaxBytesReader 和 io.LimitReader 相似,不过它是用来限制请求体的大小。和 io.LimitReader 的差异主要体现在 MaxBytesReader 的返回值是一个 ReadCloser,超过上限会返回一个非 EOF 的错误。并且在调用 Close 的时候关闭底层 Reader。

MaxBytesReader 会拒绝发送过大请求数据的客户端来避免浪费服务器资源。

func NotFound

  1. func NotFound(w ResponseWriter, r *Request)

NotFound 以 404 错误响应客户端请求。

func ParseHTTPVersion

  1. func ParseHTTPVersion(vers string) (major, minor int, ok bool)

ParseHTTPVersion 解析 HTTP 版本字符串。”HTTP/1.0” 返回 (1, 0, true)。

func ParseTime

  1. func ParseTime(text string) (t time.Time, err error)

ParseTime 尝试使用 HTTP/1.1 允许的三种时间格式: TimeFormat、time.RFC850、和 time.ANSIC 来解析时间头部(例如:Date 头)。

func ProxyFromEnvironment

  1. func ProxyFromEnvironment(req *Request) (*url.URL, error)

ProxyFromEnvironment 返回该请求需要使用的代理 URL。可以设置环境变量 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY(或者其的第几版本)来使用代理。HTTPS_PROXY 的优先级高于 HTTP_PROXY 请求。

环境变量的值可以为完整的 URL 或假定使用 http 的 “host[:port]” 形式。如果不是以上格式将会返回错误。

如果没有定义代理环境变量将会返回 nil,nil。如果请求不想使用代理应该定义 NO_PROXY。

作为特例,如果 req.URL.Host 是 localhost (不带端口号)。那么返回 nil,nil。

func ProxyURL

  1. func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error)

ProxyURL 返回一个供 Transport 使用的代理函数,它一直返回相同 URL。

func Redirect

  1. func Redirect(w ResponseWriter, r *Request, url string, code int)

Redirect 以一个重定向的 url(可能是一个当前请求路径的相对路径)响应客户端请求。

返回的状态码在 3xx 的范围内一般为 StatusMovedPermanently、StatusFound 或 StatusSeeOther。

func Serve

  1. func Serve(l net.Listener, handler Handler) error

Serve 接受即将到达 l 上的 HTTP 链接。并为每个链接创建 goroutine。在 goroutine 中会读取请求并写入响应。当 Handler 为 nil 时默认使用 DefaultServeMux。

func ServeContent

  1. func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker)

ServeContent 以 ReadSeeker 中的内容响应请求。ServeContent 相对 io.Copy 的主要优势是它能正确处理不同种类的请求,设置 MIME 类型和处理 If-Match、If-Unmodified-Since、If-None-Match、If-Modified-Since、If-Range 请求。

如果响应没有设置 Content-Type,ServeContent 会先尝试使用文件名的后缀处判断类型。如果失败会读取第一块数据并使用 DetectContentType 解析它。名字在其他时候是没有用的;如果他为空就不会写入响应。

如果 modtime 不为 0 或 Unix 时间起点。ServeContent 会将其设置为 Last-Modified 响应头信息。如果请求头中包含 If-Modified-Since,ServeContent 会使用 modtime 来判断是否需要发送数据。

Seek 方法必须能够找到数据的结尾,这样 ServerContent 才能知道数据的大小。

如果调用者设置了 w 的 RFC 7232 第 2.3 章格式 ETag 头部。ServeContent 会使用它处理使用 If-Match、If-None-Match 或 If-Range 的请求。

注意:*os.File 实现了 io.ReadSeeker 接口。

func ServeFile

  1. func ServeFile(w ResponseWriter, r *Request, name string)

ServeFile 以文件或者文件夹的内容响应请求。

如果给定的文件/文件夹为相对路径,那么将会以当前目录作为参考目录并可能访问父级目录。如果给定的名字是用户的输入,那么在调用 ServeFile 前需要对其预处理。出于安全考虑,ServeFile 会拒绝 r.URL.Path 中带有 .. 的请求。

特殊说明:ServeFile 会将请求重定向在 r.URL.Path 的 “/index.html” 里。如果不想这样可以改变路径或者使用 ServeContent。

func ServeTLS

  1. func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error

ServeTLS 接受即将到达 l 的 HTTPS 链接,并为每个链接创建 goroutine。goroutine 会读取请求然后处理并响应请求。

如果 Handler 为 nil,会默认使用 DefaultServeMux。

此外,必须提供服务器的证书文件和私钥。如果证书由证书颁发机构签署,certFile 就应该是包含服务器证书,任何中间证书和 CA 证书的串。

func SetCookie

  1. func SetCookie(w ResponseWriter, cookie *Cookie)

SetCookie 在 ResponseWriter 头部添加一个 Set-Cookie 的头信息。cookie 必须包含一个有效名称。无效的 cookies 可能会被忽略。

func StatusText

  1. func StatusText(code int) string

StatusText 返回 HTTP 状态码对应的文字。如果返回未知状态码会返回空字符串。

type Client

  1. type Client struct {
  2. // Transport 指定 HTTP 请求的生成机制,如果是 nil, 默认使用 DefaultTransport 。
  3. Transport RoundTripper
  4.  
  5. // CheckRedirect 指定处理重定向的策略。
  6. // 如果 CheckRedirect 不为 nil, 客户端会在重定向之前调用它。
  7. // req 是即将到达的请求,via 是已经转发的请求(按时间先后排序)。
  8. // 如果 CheckRedirect 错误,Client 的 Get 方法会返回之前的响应(Body 为关闭状态)和 CheckRedirect 发生的错误。
  9. // 如果 CheckRedirect 返回 ErrUseLastResponse,那么将会返回最近一次响应(Body 为未关闭状态)和 nil。
  10. //
  11. // 如果 CheckRedirect 为 nil,调用者会使用默认的策略(支持最大 10 次连续重定向)。/span>
  12. CheckRedirect func(req *Request, via []*Request) error
  13. // Jar 代表 cookie jar。
  14. //
  15. // Jar 用来保存每个请求的相关 cookie 并更新每个响应的 cookie。
  16. // Jar 会被重定向的客户端读取。
  17. //
  18. // 如果 Jar 为 nil, cookie 只会在被显式设置的时候才会发送。
  19. Jar CookieJar
  20. //Timeout 代表请求的这个客户端请求的时间限制。
  21. // 它包括连接时间,重定向时间和读取响应的时间。
  22. // 定时器会在 Get、Head、Post 或 Do 返回时停止并中止 Response.Body 的读取。
  23. //
  24. // 零值说明没有超时时间。
  25. //
  26. // Client 可以通过底层 Request.Cancel 来取消本次对底层 Transport 的请求。
  27. // 在 Client.Do 中也可以设置 Request.Cancel;两种方式都可以取消请求。
  28. //
  29. // 出于兼容性考虑,Client 可以在 Transport 中找到 CancelRequest 并使用它。新的 RoundTripper 实现需要使用 Request.Cancel 而不是实现 CancelRequest
  30. Timeout time.Duration
  31. }

Client 是 HTTP 客户端。零值的 Client 使用了 DefaultTransport。

Client 的 Transport 含有有内部状态(用来缓存 TCP 链接),所以 Client 应该多次重用而不是

按需创建。 Client 可以安全的被多个 goroutine 使用。

Client 比 RoundTripper 更高级并且还会处理 HTTP 的细节,例如 cookies 和重定向。

当重定向的时候,Client 使用之前请求的请求头除了:

• 当请求头中包含 “Authorization”、”WWW-Authenticate” 和 “Cookie” 敏感信息。这些头部会在重定向地址不是原域名或原域名的子域名时忽略。例如 “foo.com” 在重定向到 “foo.com” 或者 “sub.foo.com” 时会带有上述头信息。而重定向到 “bar.com” 却不会。

• 当请求带有一个非 nil 的 cookie。因为每次重定向 cookie 的状态都可能会改变,所以每次重定向都有可能改变 cookie。每次重定向都会把发生变化的 cookie 数据删除并插入新值。如果 Jar 为 nil,那么将会保持原来的 cookie。

func (*Client) Do

  1. func (c *Client) Do(req *Request) (*Response, error)

Do 会根据客户端的配置发送 HTTP 请求并返回响应。

如果是因为客户端配置或者网络连接原因会返回 error,一个非 2xx 响应不会返回错误。

如果返回的 error 是 nil,响应就会包含一个非 nil 的 Body(需要用户手动 Close)。如果 Body 没有关闭那么底层 RoundTripper 不会在随后的请求中重用 TCP 链接。

请求的 Body 会被底层 Transport 关闭(即使运行出错也会关闭)。

发生错误时任何响应都能被忽略。非 nil 的 error 和非 nil 的 Response 只有在检查重定向失败的时候才会同时发生。这时返回的 Response.Body 已经关闭。

一般情况我们可以使用 Get、Post 或 PostForm 而不是 Do。

如果服务器把重定向作为响应,Client 首先使用 CheckRedirect 判断是否要遵循重定向策略。如果允许重定向,状态码为 301、302 或 303 时,随后的请求使用 Get 方法(如果之前是 HEAD 就使用 HEAD 方法)。如果定义了 Request.GetBody 方法, 307 或 308 会使用原来的方法和请求体。NewRequest 函数会自动为标准的库的 Body 类型设置 GetBody 方法。

func (*Client) Get

  1. func (c *Client) Get(url string) (resp *Response, err error)

Get 向指定的 URL 发起 GET 请求。如果响应是以下几种重定向状态码之一,Get 会在调用 CheckRedirect 函数后进行重定向 :

  1. 301 (Moved Permanently)
  2. 302 (Found)
  3. 303 (See Other)
  4. 307 (Temporary Redirect)
  5. 308 (Permanent Redirect)

如果 Client 的 CheckRedirect 返回失败或发生 HTTP 协议错误会返回错误。一个非 2xx 响应不会返回错误。

如果 err 为 nil,resp 总是一个非 nil 的 resp.Body。调用者应该在读取完数据后关闭 resp.Body。

如果想使用自定义头部,可以使用 NewRequest 和 Client.Do。

func (*Client) Head

  1. func (c *Client) Head(url string) (resp *Response, err error)

Head 向指定 URL 发起一个 HEAD 请求。如果响应是以下几种重定向状态码之一,Get 会在调用 CheckRedirect 函数后进行重定向 :

  1. 301 (Moved Permanently)
  2. 302 (Found)
  3. 303 (See Other)
  4. 307 (Temporary Redirect)
  5. 308 (Permanent Redirect)

func (*Client) Post

  1. func (c *Client) Post(url string, contentType string, body io.Reader) (resp *Response, err error)

Post 会向指定 URL 发起 POST 请求。

用户需要在读取完数据以后关闭 resp.Body。

如果 body 是一个 io.Closer,它会在请求完成后关闭。

如果想使用自定义头部,可以使用 NewRequest 和 Client.Do。

在 Client.Do 文档中具体说明如何处理重定向。

func (*Client) PostForm

  1. func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)

PostForm 会向指定 URL 发起 POST 请求,他的请求体是经过 URL 编码的键值对。

Content-Type 会设置成 application/x-www-form-urlencoded。如果想设置其他头部,可以使用 NewRequest 和 DefaultClient.Do。

如果 err 为 nil,resp 总会返回非 nil 的 resp.Body。用户应该在读取完数据以后关闭 resp.Body。

在 Client.Do 文档中具体说明如何处理重定向。

type CloseNotifier

  1. type CloseNotifier interface {
  2. // 当客户端关闭的时候,CloseNotify 会返回最多接收到一个值的 channel。
  3. //
  4. // CloseNotify 会一直等待直到 Request.Body 读取完成。
  5. //
  6. // 在处理函数执行完成以后, 不保证 channel 中是否有值返回。
  7. //
  8. // 如果是 HTTP/1.1 协议并且 CloseNotify 在一个幂等请求执行时等待,那么在下次请求到达的时候可能导致 channel 中有值返回。在 HTTP/1.1 的管道实现中没有启用观察功能而且很多时候是观察不到的。如果对于你来说这是一个问题,可以使用 HTTP/2 协议或只在 POST 请求上使用 CloseNotify。
  9. CloseNotify() <-chan bool
  10. }

ResponseWriter 实现了 CloseNotifier 接口,它赋予程序感知底层链接断开的能力。

这个机制能在客户端连接断开后取消那些服务器上的慢操作。

type ConnState

  1. type ConnState int

ConnState 代表客户端的连接状态,Server.ConnState 使用它。

  1. const (
  2. // StateNew 代表一个立刻发送请求的新链接。
  3. // 链接都以这个状态开始然后转换成 StateActive 或 StateClosed。
  4. StateNew ConnState = iota
  5.  
  6. // StateActive 代表一个已经读取过 1 个或更多字节请求的链接。
  7. // The Server.ConnState 会在请求进入处理函数前触发 StateActive 状态。在处理请求的过程中都不会再触发。
  8. // 在请求处理以后,状态会变成 StateClosed、StateHijacked 或 StateIdle。
  9. // 对于 HTTP/2,StateActive 会在活跃请求从 0 变为 1 时触发,并且只在所有活跃请求中触发一次。
  10. // 这意味着 ConState 不会在每个请求之前使用;ConnState 只表示链接的总体状态。
  11. StateActive
  12.  
  13. // StateIdle 代表一个已经处理完请求并处于 keep-alive 状态等待新请求的链接。
  14. // 链接可以从 StateIdle 状态变为 StateActive 或 StateClosed 状态。
  15. StateIdle
  16.  
  17. // StateHijacked 代表一个劫持链接。
  18. // 这是一个链接的最终状态。它不会转换成 StateClosed.
  19. StateHijacked
  20.  
  21. // StateClosed 代表一个关闭的链接。
  22. // 这是一个最终状态,劫持链接不会变成这个状态。
  23. StateClosed
  24.  
  25.  
  26. )

func (ConnState) String

  1. func (c ConnState) String() string

  1. type Cookie struct {
  2. Name string
  3. Value string
  4.  
  5. Path string // optional
  6. Domain string // optional
  7. Expires time.Time // optional
  8. RawExpires string // 只针对 cookie 的读取。
  9.  
  10. // MaxAge 等于 0 代表没有 `Max-Age` 属性。
  11.  
  12. // MaxAge 小于 0 代表现在删除 cookie,与 `Max-Age: 0` 相同。
  13. // MaxAge 大于 0 代表 `Max-Age` 在规定时间内存在。
  14. MaxAge int
  15. Secure bool
  16. HttpOnly bool
  17. Raw string
  18. Unparsed []string // 键值对的原生字符串文本。
  19. }

Cookie 代表 HTTP 响应中的 Set-Cookie 头信息和 HTTP 请求中的 Cookie 头信息。

更多详情请看http://tools.ietf.org/html/rfc6265。

func (*Cookie) String

  1. func (c *Cookie) String() string

String 返回 cookie 序列化后的字符串 (用于请求中的 Cookie 或者响应中的 Set-Cookie 头信息;只有 Name 和 Value 都存在才会被返回)。如果 c 为 nil 或者 c.Name 是无效的返回空字符串。

type CookieJar

  1. type CookieJar interface {
  2. // SetCookies 处理指定 URL 返回的 cookie 信息。
  3. // 它可以选择保存或者不保存 cookie。这依赖具体的实现。
  4. SetCookies(u *url.URL, cookies []*Cookie)
  5.  
  6. // Cookies 返回请求指定 URL 的 cookie。
  7. // 它严格遵循的 cookie 标准使用规范(RFC 6265)。
  8. Cookies(u *url.URL) []*Cookie
  9.  
  10. }

CookieJar 会管理 cookie 的储存并在 HTTP 请求中使用。

CookieJar 的实现必须保证能安全的被多个 goroutine 使用。

net/http/cookiejar 包提供了 CookieJar 的实现。

type Dir

  1. type Dir string

Dir 使用原生的文件系统实现了指定文件目录树的 FileSystem。

FileSystem.Open 传入 ‘/‘ 开头的路径时,Dir 的值是它在文件系统中的文件名而不是 URL,所以他的分隔符为 filepath.Separator 而不一定是 ‘/‘。

注意 Dir 可以在一段时间内读取到一些敏感文件(例如 .git 目录或 .htpasswd)。为了排除这些文件,可以把这些文件移出目录或创建自定义的 FileSystem 实现。

一个空的 Dir 用 . 表示。

func (Dir) Open

  1. func (d Dir) Open(name string) (File, error)

type File

  1. type File interface {
  2. io.Closer
  3. io.Reader
  4. io.Seeker
  5. Readdir(count int) ([]os.FileInfo, error)
  6. Stat() (os.FileInfo, error)
  7. }

FileSystem 的 Open 返回 File 作为 FileServer 的实现。

这些方法的行为应该与 *os.File 保持一致。

type FileSystem

  1. type FileSystem interface {
  2. Open(name string) (File, error)
  3. }

FileSystem 实现了对一组指定文件的访问。不管是什么操作系统文件分隔符都是下划线(’/‘,U+002F)字符。

type Flusher

  1. type Flusher interface {
  2. // Flush 将所有缓存数据发送到客户端。
  3. Flush()
  4. }

ResponseWriters 实现了 Flusher 接口,它允许 HTTP 处理函数将缓存数据刷新进客户端。

默认的 HTTP/1.x 和 HTTP/2 ResponseWriter 实现都支持 Flusher。但是被封装过的 ResponseWriter 不一定实现了该接口。处理函数应该在使用之前测试是否实现了该接口。

注意:如果客户端是通过 HTTP 代理连接,即使 ResponseWriters 支持 Flush缓存数据也有可能在响应结束前不会直接到达客户端。

type Handler

  1. type Handler interface {
  2. ServeHTTP(ResponseWriter, *Request)
  3. }

Handler 负责对 HTTP 请求作出响应。

ServeHTTP 应该将响应头和响应数据写入 ResponseWriter 后返回。函数返回代表请求结束;在调用 ServeHTTP 的同时或之后再向 ResponseWriter 写入数据,或读取请求体都是无效的。

根据不同的 HTTP 客户端软件、HTTP 协议版本、所有客户端到服务端的中间环节都不可能在写入 ResponseWriter 之后读取 Request.Body。严谨的处理函数应该先读取 Request.Body 再响应请求。

除了读取请求,处理函数不能对请求做任何修改。

如果 ServeHTTP panic,服务器会认为 panic 就是中断此次请求,它会 recover 这个 panic,在错误日志中记录调用栈,

并关闭连接或发送 RST_STREAM(如果是 HTTP/2),这依赖 HTTP 协议的实现。中断请求函数客户端会得到一个中断的响应,但是他并不是服务器出错,所以不会有错误日志或 panic,而进入 ErrAbortHandler 函数。

func FileServer

  1. func FileServer(root FileSystem) Handler

FileServer 返回一个 HTTP 处理函数,它用 root 里文件的内容作为 HTTP 请求的响应来提供服务。

使用 http.Dir 来获取操作系统的文件系统实现:

  1. http.Handle("/", http.FileServer(http.Dir("/tmp")))

如果在请求路径有的尾部像 /index.html 这样,会把请求定向到同名文件路径,如果没有会自动定向到 index.html


例:

  1. // Simple static webserver:
  2. log.Fatal(http.ListenAndServe(":8080", http.FileServer(http.Dir("/usr/share/doc"))))


例:

  1. // 为了在一个 URL 路径下(/tmpfiles/)提供(/tmp)文件目录服务,可以使用 StripPrefix 在到达文件服务器之前修改请求的 URL 路径:
  2. http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))

func NotFoundHandler

  1. func NotFoundHandler() Handler

NotFoundHandler 返回一个将 404 page not found 作为请求响应的处理函数。

func RedirectHandler

  1. func RedirectHandler(url string, code int) Handler

RedirectHandler 返回一个将请求以指定状态码重定向 url 作为响应的处理函数。

重定向状态码应该在 3xx 范围内,一般都为 StatusMovedPermanently、StatusFound 或 StatusSeeOther。

func StripPrefix

  1. func StripPrefix(prefix string, h Handler) Handler

StripPrefix 返回一个将 URL 中的指定前缀去掉后调用 h 的处理函数。

如果请求不是以指定前缀开头,返回 HTTP 的 404 not found 错误。


例:

  1. // 为了在一个 URL 路径下(/tmpfiles/)提供(/tmp)文件目录服务,可以使用 StripPrefix 在到达文件服务器之前修改请求的 URL 路径:
  2. http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp"))))

func TimeoutHandler

  1. func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler

TimeoutHandler 返回一个必须在规定时间内返回的处理函数。

Handler 会为每个请求调用 h.ServeHTTP,但是如果函数执行时间比规定时限更长,就会返回 503 错误和给定的错误信息(如果 msg 为空,会使用默认信息)。在超时以后 h 中 ResponseWriter 的写操作返回 ErrHandlerTimout。

TimeoutHandler 会将所有的处理函数写入内存而且不支持 Hijacker 和 Flusher 接口。

type HandlerFunc

  1. type HandlerFunc func(ResponseWriter, *Request)

HandlerFunc 类型是一个允许使用普通的函数作为 HTTP 的处理函数的适配器。如果一个函数拥有合适的函数签名 HandlerFunc(f) 会是一个调用 f 的 Handler。

func (HandlerFunc) ServeHTTP

  1. func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request)

ServeHTTP 调用 f(w, r)。

  1. type Header map[string][]
  2.  
  3. Header 代表 HTTP 头部的键值对信息。
  4.  
  5. func (Header) Add

  6. func (h Header) Add(key, value string)
  7.  
  8. Add Header 添加一个键值对,他会将值追加到 key 对应的值中。

  9. func (Header) Del

  10. func (h Header) Del(key string)
  11.  
  12. Del 删除 key 对应的值。

  13. func (Header) Get

  14. func (h Header) Get(key string) string
  15.  
  16. Get 会返回 key 对应的第一个值。它不区分大小写。textproto.CanonicalMIMEHeaderKey 用来提供规范化的 key

  17. 如果 key 没有对应的值。Get 返回空字符串。如果想获取 key 的多个值,或使用非规范化的 key,可以直接访问 map

  18. func (Header) Set

  19. func (h Header) Set(key, value string)
  20.  
  21. Set 设置 key 的值。它会替换已经存在键的值。

  22. func (Header) Write

  23. func (h Header) Write(w io.Writer) error
  24.  
  25. Write 以线性格式写入头信息。

  26. func (Header) WriteSubset

  27. func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error
  28.  
  29. WriteSubset 以线性格式写入头部,如果 exclude 不是 nil 不会写入 exclude[key] == true 的键。

  30. type Hijacker

  31. type Hijacker interface {
  32.     // Hijack 让调用者接管链接。
  33.     // 调用 Hijack 后 http 服务器不会再对链接做任何操作。
  34.     //
  35.     // 由调用者管理和关闭这些链接。
  36.     //
  37.     // 返回的 net.Conn 可能有读或写的截止时间,这依赖服务器的配置。
  38.     // 由调用者负责按需设置或者清除截止时间。
  39.     //
  40.     // 返回的 bufio.Reader 可能包含来自客户端还没处理的数据。
  41.     //
  42.     // 在调用 Hijack 后,原来的 Request.Body 不应该再被使用。
  43.     Hijack() (net.Conn, *bufio.ReadWriter, error)
  44. }
  45.  
  46. ResponseWriters 实现了 Hijacker 接口,它允许 HTTP 处理器接管链接。

  47. 默认的 HTTP/1.x ResponseWriter 链接支持 Hijacker,但是 HTTP/2 不支持。封装的 ResponseWriter 可能不支持 Hijacker,处理器应该在使用前测试它是否有这种能力。


  48. 例:

  49. http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
  50.     hj, ok := w.(http.Hijacker)
  51.     if !ok {
  52.         http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
  53.         return
  54.     }
  55.     conn, bufrw, err := hj.Hijack()
  56.     if err != nil {
  57.         http.Error(w, err.Error(), http.StatusInternalServerError)
  58.         return
  59.     }
  60.     // Don't forget to close the connection:
  61.     defer conn.Close()
  62.     bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
  63.     bufrw.Flush()
  64.     s, err := bufrw.ReadString('\n')
  65.     if err != nil {
  66.         log.Printf("error reading string: %v", err)
  67.         return
  68.     }
  69.     fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
  70.     bufrw.Flush()
  71. })
  72. type ProtocolError

  73. type ProtocolError struct {
  74.     ErrorString string
  75. }
  76.  
  77. ProtocolError 代表 HTTP 协议错误。

  78. 弃用:不是所有 http 包协议相关的错误都是 ProtocolError 类型。

  79. func (*ProtocolError) Error

  80. func (pe *ProtocolError) Error() string
  81.  
  82.  
  83. type PushOptions

  84. type PushOptions struct {
  85.     //  Method 代表请求承诺的 HTTP 方法。
  86.     // 它的值只能是 "GET" 或 "HEAD"。为空默认使用 "GET"。
  87.     Method string
  88.     // Header 代表请求额承诺的请求头。
  89.     // 它不能是 HTTP/2 中像 ":path" 和 ":scheme" 这些会自动添加的请求头字段。
  90.     Header Header
  91. }
  92.  
  93. PushOptions 描述了 Pusher.Push 的可选项。

  94. type Pusher

  95. type Pusher interface {
  96.     // Push 初始化一个 HTTP/2 服务器推送。这会构造一个给定选项和目标的请求。
  97.     // 把这个请求序列化进 PUSH_PROMISE 框架。然后分发进请求处理函数。
  98.     //如果 opts 为空,使用默认选项。
  99.     //
  100.     // target 必须是绝对路径或完整 URL(包含有效主机名称和父请求相同的协议方案)。
  101.     // 如果 target 是绝对路径那么继承父请求的主机名和协议方案。
  102.     //
  103.     // HTTP/2 不允许递归推送和越权推送。
  104.     // Push 不一定能检测到这些无效推送,不过无效的推送和取消操作可以被客户端侦测到。
  105.     //
  106.     // 想要向 URL X 推送的处理函数应该在任何可能触发向 URL X 请求之前调用 Push 方法。这样可以避免客户端在 X 接收到 PUSH_PROMISE 之前发起请求而引起的冲突。
  107.     //
  108.     // 如果客户端禁用了推送或底层链接不支持推送会返回 ErrNotSupported。
  109.     Push(target string, opts *PushOptions) error
  110. }
  111.  
  112. ResponseWriters 实现了Pusher 接口用来支持 HTTP/2 服务器的推送功能。更多信息请看https://tools.ietf.org/html/rfc7540#section-8.2。

  113. type Request

  114. type Request struct {
  115.     // Method 代表 HTTP 请求的方法 (GET、POST、PUT、等)。
  116.     // 对于客户端空 Method 代表 GET 请求。
  117.     //
  118.     // Go 的 HTTP 客户端不支持使用 CONNECT 方法发送请求。Transport 有文档具体说明。
  119.     Method string
  120.     //  URL 对于服务端代表被请求的地址。
  121.     // 对于客户端代表请求的 URL。
  122.     //
  123.     // 对于服务端来讲 URL 是从 RequestURI 中解析出来的。对于大多数请求,Path 和 RawQuery 都为空。(详情请看 RFC 2616 第 5.1.2 章节)
  124.     //
  125.     // 对于客户端请求,URL 的 Host 代表连接的服务器地址。而请求的 Host 字段可选地指定要在 HTTP 请求中发送的 Host 值。
  126.     URL *url.URL
  127.     // 请求的协议版本。
  128.     //
  129.     // 客户端忽略这些字段。HTTP 客户端总是使用 HTTP/1.1 或 HTTP/2。
  130.     // 详情请看 Transport 文档。
  131.     Proto      string // "HTTP/1.0"
  132.     ProtoMajor int    // 1
  133.     ProtoMinor int    // 0
  134.     // Header 包含服务器接收或请求发送的请求头信息。
  135.     //
  136.     // 如果服务器接收到如下头信息,
  137.     //
  138.     //    Host: example.com
  139.     //    accept-encoding: gzip, deflate
  140.     //    Accept-Language: en-us
  141.     //    fOO: Bar
  142.     //    foo: two
  143.     //
  144.     // 会转换为:
  145.     //
  146.     //    Header = map[string][]string{
  147.     //        "Accept-Encoding": {"gzip, deflate"},
  148.     //        "Accept-Language": {"en-us"},
  149.     //        "Foo": {"Bar", "two"},
  150.     //    }
  151.     //
  152.     // 对于即将到达的请求,Host 头信息会晋升为 Request.Host 字段并在 Header 的 map 中移除。
  153.     //
  154.     // HTTP 定义的头信息不区分大小写。请求解析器使用 CanonicalHeaderKey 实现忽略头信息的大小写,将首字符和连字符之后的字母大写,其他字母小写。
  155.     //
  156.     // 对于客户端请求,固定的头部例如 Content-Length 和 Connection 会自动按需设置已经存在的值会被忽略。详情请看 Request.Write 文档。
  157.     Header Header
  158.     //  Body 代表请求体。
  159.     //
  160.     // 客户端请求的请求体为 nil 说明请求没有请求体(例如 GET 请求)。客户端的 Transport 负责调用 Close 方法。
  161.     //
  162.     // 对于服务端请求的请求体一直为非 nil,但是在没有请求体存在的时候会立即返回 EOF。服务器会自动关闭请求体。ServeHTTP 不需要做关闭操作。
  163.     Body io.ReadCloser
  164.     // GetBody 定义了一个可选的函数用来返回请求体的拷贝。
  165.     // 一般会用在在重定向时需要多次读取请求的时候。使用 GetBody 时仍然需要设置 Body。
  166.     //
  167.     // 对于服务端请求它是没用的。
  168.     GetBody func() (io.ReadCloser, error)
  169.     // ContentLength 记录对应内容的长度。
  170.     // -1 表示未知长度。
  171.     // Values >= 0 表示可以读取的最大字节数。
  172.     // 对于客户端请求,一个非 nil 的 Body 值为 0 与未知长度是一样的。
  173.     ContentLength int64
  174.     // TransferEncoding 表示请求体由外至内的传输编码。空列表代表未编码。
  175.     // TransferEncoding 总能被忽略;chunked 会根据收发请求的情况自动添加删除。
  176.     TransferEncoding []string
  177.     // Close 表示是否要在响应请求(服务端)或在读取响应(客户端)之后关闭链接。
  178.     //
  179.     // HTTP 服务器会自动处理并且处理函数中不需要这个字段。
  180.     //
  181.     // 客户端通过设置 Close 来阻止在设置 Transport.DisableKeepAlives 时请求相同主机时复用 TCP 链接。
  182.     Close bool
  183.     // 服务端的 Host 表示请求 URL 中的主机名。依据 RFC 2616,这个值可以是 Host 请求头的值也可以是 URL 主机名本身。
  184.     // 它可能是 `host:port` 格式。对于国际域名,他可能是 Punycode 或 Unicode 格式。使用 `golang.org/x/net/idna` 转换成你需要的格式。
  185.     //
  186.     // 客户端请求可以选择在发送时重写 Host 请求头。Request.Write 方法使用的是 URL.Host 的值。Host 可以是一个国际域名。
  187.     Host string
  188.     // Form 保存从 URL 参数和 POST 或 PUT 请求体中解析的数据。
  189.     // 这个字段只有在调用 ParseForm 后才有效。
  190.     // HTTP 客户端会忽略 Form 而直接使用 Body。
  191.     Form url.Values
  192.     // PostForm 包含从 POST、PATCH 或 PUT 请求体中解析出的数据。
  193.     //
  194.     // 这个字段只在 ParseForm 调用后有效。
  195.     // HTTP 客户端忽略 PostForm 直接使用 Body。
  196.     PostForm url.Values
  197.     // MultipartForm 解析包括上传文件的 multipart 表单。
  198.     // 这个字段只在 ParseForm 调用后有效。
  199.     // HTTP 客户端忽略 MultipartForm 直接使用 Body。
  200.     MultipartForm *multipart.Form
  201.     // Trailer 指定一些在请求体之后发送的额外头部。
  202.     //
  203.     // 服务端请求的 Trailer 最初只包含请求 trailer 的键,它们的值都为 nil
  204.         (客户端定义的 trailer 会在之后发送)。当处理函数正在读取请求体时,不能使用 Trailer。在请求体返回 EOF 后,Trailer 会被再次读取,如果客户端发送了 trailer 的值,那么 Trailer 就不会是 nil 值。
  205.     //
  206.     // 客户端的 Trailer 必须包括需要发送 trailer 的键。值可以为 nil 或者最终值。ContentLength 必须是 0 或 -1,表示发送一个分段的请求。
  207.     // 在 HTTP 请求发送以后在请求体被读取前 map 中的值都是可以修改的。一旦 Body 返回 EOF,调用者就不能再修改 Trailer。
  208.     //
  209.     // 只有少数 HTTP 客户端,服务器,或代理支持 HTTP trailers。
  210.     Trailer Header
  211.     // RemoteAddr 允许 HTTP 服务器和其他软件记录请求的发送地址,一般是为了日志需要。这个字段不会被 ReadRequest 填充并且没有定义格式。在调用处理函数之前,HTTP 服务器会将 RemoteAddr 设置为 `IP:port`;
  212.     // 这个字段会被 HTTP 客户端忽略。
  213.     RemoteAddr string
  214.     // RequestURI 保存客户端发给服务端的 Request-Line 的 Request-URI 原始数据。一般使用 URL 字段,在 HTTP 客户端请求中手动设置该字段是错误的。
  215.     RequestURI string
  216.     // TLS 允许 HTTP 服务器和其他软件记录接收请求的 TLS 链接的相关信息。这个字段不会被 ReadRequest 填充。
  217.     // 在这个包中的 HTTP 服务器会在调用处理函数前为开启 TLS 的链接设置该字段(如果未开启值为 nil)。
  218.     // 这个字段会被 HTTP 客户端忽略。
  219.     TLS *tls.ConnectionState
  220.     // Cancel 是一个可选的 channel,它的关闭意味着请求被取消。不是所有的 RoundTripper 实现都支持 Cancel。
  221.     //
  222.     // 在服务端这个字段不适用。
  223.     //
  224.     // 弃用:使用 Context 和 WithContext 代替。如果请求的 Cancel 和 context 一起存在,不保证它们的优先级。
  225.     Cancel <-chan struct{}
  226.     // Response 是一个重定向的响应,它是创建该请求的原因。这个字段只有在客户端重定向时才会用到。
  227.     Response *Response
  228.     // contains filtered or unexported fields
  229. }
  230.  
  231. Request 代表一个服务器接收或向客户端发送的 HTTP 请求。

  232. 客户端和服务端使用的时候语义上略有不同。为了了解这些我们可以查看 Request.Write RoundTripper 的文档。

  233. func NewRequest

  234. func NewRequest(method, url string, body io.Reader) (*Request, error)
  235.  
  236. NewRequest 返回指定方法、URL 和请求体(可选)的新 Request

  237. 如果 body 实现了 io.Closer,那么 Request.Body 会使用它并由 DoPostPostForm Transport.RoundTrip 负责关闭。

  238. NewRequest 返回一个适用于 Client.Do Transport.RoundTrip Request。如果想创建一个测试处理函数使用的请求,

  239. 可以使用 net/http/httptest 中的 NewRequestReadRequest,或手动修改请求的字段。

  240. 如果 body bytes.Bufferbytes.Reader *strings.Reader 类型,返回请求的 ContentLength 是一个确切的值(而不是 -1),GetBody 会被填充(所以重定向的 307 308 能够重新读取body),并且 Body 会在 ContentLength 等于 0 的时候设置成 NoBody

  241. func ReadRequest

  242. func ReadRequest(b *bufio.Reader) (*Request, error)
  243.  
  244. ReadRequest 读取并解析 b 中的请求数据。

  245. func (*Request) AddCookie

  246. func (r *Request) AddCookie(c *Cookie)
  247.  
  248. AddCookie 为请求添加 cookie。依据 RFC 6265 的第 5.4 章节,AddCookie 不会添加多个相同 Cookie 头。这意味着所有的 cookie都会由分号分割写在同一行里面。

  249. func (*Request) BasicAuth

  250. func (r *Request) BasicAuth() (username, password string, ok bool)
  251.  
  252. 如果请求使用的是 HTTP 基础验证 BasicAuth 返回 Authorization 头用于验证的用户名和密码。详情请看 RFC 2617 2 章。

  253. func (*Request) Context

  254. func (r *Request) Context() context.Context
  255.  
  256. Context 返回请求的 context,可以使用 WithContext 来更改 context

  257. context 总是非 nil 的;它默认是 background context

  258. 对于服务器接收到的请求,context 会在客户端链接关闭或 ServeHTTP 方法返回时取消请求。

  259. func (*Request) Cookie

  260. func (r *Request) Cookie(name string) (*Cookie, error)
  261.  
  262. Cookie 返回名字为 name cookie ,如果没有找到返回 ErrNoCookie。如果找到多个同名 cookie,只有一个会返回。

  263. func (*Request) Cookies

  264. func (r *Request) Cookies() []*Cookie
  265.  
  266. Cookies 解析并返回 HTTP 请求的 cookie

  267. func (*Request) FormFile

  268. func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)
  269.  
  270. FormFile 返回 key 对应的第一个文件。FormFile 会在需要时调用 ParseMultipartForm ParseForm

  271. func (*Request) FormValue

  272. func (r *Request) FormValue(key string) string
  273.  
  274. FormValue 返回请求查询部分 key 对应的第一个值。POST PUT body 请求体参数优先级高于 URL 查询部分。FormValue 会在需要的时候调用 ParseMultipartForm ParseForm 并会忽略这些函数返回的错误。如果 key 不存在,FormValue 返回空字符串。如果同一个键对应多个值,会调用 ParseForm 然后直接在 Request.Form 取值。

  275. func (*Request) MultipartReader

  276. func (r *Request) MultipartReader() (*multipart.Reader, error)
  277.  
  278. 如果是 multipart/form-data POST 请求,MultipartReader 返回一个 MIME multipart reader ,否则返回 nil error。使用这个函数代替 ParseMultipartForm 把请求体最为流进行处理。

  279. func (*Request) ParseForm

  280. func (r *Request) ParseForm() error
  281.  
  282. ParseForm 填充了 r.Form r.PostForm

  283. 对于所有请求,ParseForm 会解析 URL 中的查询部分并更新到 r.Form 中。

  284. 对于 POSTPUT PATCH 请求,他还解析请求体并将结果保存在 r.PostForm r.Form 中。请求体参数优先级高于 URL 查询参数。

  285. 对于其他的 HTTP 方法,如果请求的 Content-Type 不是 application/x-www-form-urlencoded,就不会读取请求体,这时 r.PostForm 是一个非 nil 的空值。

  286. 如果不使用 MaxBytesReader 限制请求体的尺寸。会取默认值 10MB

  287. ParseMultipartForm 会自动调用 ParseFormParseForm 是幂等的。

  288. func (*Request) ParseMultipartForm

  289. func (r *Request) ParseMultipartForm(maxMemory int64) error
  290.  
  291. ParseMultipartForm 把请求体当作 multipart/form-data 类型并解析。它会解析整个请求体和最大 maxMemory 字节的文件并保存在内存中,其余部分会保存在硬盘或临时文件中。ParseMultipartForm 会在需要时调用 ParseFormParseMultipartForm 只需调用一次,多次调用没有效果。

  292. func (*Request) PostFormValue

  293. func (r *Request) PostFormValue(key string) string
  294.  
  295. PostFormValue 返回 POST PUT 请求体参数中 key 对应的第一个值。它会忽略 URL 查询参数。PostFormValue

  296. 在需要时调用 ParseMultipartForm ParseForm 并会忽略这些函数的错误。如果 key 不存在返回空字符串。

  297. func (*Request) ProtoAtLeast

  298. func (r *Request) ProtoAtLeast(major, minor int) bool
  299.  
  300. ProtoAtLeast 验证 HTTP 协议版本至少为 major.minor

  301. func (*Request) Referer

  302. func (r *Request) Referer() string
  303.  
  304. 如果请求发送了上一个请求的 URLReferer 会返回它。

  305. Referer 其实是在 HTTP 早期请求中的拼写错误。这个值可以通过 Header[“Referer”] 获取。

  306. 将它作为函数提供的好处是编译器可以诊断 req.Referer() 的拼写错误,Header[“Referrer”] 却不能。

  307. func (*Request) SetBasicAuth

  308. func (r *Request) SetBasicAuth(username, password string)
  309.  
  310. SetBasicAuth 设置请求的 Authorization 头信息供 HTTP 基础认证。

  311. 基础认证提供的用户名和密码是没有加密的。

  312. func (*Request) UserAgent

  313. func (r *Request) UserAgent() string
  314.  
  315. 如果请求发送了 User-Agent 头信息,UserAgent 会返回它。

  316. func (*Request) WithContext

  317. func (r *Request) WithContext(ctx context.Context) *Request
  318.  
  319. WithContext 返回一个浅拷贝的 context 来替换 ctxctx 不能是 nil

  320. func (*Request) Write

  321. func (r *Request) Write(w io.Writer) error
  322.  
  323. Write 以线性格式将 HTTP/1.1 请求头和请求体写入 w,这个方法会访问以下字段:

  324. Host
  325. URL
  326. Method (defaults to "GET")
  327. Header
  328. ContentLength
  329. TransferEncoding
  330. Body
  331. 如果 Body 存在,Content-Length 小于 0 并且 TransferEncoding 没有设置成 identityWrite 会把 Transfer-Encoding: chunked 写入请求头。Body 会在请求发送完成后关闭。

  332. func (*Request) WriteProxy

  333. func (r *Request) WriteProxy(w io.Writer) error
  334.  
  335. WriteProxy Write 相似只是以 HTTP 代理的格式写入。特指:WriteProxy 会根据 RFC 2616 5.1.2 章把绝对路径的 URI、协议和主机写入 Request-URI 行。WriteProxy 还会将 r.Host r.URL.Host 的值写入 Host 头信息。

  336. type Response

  337. type Response struct {
  338.     Status     string // e.g. "200 OK"
  339.     StatusCode int    // e.g. 200
  340.     Proto      string // e.g. "HTTP/1.0"
  341.     ProtoMajor int    // e.g. 1
  342.     ProtoMinor int    // e.g. 0
  343.     // Header 保存响应头的键值对信息。如果响应头包含多个相同的键,会把他们用分号分割(RFC 2616 第 4.2 章需要把多个相同头部看作一个分号序列)。
  344.     // 响应头的值复制到这个结构的其他字段(例如:ContentLength,TransferEncoding,Trailer)。
  345.     //
  346.     // 响应头的中的键都是规范化的 (请看 CanonicalHeaderKey).
  347.     Header Header
  348.     // Body 代表响应体。
  349.     //
  350.     // 响应体可以从 Body 属性按需读取。如果网络链接断开或者服务器关闭了响应,Body.Read 会返回错误。
  351.     //
  352.     // Client 和 Transport 确保 Body 即使在没有响应体或者响应长度为 0 的时候也不为 nil。由调用者负责关闭它。
  353.     // 如果 Body 读取完成后没有关闭,默认的 HTTP 客户端的 Transport 不会企图重用 HTTP/1.0 或 HTTP/1.1 的 TCP 链接。
  354.     //
  355.     // 如果服务器响应头中包含 Transfer-Encoding 且为 chunked,Body 会自动的分段传输。
  356.     Body io.ReadCloser
  357.      // ContentLength 记录对应响应内容的长度,-1 表示响应内容长度未知。如果在响应头中设置它大于 0,代表可以在 Body 中最多读取 ContentLength 个字节的数据。
  358.     ContentLength int64
  359.      // 包含请求体从外到内的传输编码。如果为 nil,说明未编码。
  360.     TransferEncoding []string
  361.     // Close 记录响应头指向的链接在读取 Body后是否关闭。
  362.     // 这个值只是给客户端作为参考:ReadResponse 和 Response.Write 都会关闭链接。
  363.     Close bool
  364.     // Uncompressed 是否需要 http 解压已经被压缩的数据。如果为 true,会从 Body 中读取数据并解压缩内容而不是直接返回在服务端压缩过的数据,ContentLength 会置为 -1,Content-Length 和 Content-Encoding 字段会从 responseHeader 中删除。如果想获取服务器原本的响应数据,需要把 Transport.DisableCompression 置为 true。
  365.     Uncompressed bool
  366.     // Trailer 保存的键值对格式与响应头相同。
  367.     //
  368.     // Trailer 最初由服务器指定的 `Trailer` 头的键都为 nil。它们不会在添加在响应头中。
  369.     //
  370.     // 不能在读取响应的时候访问 Trailer。
  371.     //
  372.     // 当响应体返回 io.EOF 时,Trailer 才会获取到服务器发送的值。
  373.     Trailer Header
  374.     // Request 代表获取到该响应的请求。
  375.     // Request 的 Body 为 nil (因为已经被消费)。
  376.     // 它只会在客户端请求中才会有值。
  377.     Request *Request
  378.     // TLS 包含响应收到的 TLS 链接信息。对于非加密链接它为 nil。
  379.     // 这个指针对应的值是响应之间共享的所以不能改变它。
  380.     TLS *tls.ConnectionState
  381. }
  382.  
  383. Response 表示来自 HTTP 请求的响应。

  384. 一旦收到响应头,Client Transport 就会从服务器返回 Response。响应体在读取 Body 字段时按需传输。

  385. func Get

  386. func Get(url string) (resp *Response, err error)
  387.  
  388. Get 向指定 URL 发起 Get 请求。如果响应的状态码是下面几种重定向状态码,Get 会自动进行最多 10 次的重定向:

  389. 301 (Moved Permanently)
  390. 302 (Found)
  391. 303 (See Other)
  392. 307 (Temporary Redirect)
  393. 308 (Permanent Redirect)
  394. 如果有太多的重定向或者发生 HTTP 协议错误会返回错误。一个非 2xx 的响应不会导致错误。

  395. err nilresp Body 一定不是 nil。用户应该是读取之后关闭 resp.Body

  396. Get DefaultClient.Get 的封装。

  397. 如果想自定义请求头,可以使用 NewRequest DefaultClient.Do


  398. 例:

  399. res, err := http.Get("http://www.google.com/robots.txt")
  400. if err != nil {
  401.     log.Fatal(err)
  402. }
  403. robots, err := ioutil.ReadAll(res.Body)
  404. res.Body.Close()
  405. if err != nil {
  406.     log.Fatal(err)
  407. }
  408. fmt.Printf("%s", robots)
  409. func Head(url string) (resp *Response, err error)
  410.  
  411. Head 向指定 URL 发起 HEAD 请求。如果响应的状态码是下面几种重定向状态码,Get 会自动进行最多 10 次的重定向:

  412. 301 (Moved Permanently)
  413. 302 (Found)
  414. 303 (See Other)
  415. 307 (Temporary Redirect)
  416. 308 (Permanent Redirect)
  417. Head DefaultClient.Head 的封装。

  418. func Post

  419. func Post(url string, contentType string, body io.Reader) (resp *Response, err error)
  420.  
  421. Post 向指定 URL 发起 POST 请求。

  422. 用户应该在读取完 resp.Body 后关闭它。

  423. 如果 Body 是一个 io.Closer 接口实现。它会在请求结束后关闭。

  424. Post DefaultClient.Post 的封装。

  425. 如果想自定义请求头,可以使用 NewRequest DefaultClient.Do

  426. 关于更多关于重定向的处理请看 Client.Do 文档。

  427. func PostForm

  428. func PostForm(url string, data url.Values) (resp *Response, err error)
  429.  
  430. PostForm 向指定 URL 发起 POST 请求,他会在请求体附带 URL 编码过的键值对。

  431. Content-Type 头会被设置为 application/x-www-form-urlencoded。如果想设置其他请求头,可以使用 NewRequest DefaultClient.Do

  432. err nilresp 总是包含一个非 nil Body。用户应该在读取完 resp.Body 后关闭它。

  433. PostForm DefaultClient.PostForm 的封装。

  434. 关于更多关于重定向的处理请看 Client.Do 文档。

  435. func ReadResponse

  436. func ReadResponse(r *bufio.Reader, req *Request) (*Response, error)
  437.  
  438. ReadResponse r 中读取并返回 HTTP 响应。req 可以选择指定响应对应的参数。如果为 nil ,假设它是一个 GET 请求。用户必须在读取完 resp.Body 后关闭它。在这之后客户端可以在 resp.Trailer 中获取 trailer

  439. func (*Response) Cookies

  440. func (r *Response) Cookies() []*Cookie
  441.  
  442. Cookies 解析并返回 Set-Cookie 头中的 cookie

  443. func (*Response) Location

  444. func (r *Response) Location() (*url.URL, error)
  445.  
  446. 响应头中如果存在 LocationLocation函数返回它对应的 URL。如果是相对路径会选择响应对应的请求作为参考。如果没有 Location 头信息会返回 ErrNoLocation 错误。

  447. func (*Response) ProtoAtLeast

  448. func (r *Response) ProtoAtLeast(major, minor int) bool
  449.  
  450. ProtoAtLeast 判断在响应中的 HTTP 协议至少为 major.minor

  451. func (*Response) Write

  452. func (r *Response) Write(w io.Writer) error
  453.  
  454. Write HTTP/1.x 服务器响应格式将 r 写入 w。包括状态行,头部,数据体和 trailer(可选)。

  455. 这个方法将会访问 r 的以下属性:

  456. StatusCode
  457. ProtoMajor
  458. ProtoMinor
  459. Request.Method
  460. TransferEncoding
  461. Trailer
  462. Body
  463. ContentLength
  464. Header, values for non-canonical keys will have unpredictable behavior
  465. Response Body 会在发送后关闭。

  466. type ResponseWriter

  467. type ResponseWriter interface {
  468.     // Header 返回通过 WriteHeader 发送的头信息 map。这个机制也能用来设置 HTTP trailer。
  469.     //
  470.     // 在调用 WriteHeader 后再修改头信息 map 不会影响响应的头信息,除非它是 trailer。
  471.     //
  472.     // 有两种方式来设置 Trailer。推荐的方式是在头信息中预先声明你要返回的 trailers 键名。这些键会被处理成 trailer。第二种方式在第一次写入 trailer 前都不知道 trailer 的键信息,它为 trailer 信息设置一个常量值的前缀 TrailerPrefix。
  473.     //
  474.     // 如果不想使用隐式的头部(例如:Date),可以把他的值设为 nil。
  475.     Header() Header
  476.     // Write 会把 HTTP 的响应写入链接。
  477.     //
  478.     // 如果没有调用过 WriteHeader,Write 会在写入数据前调用 WriteHeader(http.StatusOK)。如果响应头中没有 Content-Type 信息,会把写入数据的前 512 字节传入 DetectContentType 并把结果作为 Content-Type 的值。
  479.     //
  480.     // 根据 HTTP 协议的版本和客户端,调用 Write 可能会阻止再次读取 Request.Body。对于 HTTP/1.x 请求,处理函数需要在写入请求前读取请求体数据。一旦头部被刷新(用于显式调用 Flusher.Flush 或写入的数据触发了刷新),请求体就会无效。而对于 HTTP/2 请求,Go 的 HTTP 服务器允许处理函数读取请求的同时写入响应。但是这种行为不是所有的 HTTP/2 客户端都支持。如果可能,处理函数应该在写入前完成读取请求以保证最大的兼容性。
  481.     Write([]byte) (int, error)
  482.     // WriteHeader 发送状态码和响应头。如果 WriteHeader 没有被显式调用,那么第一次调用 Write 时会隐式触发 WriteHeader(http.StatusOK)。因此它主要用于返回错误状态码的情况。
  483.     //
  484.     // 状态码必须是有效的 HTTP 1xx-5xx 状态码。只可以写入一回头部。Go 目前不支持发送用户自定义的 1xx 信息头,除了 100-continue 会在请求体被读取的时候自动发送。
  485.     WriteHeader(statusCode int)
  486. }
  487.  
  488. HTTP 处理函数使用 ResponseWriter 接口初始化 HTTP 响应。

  489. ResponseWriter 不能在 Handler.ServeHTTP 方法返回后使用。


  490. 例:

  491. mux := http.NewServeMux()
  492. mux.HandleFunc("/sendstrailers", func(w http.ResponseWriter, req *http.Request) {
  493.     //在调用 WriteHeader 或 Write 之前,声明你之后将要发送的 trailer。
  494.     //这三个头其实会送入 trailer。
  495.     w.Header().Set("Trailer", "AtEnd1, AtEnd2")
  496.     w.Header().Add("Trailer", "AtEnd3")
  497.     w.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
  498.     w.WriteHeader(http.StatusOK)
  499.     w.Header().Set("AtEnd1", "value 1")
  500.     io.WriteString(w, "This HTTP response has both headers before this text and trailers at the end.\n")
  501.     w.Header().Set("AtEnd2", "value 2")
  502.     w.Header().Set("AtEnd3", "value 3") // These will appear as trailers.
  503. })
  504. type RoundTripper

  505. type RoundTripper interface {
  506.     // RoundTrip 执行一个单独的 HTTP 事务,并响应指定请求。
  507.     //
  508.     // RoundTrip 不应该企图中断响应。尤其是在它获取到了一个响应时,必须返回 err == nil,不管 HTTP 状态码是什么。
  509.     // 一个非 nil 错误应该当作获取响应失败处理。相似的,RoundTrip 不应该获取高级的协议信息例如重定向,身份验证或 cookie。
  510.     //
  511.     // RoundTrip 不能改变请求,除了读取和关闭请求体。
  512.     // been closed.
  513.     //
  514.     // RoundTrip 必须关闭请求体,包括发生错误的时候,不过可以根据实现在不同的 goroutine 中关闭,甚至是在 RoundTrip 返回以后。这意味着调用者如果想要让接下来的请求复用请求体必须等到 Close 函数调用以后。
  515.     //
  516.     // 必须初始化请求的 URL 和 Header 字段。
  517.     RoundTrip(*Request) (*Response, error)
  518. }
  519.  
  520. RoundTripper 接口代表执行 HTTP 单个事务,根据请求取得响应的能力。

  521. RoundTripper 实现必须能够安全的被多个 goroutine 同时使用。

  522. var DefaultTransport RoundTripper = &Transport{
  523.     Proxy: ProxyFromEnvironment,
  524.     DialContext: (&net.Dialer{
  525.         Timeout:   30 * time.Second,
  526.         KeepAlive: 30 * time.Second,
  527.         DualStack: true,
  528.     }).DialContext,
  529.     MaxIdleConns:          100,
  530.     IdleConnTimeout:       90 * time.Second,
  531.     TLSHandshakeTimeout:   10 * time.Second,
  532.     ExpectContinueTimeout: 1 * time.Second,
  533. }
  534.  
  535. DefaultTransport Transport 的默认实现,DefaultClient 使用它。它按需建立网络连接并且缓存它们来在随后的请求中复用。它会使用环境变量中的 HTTP_PROXY NO_PROXY (或 http_proxy no_proxy)作为 HTTP 代理。

  536. func NewFileTransport

  537. func NewFileTransport(fs FileSystem) RoundTripper
  538.  
  539. NewFileTransport 返回一个新的 RoundTripper,他服务于文件系统。RoundTripper 的返回值忽略 URL 的主机参数。

  540. 一个使用 NewFileTransport 的例子就是注册 file 协议的 Transport

  541. t := &http.Transport{}
  542. t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
  543. c := &http.Client{Transport: t}
  544. res, err := c.Get("file:///etc/passwd")
  545. ...
  546. type ServeMux

  547. type ServeMux struct {
  548.     // contains filtered or unexported fields
  549. }
  550.  
  551. ServeMux 是一个 HTTP 请求多路复用器。他根据已经注册的 pattern 匹配每个请求的 URL 并调用最匹配的处理函数。

  552. Patterns 名称固定为绝对路径(例如 /favicon.ico),或者以下划线结尾(例如 /images/)。

  553. patterns 的优先级高于短 patterns。所以如果注册了 2 patterns /images/ /images/thumbnails/

  554. 第二个的处理函数将会处理 /images/thumbnails/ 而前者会接收其他在 /images/ 子树下的请求。

  555. 注意:因为以斜线结尾的 pattern 被命名为一个子树,pattern / 会匹配所有其他 pattern 没有匹配的请求,不仅仅是 /。

  556. 如果一个子树已经注册并且一个请求访问了这个子树路径但没有以斜线结尾,ServeMux 会自动重定向到子树根节点(添加结尾的下划线)。这个行为可以通过注册一个不以斜线结尾的 pattern 覆盖。例如:注册 /images/ 导致 ServeMux 重定向 /images /images/,除非已经注册 /images

  557. Patterns 可以选择以主机名称开头来严格匹配 URL。指定主机的 patterns 的优先级高于普通 patterns,所以注册 /codesearch codesearch.google.com/ 的处理函数不会对 http://www.google.com/ 请求做出响应。

  558. ServeMux 也关心 URL 路径的形式。他会自动过滤 . .. 和多余的斜线。

  559. func NewServeMux

  560. func NewServeMux() *ServeMux
  561.  
  562. NewServeMux 创建并返回一个新的 ServeMux

  563. func (*ServeMux) Handle

  564. func (mux *ServeMux) Handle(pattern string, handler Handler)
  565.  
  566. Handle 注册指定 pattern 的处理函数。如果给定的 pattern 已经拥有处理函数将会 panic


  567. 例:

  568. mux := http.NewServeMux()
  569. mux.Handle("/api/", apiHandler{})
  570. mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
  571.     // "/" 会匹配所有请求,所以我们要确保我们在 root 下。
  572.     if req.URL.Path != "/" {
  573.         http.NotFound(w, req)
  574.         return
  575.     }
  576.     fmt.Fprintf(w, "Welcome to the home page!")
  577. })
  578. func (*ServeMux) HandleFunc

  579. func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))
  580.  
  581. HandleFunc 注册指定 pattern 的处理函数。

  582. func (*ServeMux) Handler

  583. func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)
  584.  
  585. Handler 根据 r.Methodr.Host r.URL.Path 返回请求所用的处理函数,它总是返回非 nil 的处理函数。如果不存在这个路径。处理函数会是一个内部产生的重定向到指定页面的处理函数。如果主机包含端口,会在匹配的时候忽略。

  586. 对于 CONNECT 请求路径和主机名的使用没有变化。

  587. 处理函数也返回匹配到的路径,如果是一个内部生成的重定向路径会返回重定向页面的路径。

  588. 如果请求没有匹配到处理函数。处理函数会是 page not found 处理函数和一个空 parttern

  589. func (*ServeMux) ServeHTTP

  590. func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)
  591.  
  592. ServeHTTP 将请求分发到它最匹配的 pattern 对应的处理函数上。

  593. type Server

  594. type Server struct {
  595.     Addr    string  // TCP 的监听地址, 如果为空使用 ":http"
  596.     Handler Handler // 调用的处理函数, 如果为 nil 使用 http.DefaultServeMux
  597.     // 可选的 TLS 配置,  ServeTLS 和 ListenAndServeTLS 使用。
  598.     // 它的值会被 ServeTLS 和 ListenAndServeTLS 拷贝,所以不能使用像 tls.Config.SetSessionTicketKeys 修改它的配置信息。如果需要使用 SetSessionTicketKeys,可以在 TLS 监听器上使用 Server.Serve。
  599.     TLSConfig *tls.Config
  600.     // ReadTimeout 读取的请求实体的最大时间,包括请求体。
  601.     //
  602.     // 因为 ReadTimeout 不能让处理函数自己决定每个请求体的有效时间和上传频率,所以大多数人更推荐使用 ReadHeaderTimeout。它们两个是可以一起使用的。
  603.     ReadTimeout time.Duration
  604.     // ReadHeaderTimeout 是允许读取请求头的时间。链接的读取时限会在读取头部信息后重置。处理函数可以慢慢考虑如何使用请求体。
  605.     ReadHeaderTimeout time.Duration
  606.     // WriteTimeout 是写入响应的超时时间。它会在读取到新请求的请求头时重置。和 ReadTimeout 一样,它不能让处理函数决定写入请求体的时间。
  607.     WriteTimeout time.Duration
  608.     //IdleTimeout 是在 keep-alives 开启时保持连接状态等待下次请求的最大时间。如果 IdleTimeout 为 0,会使用 ReadTimeout 的值。如果它们都是 0,会使用 ReadHeaderTimeout。
  609.     IdleTimeout time.Duration
  610.     // MaxHeaderBytes 控制服务器从请求头中读取的键值对的最大字节数(包括请求行)。它不会限制请求体的大小。
  611.     // 如果值为 0,会使用 DefaultMaxHeaderBytes。
  612.     // 
  613.     MaxHeaderBytes int
  614.     // TLSNextProto 可选的在发生 NPN/ALPN 协议升级的时候指定一个函数来接管 TLS 链接的所有权。
  615.     // map 的键是协议名。处理函数的参数用来处理 HTTP 请求并且会在没有设置的时候生成请求的 TLS 和 RemoteAddr。链接会在函数返回的时候自动关闭。
  616.     // 如果 TLSNextProto 不为 nil, 不会自动启用对 HTTP/2 的支持。
  617.     TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
  618.     // ConnState 可选的指定一个函数,它会在哭护短连接状态改变的时候调用。ConnState 类型文档会具体说明。
  619.     ConnState func(net.Conn, ConnState)
  620.     // ErrorLog 一个 logger 用来接收链接的错误,未定义处理器行为和底层文件系统错误。
  621.     // 如果为 nil,日志会通过 log 包输出错误信息到 os.Stderr。
  622.     ErrorLog *log.Logger
  623.     // contains filtered or unexported fields
  624. }
  625.  
  626. Server 定义了 HTTP 服务器运行时的参数。零值的 Server 是一个有效的配置。

  627. func (*Server) Close

  628. func (srv *Server) Close() error
  629.  
  630. Close 会立即关闭所有正在监听的 net.Listener 或任何状态为 StateNewStateActive StateIdle 的链接。如果想优雅的关闭,请使用 Shutdown

  631. Close 不会关闭被劫持的链接,例如 WebSocket

  632. Close 返回在关闭底层监听时的任何错误。

  633. func (*Server) ListenAndServe

  634. func (srv *Server) ListenAndServe() error
  635.  
  636. ListenAndServe 监听一个 TCP 地址 srv.Addr 并调用请求处理函数来处理来自 TLS 链接的请求。接收到的链接会启用 TCP keep-alives。如果 srv.Addr 为空, 会使用 “:http”。ListenAndServe 总是返回一个非 nil 错误。

  637. func (*Server) ListenAndServeTLS

  638. func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error
  639.  
  640. ListenAndServeTLS 监听一个 TCP 地址 srv.Addr 并且点用请求处理函数来处理 TLS 链接。接收到的链接会被启用 TCP keep-alive

  641. 如果 TLSConfig.Certificates TLSConfig.GetCertificate 都没有被填充那么必须提供包含服务器的证书和对应私钥的文件名。如果证书是被证书颁发机构签名,certFile 应该是服务器证书、中间器和 CA 证书串。

  642. 如果 srv.Addr 为空,使用 :https

  643. ListenAndServeTLS r 一直返回非 nil 错误。

  644. func (*Server) RegisterOnShutdown

  645. func (srv *Server) RegisterOnShutdown(f func())
  646.  
  647. RegisterOnShutdown 注册一个在服务器关闭时执行的函数。它对于关闭那些接受 NPN/ALPN 协议升级或已经被劫持的链接非常有用。这个函数应该根据协议关闭链接,但不等待关闭完成。

  648. func (*Server) Serve

  649. func (srv *Server) Serve(l net.Listener) error
  650.  
  651. Serve l 中接受链接。并为每个链接创建一个新的 goroutinegoroutine 会读取请求然后调用 srv.Handler 进行响应。

  652. 为了支持 HTTP/2 在调用 Serve 之前 srv.TLSConfig 应该根据 TLS 配置初始化。如果 srv.TLSConfig 非空并且在 Config.NextProtos 中不包含 h2”,说明不支持 HTTP/2

  653. Serve 总是返回一个非 nil 错误。在 Close 或者 Shutdown 之后,返回 ErrServerClosed 错误。

  654. func (*Server) ServeTLS

  655. func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error
  656.  
  657. ServeTLS l 中接受请求链接。并为每个链接创建一个新的 goroutinegoroutine 会读取请求然后调用 srv.Handler 进行响应。

  658. 如果 TLSConfig.Certificates TLSConfig.GetCertificate 都没有被填充那么必须提供包含服务器的证书和对应私钥的文件名。如果证书是被证书颁发机构签名的,certFile 应该是服务器证书、中间证书和 CA 证书组成的串。

  659. 为了支持 HTTP/2 在调用 Serve 之前 srv.TLSConfig 应该根据 TLS 配置初始化。如果 srv.TLSConfig 非空并且在 Config.NextProtos 中不包含 h2”,说明不支持 HTTP/2

  660. ServeTLS 总是返回一个非 nil 错误。在 Close 或者 Shutdown 之后,返回 ErrServerClosed 错误。

  661. func (*Server) SetKeepAlivesEnabled

  662. func (srv *Server) SetKeepAlivesEnabled(v bool)
  663.  
  664. SetKeepAlivesEnabled 控制 HTTP keep-alives 是否开启。keep-alives 默认是开启的。只有一些资源限制严重或者服务器正在关闭才会禁用它。

  665. func (*Server) Shutdown

  666. func (srv *Server) Shutdown(ctx context.Context) error
  667.  
  668. Shutdown 不会立即关闭还在活跃的链接。Shutdown 先关闭所有的监听端口,然后关闭空闲的链接,然后等待活跃的链接变成空闲链接然后关闭它。如果 context 在关闭之前过期,Shutdown 会返回 context 的错误。否则返回关闭服务器监听端口发生的错误。

  669. 一旦调用 ShutdownServeListenAndServe ListenAndServeTLS 会立即返回 ErrServerClosed。确保程序不会退出等待 Shutdown 执行完成。

  670. Shutdown 不会企图关闭或等待劫持链接例如 WebSocketsShutdown 的调用者应该分别通知这些长链接关闭并等待它们关闭完成。


  671. 例:

  672. var srv http.Server
  673. idleConnsClosed := make(chan struct{})
  674. go func() {
  675.     sigint := make(chan os.Signal, 1)
  676.     signal.Notify(sigint, os.Interrupt)
  677.     <-sigint
  678.     // We received an interrupt signal, shut down.
  679.     if err := srv.Shutdown(context.Background()); err != nil {
  680.         // Error from closing listeners, or context timeout:
  681.         log.Printf("HTTP server Shutdown: %v", err)
  682.     }
  683.     close(idleConnsClosed)
  684. }()
  685. if err := srv.ListenAndServe(); err != http.ErrServerClosed {
  686.     // Error starting or closing listener:
  687.     log.Printf("HTTP server ListenAndServe: %v", err)
  688. }
  689. <-idleConnsClosed
  690. type Transport

  691. type Transport struct {
  692.     // Proxy 是一个返回指定请求代理的函数。如果该函数返回一个非 nil 错误。请求会因为错误中断。
  693.     //
  694.     // 代理的类型由 URL 的协议决定。如果协议部分为空,默认为 http 代理。
  695.     //
  696.     // 如果 Proxy 是 nil 或者返回一个 nil 的 *URL,不会使用代理。
  697.     Proxy func(*Request) (*url.URL, error)
  698.     // DialContext 指定创建非加密链接的函数。
  699.     // 如果 DialContext 为 nil (并且弃用的 Dial 也为 nil), transport 会默认使用 net 包。
  700.     DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
  701.     // Dial 创建非加密链接的函数。
  702.     //
  703.     // 弃用:请使用 DialContext,它允许 transport 在不需要的时候取消链接。
  704.     // 如果都设置了,会优先使用 DialContext。
  705.     Dial func(network, addr string) (net.Conn, error)
  706.     // DialTLS 指定一个可选函数用来为没有代理 HTTPS 的请求创建 TLS 链接。
  707.     //
  708.     // 如果 DialTLS 为 nil,会使用 Dial 和 TLSClientConfig。
  709.     //
  710.     // 如果设置了 DialTLS,HTTPS 请求就不会使用 Dial 并忽略 TLSClientConfig 和 TLSHandshakeTimeout。我们返回的 net.Conn 链接认为已经完成了 TLS 握手。
  711.     DialTLS func(network, addr string) (net.Conn, error)
  712.     // TLSClientConfig 指定 tls.Client 使用的 TLS 协议。
  713.     // 如果为 nil,会使用默认配置。
  714.     // 如果不为 nil,HTTP/2 支持可能默认不是启用状态。
  715.     TLSClientConfig *tls.Config
  716.     // TLSHandshakeTimeout 指定最大等待 TLS 握手的时间。零值代表没有超时时间。
  717.     TLSHandshakeTimeout time.Duration
  718.     // DisableKeepAlives,如果为 true,不同请求不会复用 TCP 链接。
  719.     DisableKeepAlives bool
  720.     // DisableCompression 如果为 true,Transport 即使使用 Accept-Encoding: gzip 请求头也不会压缩请求。 
  721.     // 如果 Transport 自己发送了一个经过 gzip 的请求,并获取到了 gzip 的响应,这显然需要对 Response.Body 进行解码。然而如果用户明确的请求压缩它它并不会自动的压缩。
  722.     DisableCompression bool
  723.     // MaxIdleConns 控制包括所有主机的最大空闲(keep-alive)链接数。0 代表不限制。
  724.     MaxIdleConns int
  725.     // MaxIdleConnsPerHost, 如果不为 0,会控制每个主机的最大空闲(keep-alive) 链接数。如果为零值,会使用 DefaultMaxIdleConnsPerHost。
  726.     MaxIdleConnsPerHost int
  727.     // IdleConnTimeout 是空闲链接在关闭前的最大有效时间。
  728.     // 零值代表不限制。
  729.     IdleConnTimeout time.Duration
  730.     // ResponseHeaderTimeout 如果非零,限制在写入请求成功后等待响应头的时间。
  731.     // 这个时间不包括读取响应体的时间。
  732.     ResponseHeaderTimeout time.Duration
  733.     // ExpectContinueTimeout 代表在请求头中包含 Expect: 100-continue 时,写入请求头后第一次获取响应头的超时时间。零值意味着请求体会被立刻发送而不等待服务器批准。
  734.     // 这个时间不包括发送请求头的时间。
  735.     ExpectContinueTimeout time.Duration
  736.     // TLSNextProto 指定 Transport 在 NPN/ALPN 协议协商以后如何在备用协议间切换。如果 Transport 使用非空协议名发起一个 TLS 链接并且在 TLSNextProto 中包含该协议的键,那么请求根据权限(例如:"example.com" 或者 "example.com:1234")调用这个函数。这个函数必须返回一个 RoundTripper 来处理请求。
  737.     // 如果 TLSNextProto 不为 nil,不会自动启用对 HTTP/2 的支持。
  738.     TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper
  739.     // ProxyConnectHeader 可选的指定发起 CONNECT 请求时的请求头。
  740.     ProxyConnectHeader Header
  741.     // MaxResponseHeaderBytes 限制服务器读取响应头的最大字节数。
  742.     // 零值意味着默认限制。
  743.     MaxResponseHeaderBytes int64
  744.     // contains filtered or unexported fields
  745. }
  746.  
  747. Transport 是一个支持 HTTPHTTPS HTTP 代理(HTTP HTTPS CONNECT)的 RoundTripper 实现。

  748. 默认情况下,Transport 会缓存链接进行复用。这可能导致在访问多个主机的时候导致打开过多的链接。

  749. 这个行为可以通过调用 CloseIdleConnections 方法,设置 MaxIdleConnsPerHost DisableKeepAlives 来改变。

  750. Transports 应该使用重用策略来代替按需创建的策略。Transports 可以安全的被多个 goroutine 同时使用。

  751. Transport 用来创建比较原始的 HTTP HTTPS 请求,对于更加实用的高级功能,例如 cookies 或者重定向,请看 Client

  752. 对于 HTTP URL Transport 使用 HTTP/1.1,对于 HTTPS URL Transport 可以使用 HTTP/1.1 HTTP/2,这依赖服务器是否支持 HTTP/2 Transport 是如何配置的。DefaultTransport 支持 HTTP/2。为了让 transport 显式的启用 HTTP/2,可以使用 golang.org/x/net/http2 并且调用 ConfigureTransport。关于更多的关于 HTTP/2 可以查看包文档。

  753. Transport 会在处理 HTTPS 请求时发送 CONNECT 请求到一个代理来供自己使用,但是 Transport 一般不会发送一个 CONNECT 请求。因此经过 RoundTrip 的请求中不应该有一个叫 CONNECT 的方法,作为 Go HTTP/1.x 实现不支持全双工链接的请求体(可以获取响应的时候发送请求)。Go HTTP/2 实现支持全双工链接,但是一些 CONNET 代理都是 HTTP/1.x

  754. func (*Transport) CancelRequest

  755. func (t *Transport) CancelRequest(req *Request)
  756.  
  757. CancelRequest 会通过关闭链接来取消请求。

  758. CancelRequest 只应该在 RoundTrip 返回以后调用。

  759. 弃用:使用 Request.WithContext 来创建一个带可以取消 context 的请求。CancelRequest 不能取消 HTTP/2 请求。

  760. func (*Transport) CloseIdleConnections

  761. func (t *Transport) CloseIdleConnections()
  762.  
  763. CloseIdleConnections 关闭之前所有请求的链接。不包括 keep-alive 状态的链接。他不会中断任何当前正在用的链接。

  764. func (*Transport) RegisterProtocol

  765. func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper)
  766.  
  767. RegisterProtocol 注册一个新的协议。Transport 将会把请求转发给 rt

  768. RegisterProtocol 可以使用其他包的协议实现例如:”ftp file”。

  769. 如果 rt.RoundTrip 返回 ErrSkipAltProtocolTransport 将会处理 RoundTrip 自己,就像协议没有注册一样。

  770. func (*Transport) RoundTrip

  771. func (t *Transport) RoundTrip(req *Request) (*Response, error)
  772.  
  773. RoundTrip 实现了 RoundTripper 接口。

  774. 对于高级 HTTP 客户端的支持请看 GetPost Client 类型。

  775. Subdirectories