Golang标准库——net(2)

  • http
  • http/cgi
  • http/cookiejar
  • http/fcgi
  • http/httptest
  • http/httptrace
  • http/httputil
  • http/pprof

http

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

Get、Head、Post和PostForm函数发出HTTP/ HTTPS请求。

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"}})

程序在使用完回复后必须关闭回复的主体。

resp, err := http.Get("http://example.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

要管理HTTP客户端的头域、重定向策略和其他设置,创建一个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)
// ...

要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:

tr := &http.Transport{
    TLSClientConfig:    &tls.Config{RootCAs: pool},
    DisableCompression: true,
}
client := &http.Client{Transport: tr}
resp, err := client.Get("https://example.com")

Client和Transport类型都可以安全的被多个go程同时使用。出于效率考虑,应该一次建立、尽量重用。

ListenAndServe使用指定的监听地址和处理器启动一个HTTP服务端。处理器参数通常是nil,这表示采用包变量DefaultServeMux作为处理器。Handle和HandleFunc函数可以向DefaultServeMux添加处理器。

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())
const (
    StatusContinue           = 100
    StatusSwitchingProtocols = 101
    StatusOK                   = 200
    StatusCreated              = 201
    StatusAccepted             = 202
    StatusNonAuthoritativeInfo = 203
    StatusNoContent            = 204
    StatusResetContent         = 205
    StatusPartialContent       = 206
    StatusMultipleChoices   = 300
    StatusMovedPermanently  = 301
    StatusFound             = 302
    StatusSeeOther          = 303
    StatusNotModified       = 304
    StatusUseProxy          = 305
    StatusTemporaryRedirect = 307
    StatusBadRequest                   = 400
    StatusUnauthorized                 = 401
    StatusPaymentRequired              = 402
    StatusForbidden                    = 403
    StatusNotFound                     = 404
    StatusMethodNotAllowed             = 405
    StatusNotAcceptable                = 406
    StatusProxyAuthRequired            = 407
    StatusRequestTimeout               = 408
    StatusConflict                     = 409
    StatusGone                         = 410
    StatusLengthRequired               = 411
    StatusPreconditionFailed           = 412
    StatusRequestEntityTooLarge        = 413
    StatusRequestURITooLong            = 414
    StatusUnsupportedMediaType         = 415
    StatusRequestedRangeNotSatisfiable = 416
    StatusExpectationFailed            = 417
    StatusTeapot                       = 418
    StatusInternalServerError     = 500
    StatusNotImplemented          = 501
    StatusBadGateway              = 502
    StatusServiceUnavailable      = 503
    StatusGatewayTimeout          = 504
    StatusHTTPVersionNotSupported = 505
)

HTTP状态码,参见RFC 2616

const DefaultMaxHeaderBytes = 1 << 20 // 1 MB

DefaultMaxHeaderBytes是HTTP请求的头域最大允许长度。可以通过设置Server.MaxHeaderBytes字段来覆盖。

const DefaultMaxIdleConnsPerHost = 2

DefaultMaxIdleConnsPerHost是Transport的MaxIdleConnsPerHost的默认值。

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

TimeFormat是当解析或生产HTTP头域中的时间时,用与time.Parse或time.Format函数的时间格式。这种格式类似time.RFC1123但强制采用GMT时区。

Variables

var (
    ErrHeaderTooLong        = &ProtocolError{"header too long"}
    ErrShortBody            = &ProtocolError{"entity body too short"}
    ErrNotSupported         = &ProtocolError{"feature not supported"}
    ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
    ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
    ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
    ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
)

HTTP请求的解析错误。

var (
    ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
    ErrBodyNotAllowed  = errors.New("http: request method or response status code does not allow body")
    ErrHijacked        = errors.New("Conn has been hijacked")
    ErrContentLength   = errors.New("Conn.Write wrote more than the declared Content-Length")
)

会被HTTP服务端返回的错误。

var DefaultClient = &Client{}

DefaultClient是用于包函数Get、Head和Post的默认Client。

var DefaultServeMux = NewServeMux()

DefaultServeMux是用于Serve的默认ServeMux。

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

在Resquest或Response的Body字段已经关闭后,试图从中读取时,就会返回ErrBodyReadAfterClose。这个错误一般发生在:HTTP处理器中调用完ResponseWriter 接口的WriteHeader或Write后从请求中读取数据的时候。

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

在处理器超时以后调用ResponseWriter接口的Write方法,就会返回ErrHandlerTimeout。

var ErrLineTooLong = errors.New("header line too long")
var ErrMissingFile = errors.New("http: no such file")

当请求中没有提供给FormFile函数的文件字段名,或者该字段名不是文件字段时,该函数就会返回ErrMissingFile。

var ErrNoCookie = errors.New("http: named cookie not present")
var ErrNoLocation = errors.New("http: no Location header in response")

type ProtocolError

type ProtocolError struct {
    ErrorString string
}

HTTP请求解析错误。

func (*ProtocolError) Error

func (err *ProtocolError) Error() string

func CanonicalHeaderKey

func CanonicalHeaderKey(s string) string

CanonicalHeaderKey函数返回头域(表示为Header类型)的键s的规范化格式。规范化过程中让单词首字母和'-'后的第一个字母大写,其余字母小写。例如,"accept-encoding"规范化为"Accept-Encoding"。

func DetectContentType

func DetectContentType(data []byte) string

DetectContentType函数实现了http://mimesniff.spec.whatwg.org/描述的算法,用于确定数据的Content-Type。函数总是返回一个合法的MIME类型;如果它不能确定数据的类型,将返回"application/octet-stream"。它最多检查数据的前512字节。

func ParseHTTPVersion

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

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

func ParseTime

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

ParseTime用3种格式TimeFormat, time.RFC850和time.ANSIC尝试解析一个时间头的值(如Date: header)。

func StatusText

func StatusText(code int) string

StatusText返回HTTP状态码code对应的文本,如220对应"OK"。如果code是未知的状态码,会返回""。

type ConnState

type ConnState int

ConnState代表一个客户端到服务端的连接的状态。本类型用于可选的Server.ConnState回调函数。

const (
    // StateNew代表一个新的连接,将要立刻发送请求。
    // 连接从这个状态开始,然后转变为StateAlive或StateClosed。
    StateNew ConnState = iota
    // StateActive代表一个已经读取了请求数据1到多个字节的连接。
    // 用于StateAlive的Server.ConnState回调函数在将连接交付给处理器之前被触发,
    // 等到请求被处理完后,Server.ConnState回调函数再次被触发。
    // 在请求被处理后,连接状态改变为StateClosed、StateHijacked或StateIdle。
    StateActive
    // StateIdle代表一个已经处理完了请求、处在闲置状态、等待新请求的连接。
    // 连接状态可以从StateIdle改变为StateActive或StateClosed。
    StateIdle
    // 代表一个被劫持的连接。这是一个终止状态,不会转变为StateClosed。
    StateHijacked
    // StateClosed代表一个关闭的连接。
    // 这是一个终止状态。被劫持的连接不会转变为StateClosed。
    StateClosed
)

func (ConnState) String

func (c ConnState) String() string

type Header

type Header map[string][]string

Header代表HTTP头域的键值对。

func (Header) Get

func (h Header) Get(key string) string

Get返回键对应的第一个值,如果键不存在会返回""。如要获取该键对应的值切片,请直接用规范格式的键访问map。

func (Header) Set

func (h Header) Set(key, value string)

Set添加键值对到h,如键已存在则会用只有新值一个元素的切片取代旧值切片。

func (Header) Add

func (h Header) Add(key, value string)

Add添加键值对到h,如键已存在则会将新的值附加到旧值切片后面。

func (Header) Del

func (h Header) Del(key string)

Del删除键值对。

func (Header) Write

func (h Header) Write(w io.Writer) error

Write以有线格式将头域写入w。

func (Header) WriteSubset

func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error

WriteSubset以有线格式将头域写入w。当exclude不为nil时,如果h的键值对的键在exclude中存在且其对应值为真,该键值对就不会被写入w。

type Cookie

type Cookie struct {
    Name       string
    Value      string
    Path       string
    Domain     string
    Expires    time.Time
    RawExpires string
    // MaxAge=0表示未设置Max-Age属性
    // MaxAge<0表示立刻删除该cookie,等价于"Max-Age: 0"
    // MaxAge>0表示存在Max-Age属性,单位是秒
    MaxAge   int
    Secure   bool
    HttpOnly bool
    Raw      string
    Unparsed []string // 未解析的“属性-值”对的原始文本
}

Cookie代表一个出现在HTTP回复的头域中Set-Cookie头的值里或者HTTP请求的头域中Cookie头的值里的HTTP cookie。

func (*Cookie) String

func (c *Cookie) String() string

String返回该cookie的序列化结果。如果只设置了Name和Value字段,序列化结果可用于HTTP请求的Cookie头或者HTTP回复的Set-Cookie头;如果设置了其他字段,序列化结果只能用于HTTP回复的Set-Cookie头。

type CookieJar

type CookieJar interface {
    // SetCookies管理从u的回复中收到的cookie
    // 根据其策略和实现,它可以选择是否存储cookie
    SetCookies(u *url.URL, cookies []*Cookie)
    // Cookies返回发送请求到u时应使用的cookie
    // 本方法有责任遵守RFC 6265规定的标准cookie限制
    Cookies(u *url.URL) []*Cookie
}

CookieJar管理cookie的存储和在HTTP请求中的使用。CookieJar的实现必须能安全的被多个go程同时使用。

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

type Request

type Request struct {
    // Method指定HTTP方法(GET、POST、PUT等)。对客户端,""代表GET。
    Method string
    // URL在服务端表示被请求的URI,在客户端表示要访问的URL。
    //
    // 在服务端,URL字段是解析请求行的URI(保存在RequestURI字段)得到的,
    // 对大多数请求来说,除了Path和RawQuery之外的字段都是空字符串。
    // (参见RFC 2616, Section 5.1.2)
    //
    // 在客户端,URL的Host字段指定了要连接的服务器,
    // 而Request的Host字段(可选地)指定要发送的HTTP请求的Host头的值。
    URL *url.URL
    // 接收到的请求的协议版本。本包生产的Request总是使用HTTP/1.1
    Proto      string // "HTTP/1.0"
    ProtoMajor int    // 1
    ProtoMinor int    // 0
    // Header字段用来表示HTTP请求的头域。如果头域(多行键值对格式)为:
    //  accept-encoding: gzip, deflate
    //  Accept-Language: en-us
    //  Connection: keep-alive
    // 则:
    //  Header = map[string][]string{
    //      "Accept-Encoding": {"gzip, deflate"},
    //      "Accept-Language": {"en-us"},
    //      "Connection": {"keep-alive"},
    //  }
    // HTTP规定头域的键名(头名)是大小写敏感的,请求的解析器通过规范化头域的键名来实现这点。
    // 在客户端的请求,可能会被自动添加或重写Header中的特定的头,参见Request.Write方法。
    Header Header
    // Body是请求的主体。
    //
    // 在客户端,如果Body是nil表示该请求没有主体买入GET请求。
    // Client的Transport字段会负责调用Body的Close方法。
    //
    // 在服务端,Body字段总是非nil的;但在没有主体时,读取Body会立刻返回EOF。
    // Server会关闭请求的主体,ServeHTTP处理器不需要关闭Body字段。
    Body io.ReadCloser
    // ContentLength记录相关内容的长度。
    // 如果为-1,表示长度未知,如果>=0,表示可以从Body字段读取ContentLength字节数据。
    // 在客户端,如果Body非nil而该字段为0,表示不知道Body的长度。
    ContentLength int64
    // TransferEncoding按从最外到最里的顺序列出传输编码,空切片表示"identity"编码。
    // 本字段一般会被忽略。当发送或接受请求时,会自动添加或移除"chunked"传输编码。
    TransferEncoding []string
    // Close在服务端指定是否在回复请求后关闭连接,在客户端指定是否在发送请求后关闭连接。
    Close bool
    // 在服务端,Host指定URL会在其上寻找资源的主机。
    // 根据RFC 2616,该值可以是Host头的值,或者URL自身提供的主机名。
    // Host的格式可以是"host:port"。
    //
    // 在客户端,请求的Host字段(可选地)用来重写请求的Host头。
    // 如过该字段为"",Request.Write方法会使用URL字段的Host。
    Host string
    // Form是解析好的表单数据,包括URL字段的query参数和POST或PUT的表单数据。
    // 本字段只有在调用ParseForm后才有效。在客户端,会忽略请求中的本字段而使用Body替代。
    Form url.Values
    // PostForm是解析好的POST或PUT的表单数据。
    // 本字段只有在调用ParseForm后才有效。在客户端,会忽略请求中的本字段而使用Body替代。
    PostForm url.Values
    // MultipartForm是解析好的多部件表单,包括上传的文件。
    // 本字段只有在调用ParseMultipartForm后才有效。
    // 在客户端,会忽略请求中的本字段而使用Body替代。
    MultipartForm *multipart.Form
    // Trailer指定了会在请求主体之后发送的额外的头域。
    //
    // 在服务端,Trailer字段必须初始化为只有trailer键,所有键都对应nil值。
    // (客户端会声明哪些trailer会发送)
    // 在处理器从Body读取时,不能使用本字段。
    // 在从Body的读取返回EOF后,Trailer字段会被更新完毕并包含非nil的值。
    // (如果客户端发送了这些键值对),此时才可以访问本字段。
    //
    // 在客户端,Trail必须初始化为一个包含将要发送的键值对的映射。(值可以是nil或其终值)
    // ContentLength字段必须是0或-1,以启用"chunked"传输编码发送请求。
    // 在开始发送请求后,Trailer可以在读取请求主体期间被修改,
    // 一旦请求主体返回EOF,调用者就不可再修改Trailer。
    //
    // 很少有HTTP客户端、服务端或代理支持HTTP trailer。
    Trailer Header
    // RemoteAddr允许HTTP服务器和其他软件记录该请求的来源地址,一般用于日志。
    // 本字段不是ReadRequest函数填写的,也没有定义格式。
    // 本包的HTTP服务器会在调用处理器之前设置RemoteAddr为"IP:port"格式的地址。
    // 客户端会忽略请求中的RemoteAddr字段。
    RemoteAddr string
    // RequestURI是被客户端发送到服务端的请求的请求行中未修改的请求URI
    // (参见RFC 2616, Section 5.1)
    // 一般应使用URI字段,在客户端设置请求的本字段会导致错误。
    RequestURI string
    // TLS字段允许HTTP服务器和其他软件记录接收到该请求的TLS连接的信息
    // 本字段不是ReadRequest函数填写的。
    // 对启用了TLS的连接,本包的HTTP服务器会在调用处理器之前设置TLS字段,否则将设TLS为nil。
    // 客户端会忽略请求中的TLS字段。
    TLS *tls.ConnectionState
}

Request类型代表一个服务端接受到的或者客户端发送出去的HTTP请求。

Request各字段的意义和用途在服务端和客户端是不同的。除了字段本身上方文档,还可参见Request.Write方法和RoundTripper接口的文档。

func NewRequest

func NewRequest(method, urlStr string, body io.Reader) (*Request, error)

NewRequest使用指定的方法、网址和可选的主题创建并返回一个新的*Request。

如果body参数实现了io.Closer接口,Request返回值的Body 字段会被设置为body,并会被Client类型的Do、Post和PostFOrm方法以及Transport.RoundTrip方法关闭。

func ReadRequest

func ReadRequest(b *bufio.Reader) (req *Request, err error)

ReadRequest从b读取并解析出一个HTTP请求。(本函数主要用在服务端从下层获取请求)

func (*Request) ProtoAtLeast

func (r *Request) ProtoAtLeast(major, minor int) bool

ProtoAtLeast报告该请求使用的HTTP协议版本至少是major.minor。

func (*Request) UserAgent

func (r *Request) UserAgent() string

UserAgent返回请求中的客户端用户代理信息(请求的User-Agent头)。

func (*Request) Referer

func (r *Request) Referer() string

Referer返回请求中的访问来路信息。(请求的Referer头)

Referer在请求中就是拼错了的,这是HTTP早期就有的错误。该值也可以从用Header["Referer"]获取; 让获取Referer字段变成方法的好处是,编译器可以诊断使用正确单词拼法的req.Referrer()的程序,但却不能诊断使用Header["Referrer"]的程序。

func (*Request) AddCookie

func (r *Request) AddCookie(c *Cookie)

AddCookie向请求中添加一个cookie。按照RFC 6265 section 5.4的跪地,AddCookie不会添加超过一个Cookie头字段。这表示所有的cookie都写在同一行,用分号分隔(cookie内部用逗号分隔属性)。

func (*Request) SetBasicAuth

func (r *Request) SetBasicAuth(username, password string)

SetBasicAuth使用提供的用户名和密码,采用HTTP基本认证,设置请求的Authorization头。HTTP基本认证会明码传送用户名和密码。

func (*Request) Write

func (r *Request) Write(w io.Writer) error

Write方法以有线格式将HTTP/1.1请求写入w(用于将请求写入下层TCPConn等)。本方法会考虑请求的如下字段:

Host
URL
Method (defaults to "GET")
Header
ContentLength
TransferEncoding
Body

如果存在Body,ContentLength字段<= 0且TransferEncoding字段未显式设置为["identity"],Write方法会显式添加"Transfer-Encoding: chunked"到请求的头域。Body字段会在发送完请求后关闭。

func (*Request) WriteProxy

func (r *Request) WriteProxy(w io.Writer) error

WriteProxy类似Write但会将请求以HTTP代理期望的格式发送。

尤其是,按照RFC 2616 Section 5.1.2,WriteProxy会使用绝对URI(包括协议和主机名)来初始化请求的第1行(Request-URI行)。无论何种情况,WriteProxy都会使用r.Host或r.URL.Host设置Host头。

func (*Request) Cookies

func (r *Request) Cookies() []*Cookie

Cookies解析并返回该请求的Cookie头设置的cookie。

func (*Request) Cookie

func (r *Request) Cookie(name string) (*Cookie, error)

Cookie返回请求中名为name的cookie,如果未找到该cookie会返回nil, ErrNoCookie。

func (*Request) ParseForm

func (r *Request) ParseForm() error

ParseForm解析URL中的查询字符串,并将解析结果更新到r.Form字段。

对于POST或PUT请求,ParseForm还会将body当作表单解析,并将结果既更新到r.PostForm也更新到r.Form。解析结果中,POST或PUT请求主体要优先于URL查询字符串(同名变量,主体的值在查询字符串的值前面)。

如果请求的主体的大小没有被MaxBytesReader函数设定限制,其大小默认限制为开头10MB。

ParseMultipartForm会自动调用ParseForm。重复调用本方法是无意义的。

func (*Request) ParseMultipartForm

func (r *Request) ParseMultipartForm(maxMemory int64) error

ParseMultipartForm将请求的主体作为multipart/form-data解析。请求的整个主体都会被解析,得到的文件记录最多maxMemery字节保存在内存,其余部分保存在硬盘的temp文件里。如果必要,ParseMultipartForm会自行调用ParseForm。重复调用本方法是无意义的。

func (*Request) FormValue

func (r *Request) FormValue(key string) string

FormValue返回key为键查询r.Form字段得到结果[]string切片的第一个值。POST和PUT主体中的同名参数优先于URL查询字符串。如果必要,本函数会隐式调用ParseMultipartForm和ParseForm。

func (*Request) PostFormValue

func (r *Request) PostFormValue(key string) string

PostFormValue返回key为键查询r.PostForm字段得到结果[]string切片的第一个值。如果必要,本函数会隐式调用ParseMultipartForm和ParseForm。

func (*Request) FormFile

func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)

FormFile返回以key为键查询r.MultipartForm字段得到结果中的第一个文件和它的信息。如果必要,本函数会隐式调用ParseMultipartForm和ParseForm。查询失败会返回ErrMissingFile错误。

func (*Request) MultipartReader

func (r *Request) MultipartReader() (*multipart.Reader, error)

如果请求是multipart/form-data POST请求,MultipartReader返回一个multipart.Reader接口,否则返回nil和一个错误。使用本函数代替ParseMultipartForm,可以将r.Body作为流处理。

type Response

type Response struct {
    Status     string // 例如"200 OK"
    StatusCode int    // 例如200
    Proto      string // 例如"HTTP/1.0"
    ProtoMajor int    // 例如1
    ProtoMinor int    // 例如0
    // Header保管头域的键值对。
    // 如果回复中有多个头的键相同,Header中保存为该键对应用逗号分隔串联起来的这些头的值
    // (参见RFC 2616 Section 4.2)
    // 被本结构体中的其他字段复制保管的头(如ContentLength)会从Header中删掉。
    //
    // Header中的键都是规范化的,参见CanonicalHeaderKey函数
    Header Header
    // Body代表回复的主体。
    // Client类型和Transport类型会保证Body字段总是非nil的,即使回复没有主体或主体长度为0。
    // 关闭主体是调用者的责任。
    // 如果服务端采用"chunked"传输编码发送的回复,Body字段会自动进行解码。
    Body io.ReadCloser
    // ContentLength记录相关内容的长度。
    // 其值为-1表示长度未知(采用chunked传输编码)
    // 除非对应的Request.Method是"HEAD",其值>=0表示可以从Body读取的字节数
    ContentLength int64
    // TransferEncoding按从最外到最里的顺序列出传输编码,空切片表示"identity"编码。
    TransferEncoding []string
    // Close记录头域是否指定应在读取完主体后关闭连接。(即Connection头)
    // 该值是给客户端的建议,Response.Write方法的ReadResponse函数都不会关闭连接。
    Close bool
    // Trailer字段保存和头域相同格式的trailer键值对,和Header字段相同类型
    Trailer Header
    // Request是用来获取此回复的请求
    // Request的Body字段是nil(因为已经被用掉了)
    // 这个字段是被Client类型发出请求并获得回复后填充的
    Request *Request
    // TLS包含接收到该回复的TLS连接的信息。 对未加密的回复,本字段为nil。
    // 返回的指针是被(同一TLS连接接收到的)回复共享的,不应被修改。
    TLS *tls.ConnectionState
}

Response代表一个HTTP请求的回复。

func ReadResponse

func ReadResponse(r *bufio.Reader, req *Request) (*Response, error)

ReadResponse从r读取并返回一个HTTP 回复。req参数是可选的,指定该回复对应的请求(即是对该请求的回复)。如果是nil,将假设请求是GET请求。客户端必须在结束resp.Body的读取后关闭它。读取完毕并关闭后,客户端可以检查resp.Trailer字段获取回复的trailer的键值对。(本函数主要用在客户端从下层获取回复)

func (*Response) ProtoAtLeast

func (r *Response) ProtoAtLeast(major, minor int) bool

ProtoAtLeast报告该回复使用的HTTP协议版本至少是major.minor。

func (*Response) Cookies

func (r *Response) Cookies() []*Cookie

Cookies解析并返回该回复中的Set-Cookie头设置的cookie。

func (*Response) Location

func (r *Response) Location() (*url.URL, error)

Location返回该回复的Location头设置的URL。相对地址的重定向会相对于该回复对应的请求来确定绝对地址。如果回复中没有Location头,会返回nil, ErrNoLocation。

func (*Response) Write

func (r *Response) Write(w io.Writer) error

Write以有线格式将回复写入w(用于将回复写入下层TCPConn等)。本方法会考虑如下字段:

StatusCode
ProtoMajor
ProtoMinor
Request.Method
TransferEncoding
Trailer
Body
ContentLength
Header(不规范的键名和它对应的值会导致不可预知的行为)

Body字段在发送完回复后会被关闭。

type ResponseWriter

type ResponseWriter interface {
    // Header返回一个Header类型值,该值会被WriteHeader方法发送。
    // 在调用WriteHeader或Write方法后再改变该对象是没有意义的。
    Header() Header
    // WriteHeader该方法发送HTTP回复的头域和状态码。
    // 如果没有被显式调用,第一次调用Write时会触发隐式调用WriteHeader(http.StatusOK)
    // WriterHeader的显式调用主要用于发送错误码。
    WriteHeader(int)
    // Write向连接中写入作为HTTP的一部分回复的数据。
    // 如果被调用时还未调用WriteHeader,本方法会先调用WriteHeader(http.StatusOK)
    // 如果Header中没有"Content-Type"键,
    // 本方法会使用包函数DetectContentType检查数据的前512字节,将返回值作为该键的值。
    Write([]byte) (int, error)
}

ResponseWriter接口被HTTP处理器用于构造HTTP回复。

type Flusher

type Flusher interface {
    // Flush将缓冲中的所有数据发送到客户端
    Flush()
}

HTTP处理器ResponseWriter接口参数的下层如果实现了Flusher接口,可以让HTTP处理器将缓冲中的数据发送到客户端。

注意:即使ResponseWriter接口的下层支持Flush方法,如果客户端是通过HTTP代理连接的,缓冲中的数据也可能直到回复完毕才被传输到客户端。

type CloseNotifier

type CloseNotifier interface {
    // CloseNotify返回一个通道,该通道会在客户端连接丢失时接收到唯一的值
    CloseNotify() <-chan bool
}

HTTP处理器ResponseWriter接口参数的下层如果实现了CloseNotifier接口,可以让用户检测下层的连接是否停止。如果客户端在回复准备好之前关闭了连接,该机制可以用于取消服务端耗时较长的操作。

type Hijacker

type Hijacker interface {
    // Hijack让调用者接管连接,返回连接和关联到该连接的一个缓冲读写器。
    // 调用本方法后,HTTP服务端将不再对连接进行任何操作,
    // 调用者有责任管理、关闭返回的连接。
    Hijack() (net.Conn, *bufio.ReadWriter, error)
}

HTTP处理器ResponseWriter接口参数的下层如果实现了Hijacker接口,可以让HTTP处理器接管该连接。

type RoundTripper

type RoundTripper interface {
    // RoundTrip执行单次HTTP事务,接收并发挥请求req的回复。
    // RoundTrip不应试图解析/修改得到的回复。
    // 尤其要注意,只要RoundTrip获得了一个回复,不管该回复的HTTP状态码如何,
    // 它必须将返回值err设置为nil。
    // 非nil的返回值err应该留给获取回复失败的情况。
    // 类似的,RoundTrip不能试图管理高层次的细节,如重定向、认证、cookie。
    //
    // 除了从请求的主体读取并关闭主体之外,RoundTrip不应修改请求,包括(请求的)错误。
    // RoundTrip函数接收的请求的URL和Header字段可以保证是(被)初始化了的。
    RoundTrip(*Request) (*Response, error)
}

RoundTripper接口是具有执行单次HTTP事务的能力(接收指定请求的回复)的接口。

RoundTripper接口的类型必须可以安全的被多线程同时使用。

type Transport

type Transport struct {
    // Proxy指定一个对给定请求返回代理的函数。
    // 如果该函数返回了非nil的错误值,请求的执行就会中断并返回该错误。
    // 如果Proxy为nil或返回nil的*URL置,将不使用代理。
    Proxy func(*Request) (*url.URL, error)
    // Dial指定创建TCP连接的拨号函数。如果Dial为nil,会使用net.Dial。
    Dial func(network, addr string) (net.Conn, error)
    // TLSClientConfig指定用于tls.Client的TLS配置信息。
    // 如果该字段为nil,会使用默认的配置信息。
    TLSClientConfig *tls.Config
    // TLSHandshakeTimeout指定等待TLS握手完成的最长时间。零值表示不设置超时。
    TLSHandshakeTimeout time.Duration
    // 如果DisableKeepAlives为真,会禁止不同HTTP请求之间TCP连接的重用。
    DisableKeepAlives bool
    // 如果DisableCompression为真,会禁止Transport在请求中没有Accept-Encoding头时,
    // 主动添加"Accept-Encoding: gzip"头,以获取压缩数据。
    // 如果Transport自己请求gzip并得到了压缩后的回复,它会主动解压缩回复的主体。
    // 但如果用户显式的请求gzip压缩数据,Transport是不会主动解压缩的。
    DisableCompression bool
    // 如果MaxIdleConnsPerHost!=0,会控制每个主机下的最大闲置连接。
    // 如果MaxIdleConnsPerHost==0,会使用DefaultMaxIdleConnsPerHost。
    MaxIdleConnsPerHost int
    // ResponseHeaderTimeout指定在发送完请求(包括其可能的主体)之后,
    // 等待接收服务端的回复的头域的最大时间。零值表示不设置超时。
    // 该时间不包括获取回复主体的时间。
    ResponseHeaderTimeout time.Duration
    // 内含隐藏或非导出字段
}

Transport类型实现了RoundTripper接口,支持http、https和http/https代理。Transport类型可以缓存连接以在未来重用。

var DefaultTransport RoundTripper = &Transport{
    Proxy: ProxyFromEnvironment,
    Dial: (&net.Dialer{
        Timeout:   30 * time.Second,
        KeepAlive: 30 * time.Second,
    }).Dial,
    TLSHandshakeTimeout: 10 * time.Second,
}

DefaultTransport是被包变量DefaultClient使用的默认RoundTripper接口。它会根据需要创建网络连接,并缓存以便在之后的请求中重用这些连接。它使用环境变量HTTP_PROXY和NO_PROXY(或http_proxy和no_proxy)指定的HTTP代理。

func (*Transport) RegisterProtocol

func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper)

RegisterProtocol注册一个新的名为scheme的协议。t会将使用scheme协议的请求转交给rt。rt有责任模拟HTTP请求的语义。

RegisterProtocol可以被其他包用于提供"ftp"或"file"等协议的实现。

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *Request) (resp *Response, err error)

RoundTrip方法实现了RoundTripper接口。

高层次的HTTP客户端支持(如管理cookie和重定向)请参见Get、Post等函数和Client类型。

func (*Transport) CloseIdleConnections

func (t *Transport) CloseIdleConnections()

CloseIdleConnections关闭所有之前的请求建立但目前处于闲置状态的连接。本方法不会中断正在使用的连接。

func (*Transport) CancelRequest

func (t *Transport) CancelRequest(req *Request)

CancelRequest通过关闭请求所在的连接取消一个执行中的请求。

type Client

type Client struct {
    // Transport指定执行独立、单次HTTP请求的机制。
    // 如果Transport为nil,则使用DefaultTransport。
    Transport RoundTripper
    // CheckRedirect指定处理重定向的策略。
    // 如果CheckRedirect不为nil,客户端会在执行重定向之前调用本函数字段。
    // 参数req和via是将要执行的请求和已经执行的请求(切片,越新的请求越靠后)。
    // 如果CheckRedirect返回一个错误,本类型的Get方法不会发送请求req,
    // 而是返回之前得到的最后一个回复和该错误。(包装进url.Error类型里)
    //
    // 如果CheckRedirect为nil,会采用默认策略:连续10此请求后停止。
    CheckRedirect func(req *Request, via []*Request) error
    // Jar指定cookie管理器。
    // 如果Jar为nil,请求中不会发送cookie,回复中的cookie会被忽略。
    Jar CookieJar
    // Timeout指定本类型的值执行请求的时间限制。
    // 该超时限制包括连接时间、重定向和读取回复主体的时间。
    // 计时器会在Head、Get、Post或Do方法返回后继续运作并在超时后中断回复主体的读取。
    //
    // Timeout为零值表示不设置超时。
    //
    // Client实例的Transport字段必须支持CancelRequest方法,
    // 否则Client会在试图用Head、Get、Post或Do方法执行请求时返回错误。
    // 本类型的Transport字段默认值(DefaultTransport)支持CancelRequest方法。
    Timeout time.Duration
}

Client类型代表HTTP客户端。它的零值(DefaultClient)是一个可用的使用DefaultTransport的客户端。

Client的Transport字段一般会含有内部状态(缓存TCP连接),因此Client类型值应尽量被重用而不是每次需要都创建新的。Client类型值可以安全的被多个go程同时使用。

Client类型的层次比RoundTripper接口(如Transport)高,还会管理HTTP的cookie和重定向等细节。

func (*Client) Do

func (c *Client) Do(req *Request) (resp *Response, err error)

Do方法发送请求,返回HTTP回复。它会遵守客户端c设置的策略(如重定向、cookie、认证)。

如果客户端的策略(如重定向)返回错误或存在HTTP协议错误时,本方法将返回该错误;如果回应的状态码不是2xx,本方法并不会返回错误。

如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。如果返回值resp的主体未关闭,c下层的RoundTripper接口(一般为Transport类型)可能无法重用resp主体下层保持的TCP连接去执行之后的请求。

请求的主体,如果非nil,会在执行后被c.Transport关闭,即使出现错误。

一般应使用Get、Post或PostForm方法代替Do方法。

func (*Client) Head

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

Head向指定的URL发出一个HEAD请求,如果回应的状态码如下,Head会在调用c.CheckRedirect后执行重定向:

301 (Moved Permanently)
302 (Found)
303 (See Other)
307 (Temporary Redirect)

func (*Client) Get

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

Get向指定的URL发出一个GET请求,如果回应的状态码如下,Get会在调用c.CheckRedirect后执行重定向:

301 (Moved Permanently)
302 (Found)
303 (See Other)
307 (Temporary Redirect)

如果c.CheckRedirect执行失败或存在HTTP协议错误时,本方法将返回该错误;如果回应的状态码不是2xx,本方法并不会返回错误。如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。

func (*Client) Post

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

Post向指定的URL发出一个POST请求。bodyType为POST数据的类型, body为POST数据,作为请求的主体。如果参数body实现了io.Closer接口,它会在发送请求后被关闭。调用者有责任在读取完返回值resp的主体后关闭它。

func (*Client) PostForm

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

PostForm向指定的URL发出一个POST请求,url.Values类型的data会被编码为请求的主体。POST数据的类型一般会设为"application/x-www-form-urlencoded"。如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。

type Handler

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

实现了Handler接口的对象可以注册到HTTP服务端,为特定的路径及其子树提供服务。

ServeHTTP应该将回复的头域和数据写入ResponseWriter接口然后返回。返回标志着该请求已经结束,HTTP服务端可以转移向该连接上的下一个请求。

func NotFoundHandler

func NotFoundHandler() Handler

NotFoundHandler返回一个简单的请求处理器,该处理器会对每个请求都回复"404 page not found"。

func RedirectHandler

func RedirectHandler(url string, code int) Handler

RedirectHandler返回一个请求处理器,该处理器会对每个请求都使用状态码code重定向到网址url。

func TimeoutHandler

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

TimeoutHandler返回一个采用指定时间限制的请求处理器。

返回的Handler会调用h.ServeHTTP去处理每个请求,但如果某一次调用耗时超过了时间限制,该处理器会回复请求状态码503 Service Unavailable,并将msg作为回复的主体(如果msg为空字符串,将发送一个合理的默认信息)。在超时后,h对它的ResponseWriter接口参数的写入操作会返回ErrHandlerTimeout。

func StripPrefix

func StripPrefix(prefix string, h Handler) Handler

StripPrefix返回一个处理器,该处理器会将请求的URL.Path字段中给定前缀prefix去除后再交由h处理。StripPrefix会向URL.Path字段中没有给定前缀的请求回复404 page not found。

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

HandlerFunc type是一个适配器,通过类型转换让我们可以将普通的函数作为HTTP处理器使用。如果f是一个具有适当签名的函数,HandlerFunc(f)通过调用f实现了Handler接口。

func (HandlerFunc) ServeHTTP

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

ServeHTTP方法会调用f(w, r)

type ServeMux

type ServeMux struct {
    // 内含隐藏或非导出字段
}

ServeMux类型是HTTP请求的多路转接器。它会将每一个接收的请求的URL与一个注册模式的列表进行匹配,并调用和URL最匹配的模式的处理器。

模式是固定的、由根开始的路径,如"/favicon.ico",或由根开始的子树,如"/images/"(注意结尾的斜杠)。较长的模式优先于较短的模式,因此如果模式"/images/"和"/images/thumbnails/"都注册了处理器,后一个处理器会用于路径以"/images/thumbnails/"开始的请求,前一个处理器会接收到其余的路径在"/images/"子树下的请求。

注意,因为以斜杠结尾的模式代表一个由根开始的子树,模式"/"会匹配所有的未被其他注册的模式匹配的路径,而不仅仅是路径"/"。

模式也能(可选地)以主机名开始,表示只匹配该主机上的路径。指定主机的模式优先于一般的模式,因此一个注册了两个模式"/codesearch"和"codesearch.google.com/"的处理器不会接管目标为"http://www.google.com/"的请求。

ServeMux还会注意到请求的URL路径的无害化,将任何路径中包含"."或".."元素的请求重定向到等价的没有这两种元素的URL。(参见path.Clean函数)

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux创建并返回一个新的*ServeMux

func (*ServeMux) Handle

func (mux *ServeMux) Handle(pattern string, handler Handler)

Handle注册HTTP处理器handler和对应的模式pattern。如果该模式已经注册有一个处理器,Handle会panic。

func (*ServeMux) HandleFunc

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))

HandleFunc注册一个处理器函数handler和对应的模式pattern。

func (*ServeMux) Handler

func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string)

Handler根据r.Method、r.Host和r.URL.Path等数据,返回将用于处理该请求的HTTP处理器。它总是返回一个非nil的处理器。如果路径不是它的规范格式,将返回内建的用于重定向到等价的规范路径的处理器。

Handler也会返回匹配该请求的的已注册模式;在内建重定向处理器的情况下,pattern会在重定向后进行匹配。如果没有已注册模式可以应用于该请求,本方法将返回一个内建的"404 page not found"处理器和一个空字符串模式。

func (*ServeMux) ServeHTTP

func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request)

ServeHTTP将请求派遣到与请求的URL最匹配的模式对应的处理器。

type Server

type Server struct {
    Addr           string        // 监听的TCP地址,如果为空字符串会使用":http"
    Handler        Handler       // 调用的处理器,如为nil会调用http.DefaultServeMux
    ReadTimeout    time.Duration // 请求的读取操作在超时前的最大持续时间
    WriteTimeout   time.Duration // 回复的写入操作在超时前的最大持续时间
    MaxHeaderBytes int           // 请求的头域最大长度,如为0则用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可选的TLS配置,用于ListenAndServeTLS方法
    // TLSNextProto(可选地)指定一个函数来在一个NPN型协议升级出现时接管TLS连接的所有权。
    // 映射的键为商谈的协议名;映射的值为函数,该函数的Handler参数应处理HTTP请求,
    // 并且初始化Handler.ServeHTTP的*Request参数的TLS和RemoteAddr字段(如果未设置)。
    // 连接在函数返回时会自动关闭。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一个可选的回调函数,该函数会在一个与客户端的连接改变状态时被调用。
    // 参见ConnState类型和相关常数获取细节。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一个可选的日志记录器,用于记录接收连接时的错误和处理器不正常的行为。
    // 如果本字段为nil,日志会通过log包的标准日志记录器写入os.Stderr。
    ErrorLog *log.Logger
    // 内含隐藏或非导出字段
}

Server类型定义了运行HTTP服务端的参数。Server的零值是合法的配置。

func (*Server) SetKeepAlivesEnabled

func (s *Server) SetKeepAlivesEnabled(v bool)

SetKeepAlivesEnabled控制是否允许HTTP闲置连接重用(keep-alive)功能。默认该功能总是被启用的。只有资源非常紧张的环境或者服务端在关闭进程中时,才应该关闭该功能。

func (*Server) Serve

func (srv *Server) Serve(l net.Listener) error

Serve会接手监听器l收到的每一个连接,并为每一个连接创建一个新的服务go程。该go程会读取请求,然后调用srv.Handler回复请求。

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe() error

ListenAndServe监听srv.Addr指定的TCP地址,并且会调用Serve方法接收到的连接。如果srv.Addr为空字符串,会使用":http"。

func (*Server) ListenAndServeTLS

func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error

ListenAndServeTLS监听srv.Addr确定的TCP地址,并且会调用Serve方法处理接收到的连接。必须提供证书文件和对应的私钥文件。如果证书是由权威机构签发的,certFile参数必须是顺序串联的服务端证书和CA证书。如果srv.Addr为空字符串,会使用":https"。

type File

type File interface {
    io.Closer
    io.Reader
    Readdir(count int) ([]os.FileInfo, error)
    Seek(offset int64, whence int) (int64, error)
    Stat() (os.FileInfo, error)
}

File是被FileSystem接口的Open方法返回的接口类型,可以被FileServer等函数用于文件访问服务。

该接口的方法的行为应该和*os.File类型的同名方法相同。

type FileSystem

type FileSystem interface {
    Open(name string) (File, error)
}

FileSystem接口实现了对一系列命名文件的访问。文件路径的分隔符为'/',不管主机操作系统的惯例如何。

type Dir

type Dir string

Dir使用限制到指定目录树的本地文件系统实现了http.FileSystem接口。空Dir被视为".",即代表当前目录。

func (Dir) Open

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

func NewFileTransport

func NewFileTransport(fs FileSystem) RoundTripper

NewFileTransport返回一个RoundTripper接口,使用FileSystem接口fs提供文件访问服务。 返回的RoundTripper接口会忽略接收的请求的URL主机及其他绝大多数属性。

NewFileTransport函数的典型使用情况是给Transport类型的值注册"file"协议,如下所示:

t := &http.Transport{}
t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/")))
c := &http.Client{Transport: t}
res, err := c.Get("file:///etc/passwd")
...

func FileServer

func FileServer(root FileSystem) Handler

FileServer返回一个使用FileSystem接口root提供文件访问服务的HTTP处理器。要使用操作系统的FileSystem接口实现,可使用http.Dir:

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

func ProxyURL

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

ProxyURL返回一个代理函数(用于Transport类型),该函数总是返回同一个URL。

func ProxyFromEnvironment

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

ProxyFromEnvironment使用环境变量HTTP_PROXY和NO_PROXY(或http_proxy和no_proxy)的配置返回用于req的代理。如果代理环境不合法将返回错误;如果环境未设定代理或者给定的request不应使用代理时,将返回(nil, nil);如果req.URL.Host字段是"localhost"(可以有端口号,也可以没有),也会返回(nil, nil)。

func SetCookie

func SetCookie(w ResponseWriter, cookie *Cookie)

SetCookie在w的头域中添加Set-Cookie头,该HTTP头的值为cookie。

func Redirect

func Redirect(w ResponseWriter, r *Request, urlStr string, code int)

Redirect回复请求一个重定向地址urlStr和状态码code。该重定向地址可以是相对于请求r的相对地址。

func NotFound

func NotFound(w ResponseWriter, r *Request)

NotFound回复请求404状态码(not found:目标未发现)。

func Error

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

Error使用指定的错误信息和状态码回复请求,将数据写入w。错误信息必须是明文。

func ServeContent

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

ServeContent使用提供的ReadSeeker的内容回复请求。ServeContent比起io.Copy函数的主要优点,是可以处理范围类请求(只要一部分内容)、设置MIME类型,处理If-Modified-Since请求。

如果未设定回复的Content-Type头,本函数首先会尝试从name的文件扩展名推断数据类型;如果失败,会用读取content的第1块数据并提供给DetectContentType推断类型;之后会设置Content-Type头。参数name不会用于别的地方,甚至于它可以是空字符串,也永远不会发送到回复里。

如果modtime不是Time零值,函数会在回复的头域里设置Last-Modified头。如果请求的头域包含If-Modified-Since头,本函数会使用modtime参数来确定是否应该发送内容。如果调用者设置了w的ETag头,ServeContent会使用它处理包含If-Range头和If-None-Match头的请求。

参数content的Seek方法必须有效:函数使用Seek来确定它的大小。

注意:本包File接口和*os.File类型都实现了io.ReadSeeker接口。

func ServeFile

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

ServeFile回复请求name指定的文件或者目录的内容。

func MaxBytesReader

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

MaxBytesReader类似io.LimitReader,但它是用来限制接收到的请求的Body的大小的。不同于io.LimitReader,本函数返回一个ReadCloser,返回值的Read方法在读取的数据超过大小限制时会返回非EOF错误,其Close方法会关闭下层的io.ReadCloser接口r。

MaxBytesReader预防客户端因为意外或者蓄意发送的“大”请求,以避免尺寸过大的请求浪费服务端资源。

func Head

func Head(url string) (resp *Response, err error)

Head向指定的URL发出一个HEAD请求,如果回应的状态码如下,Head会在调用c.CheckRedirect后执行重定向:

301 (Moved Permanently)
302 (Found)
303 (See Other)
307 (Temporary Redirect)

Head是对包变量DefaultClient的Head方法的包装。

func Get

func Get(url string) (resp *Response, err error)

Get向指定的URL发出一个GET请求,如果回应的状态码如下,Get会在调用c.CheckRedirect后执行重定向:

301 (Moved Permanently)
302 (Found)
303 (See Other)
307 (Temporary Redirect)

如果c.CheckRedirect执行失败或存在HTTP协议错误时,本方法将返回该错误;如果回应的状态码不是2xx,本方法并不会返回错误。如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。

Get是对包变量DefaultClient的Get方法的包装。

func Post

func Post(url string, bodyType string, body io.Reader) (resp *Response, err error)

Post向指定的URL发出一个POST请求。bodyType为POST数据的类型, body为POST数据,作为请求的主体。如果参数body实现了io.Closer接口,它会在发送请求后被关闭。调用者有责任在读取完返回值resp的主体后关闭它。

Post是对包变量DefaultClient的Post方法的包装。

func PostForm

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

PostForm向指定的URL发出一个POST请求,url.Values类型的data会被编码为请求的主体。如果返回值err为nil,resp.Body总是非nil的,调用者应该在读取完resp.Body后关闭它。

PostForm是对包变量DefaultClient的PostForm方法的包装。

func Handle

func Handle(pattern string, handler Handler)

Handle注册HTTP处理器handler和对应的模式pattern(注册到DefaultServeMux)。如果该模式已经注册有一个处理器,Handle会panic。ServeMux的文档解释了模式的匹配机制。

func HandleFunc

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

HandleFunc注册一个处理器函数handler和对应的模式pattern(注册到DefaultServeMux)。ServeMux的文档解释了模式的匹配机制。

func Serve

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

Serve会接手监听器l收到的每一个连接,并为每一个连接创建一个新的服务go程。该go程会读取请求,然后调用handler回复请求。handler参数一般会设为nil,此时会使用DefaultServeMux。

func ListenAndServe

func ListenAndServe(addr string, handler Handler) error

ListenAndServe监听TCP地址addr,并且会使用handler参数调用Serve函数处理接收到的连接。handler参数一般会设为nil,此时会使用DefaultServeMux。

一个简单的服务端例子:

package main
import (
    "io"
    "net/http"
    "log"
)
// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request) {
    io.WriteString(w, "hello, world!\n")
}
func main() {
    http.HandleFunc("/hello", HelloServer)
    err := http.ListenAndServe(":12345", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func ListenAndServeTLS

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

ListenAndServeTLS函数和ListenAndServe函数的行为基本一致,除了它期望HTTPS连接之外。此外,必须提供证书文件和对应的私钥文件。如果证书是由权威机构签发的,certFile参数必须是顺序串联的服务端证书和CA证书。如果srv.Addr为空字符串,会使用":https"。

一个简单的服务端例子:

import (
    "log"
    "net/http"
)
func handler(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain")
    w.Write([]byte("This is an example server.\n"))
}
func main() {
    http.HandleFunc("/", handler)
    log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
    err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
    if err != nil {
        log.Fatal(err)
    }
}

程序员可以使用crypto/tls包的generate_cert.go文件来生成cert.pem和key.pem两个文件。

http/cgi

cgi包实现了CGI(Common Gateway Interface,公共网关协议),参见RFC 3875

注意使用CGI意味着对每一个请求开始一个新的进程,这显然要比使用长期运行的服务程序要低效。本包主要是为了兼容现有的系统。

func Request

func Request() (*http.Request, error)

返回一个当前环境下的HTTP请求。它假设当前程序执行在CGI环境下,成功返回的Request的Body是可读取数据的。(如果必要)

func RequestFromMap

func RequestFromMap(params map[string]string) (*http.Request, error)

使用CGI变量集params创建一个HTTP请求。返回的Request的Body是没有数据的。

func Serve

func Serve(handler http.Handler) error

在当前活跃CGI环境下执行handler;如当前无CGI环境,会返回错误。handler为nil时将使用http.DefaultServeMux。

type Handler

type Handler struct {
    Path string // CGI可执行文件的路径
    Root string // handler的根URI前缀,""代表"/"
    // Dir指定CGI程序的工作目录。
    // 如果Dir为""则使用Path的基目录;如果Path没有基目录则使用当前工作目录。
    Dir string
    Env        []string    // 额外设置的环境变量(如果有),格式为"key=value"
    InheritEnv []string    // 从host继承的环境变量,只有"key"
    Logger     *log.Logger // 可选的logger接口切片,如为nil则使用log.Print
    Args       []string    // 可选的传递给子进程的参数
    // 当CGI进程返回一个Location头,且其值以"/"开始时,
    // 本字段指定处理内部重定向的根部HTTP Handler。参见RFC 3875 § 6.3.2。
    // 一般会使用http.DefaultServeMux。
    // 如果为nil,返回一个本地URI路径的CGI回复会发送给客户端,不进行内部跳转。
    PathLocationHandler http.Handler
}

Handler在子进程中执行具有一个CGI环境的可执行程序。

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request)

http/cookiejar

cookiejar包实现了保管在内存中的符合RFC 6265标准的http.CookieJar接口。

type PublicSuffixList

type PublicSuffixList interface {
    // 返回域名的公共后缀。
    // TODO:域名的格式化应该由调用者还是接口方法负责还没有确定。
    PublicSuffix(domain string) string
    // 返回公共后缀列表的来源的说明,该说明一般应该包含时间戳和版本号。
    String() string
}

PublicSuffixList提供域名的公共后缀。例如:

- "example.com"的公共后缀是"com"
- "foo1.foo2.foo3.co.uk"的公共后缀是"co.uk"
- "bar.pvt.k12.ma.us"的公共后缀是"pvt.k12.ma.us"

PublicSuffixList接口的实现必须是并发安全的。一个总是返回""的实现是合法的,也可以通过测试;但却是不安全的:它允许HTTP服务端跨域名设置cookie。推荐实现:code.google.com/p/go.net/publicsuffix

type Options

type Options struct {
    // PublicSuffixList是公共后缀列表,用于决定HTTP服务端是否能给某域名设置cookie
    // nil值合法的,也可以通过测试;但却是不安全的:它允许HTTP服务端跨域名设置cookie
    PublicSuffixList PublicSuffixList
}

Options是创建新Jar是的选项。

type Jar

type Jar struct {
    psList PublicSuffixList

    // mu locks the remaining fields.
    mu sync.Mutex

    // entries is a set of entries, keyed by their eTLD+1 and subkeyed by
    // their name/domain/path.
    entries map[string]map[string]entry

    // nextSeqNum is the next sequence number assigned to a new cookie
    // created SetCookies.
    nextSeqNum uint64
}

Jar类型实现了net/http包的http.CookieJar接口。

func New

func New(o *Options) (*Jar, error)

返回一个新的Jar,nil指针等价于Options零值的指针。

func (*Jar) Cookies

func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie)

实现CookieJar接口的Cookies方法,如果URL协议不是HTTP/HTTPS会返回空切片。

func (*Jar) SetCookies

func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie)

实现CookieJar接口的SetCookies方法,如果URL协议不是HTTP/HTTPS则不会有实际操作。

http/fcgi

fcgi包实现了FastCGI协议。目前只支持响应器的角色。

协议定义的地址:http://www.fastcgi.com/drupal/node/6?q=node/22

func Serve

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

Serve接受从监视器l传入的FastCGI连接,为每一个FastCGI连接创建一个新的go程。该go程读取请求然后调用handler回复请求。如果l是nil,Serve将从os.Stdin接受连接。如果handler是nil,将使用http.DefaultServeMux。

http/httptest

httptest包提供了HTTP测试的常用函数。

Constants

const DefaultRemoteAddr = "1.2.3.4"

DefaultRemoteAddr是默认的远端地址。如果ResponseRecorder未显式的设置该属性,RemoteAddr方法就会返回该值。

func NewRequest

func NewRequest(method, target string, body io.Reader) *http.Request

NewRequest 返回一个新的服务器访问请求,这个请求可以传递给 http.Handler 以便进行测试。

target 参数的值为 RFC 7230 中提到的“请求目标”(request-target): 它可以是一个路径或者一个绝对 URL。如果 target 是一个绝对 URL,那么 URL 中的主机名(host name)将被使用;否则主机名将为 example.com。

当 target 的模式为 https 时,TLS 字段的值将被设置为一个非 nil 的随意值(dummy value)。

Request.Proto 总是为 HTTP/1.1。

如果 method 参数的值为空, 那么使用 GET 方法作为默认值。

body 参数的值可以为 nil;另一方面,如果 body 参数的值为 *bytes.Reader 类型、 *strings.Reader 类型或者 *bytes.Buffer 类型,那么 Request.ContentLength 将被设置。

为了使用的方便,NewRequest 将在 panic 可以被接受的情况下,使用 panic 代替错误。

如果你想要生成的不是服务器访问请求,而是一个客户端 HTTP 请求,那么请使用 net/http 包中的 NewRequest 函数。

type ResponseRecorder

type ResponseRecorder struct {
    Code      int           // HTTP回复的状态码
    HeaderMap http.Header   // HTTP回复的头域
    Body      *bytes.Buffer // 如非nil,会将Write方法写入的数据写入bytes.Buffer
    Flushed   bool
    // 内含隐藏或非导出字段
}

ResponseRecorder实现了http.ResponseWriter接口,它记录了其修改,用于之后的检查。

func NewRecorder

func NewRecorder() *ResponseRecorder

NewRecorder返回一个初始化了的ResponseRecorder.

func (*ResponseRecorder) Flush

func (rw *ResponseRecorder) Flush()

Flush将rw.Flushed设置为真。

func (*ResponseRecorder) Heade

func (rw *ResponseRecorder) Header() http.Header

Header返回回复的头域,即Header字段。

func (*ResponseRecorder) Result

func (rw *ResponseRecorder) Result() *http.Response

Result 返回处理器生成的响应。

处理器返回的响应至少会对状态码(StatusCode)、首部(Header)、主体(Body)以及可选的 Trailer 进行设置。 因为未来可能会有更多字段被设置,所以用户不应该在测试里面对结果调用 DeepEqual。

Response.Header 是写入操作第一次调用时的首部快照(snapshot of the headers); 另一方面, 如果处理器没有执行过写入操作, 那么 Response.Header 就是 Result 方法调用时的首部快照。

Response.Body 将被生成为一个非 nil 值,而 Body.Read 则保证不会返回除 io.EOF 之外的其他任何错误。

Result 必须在处理器执行完毕之后调用。

func (*ResponseRecorder) Write

func (rw *ResponseRecorder) Write(buf []byte) (int, error)

Write总是成功,如果rw.Body非nil会把数据写入该字段。

func (*ResponseRecorder) WriteHeader

func (rw *ResponseRecorder) WriteHeader(code int)

WriteHeader设置rw.Code。

func (*ResponseRecorder) WriteString

func (rw *ResponseRecorder) WriteString(str string) (int, error)

在 str 不为 nil 的情况下, WriteString 总会成功地将 buf 中的内容写入到 rw.Body 当中。

type Server

type Server struct {
    URL      string // 格式为http://ipaddr:port,没有末尾斜杠的基地址
    Listener net.Listener
    // TLS是可选的TLS配置,在TLS开始后会填写为新的配置。
    // 如果在未启动的Server调用StartTLS方法前设置,已经存在的字段会拷贝进新配置里。
    TLS *tls.Config
    // Config可能会在调用Start/StartTLS方法之前调用NewUnstartedServer时被修改。
    Config *http.Server
    // 内含隐藏或非导出字段
}

Server是一个HTTP服务端,在本地环回接口的某个系统选择的端口监听,用于点对点HTTP测试。

func NewServer

func NewServer(handler http.Handler) *Server

NewServer返回一个新的、已启动的Server。调用者必须在用完时调用Close方法关闭它。

func NewTLSServer

func NewTLSServer(handler http.Handler) *Server

NewTLSServer返回一个新的、使用TLS的、已启动的Server。调用者必须在用完时调用Close方法关闭它。

func NewUnstartedServer

func NewUnstartedServer(handler http.Handler) *Server

NewUnstartedServer返回一个新的、未启动的Server。在修改其配置后,调用者应该调用Start或StartTLS启动它;调在用完时用者必须调用Close方法关闭它。

func (*Server) Start

func (s *Server) Start()

Start启动NewUnstartedServer返回的服务端。

func (*Server) StartTLS

func (s *Server) StartTLS()

StartTLS启动NewUnstartedServer函数返回的服务端的TLS监听。

func (*Server) CloseClientConnections

func (s *Server) CloseClientConnections()

CloseClientConnections关闭当前任何与该服务端建立的HTTP连接。

func (*Server) Close

func (s *Server) Close()

Close关闭服务端,并阻塞直到所有该服务端未完成的请求都结束为止。

http/httptrace

httptrace包提供了跟踪HTTP客户端请求中的事件的机制。

func WithClientTrace

func WithClientTrace(ctx context.Context, trace *ClientTrace) context.Context

WithClientTrace基于提供的父ctx返回一个新的上下文。 除了先前在ctx中注册的任何钩子之外,使用返回的上下文发出的HTTP客户端请求还将使用提供的跟踪钩子。 在提供的跟踪中定义的任何挂钩都将首先被调用。

type ClientTrace

type ClientTrace struct {
    // GetConn is called before a connection is created or
    // retrieved from an idle pool. The hostPort is the
    // "host:port" of the target or proxy. GetConn is called even
    // if there's already an idle cached connection available.
    GetConn func(hostPort string)

    // GotConn is called after a successful connection is
    // obtained. There is no hook for failure to obtain a
    // connection; instead, use the error from
    // Transport.RoundTrip.
    GotConn func(GotConnInfo)

    // PutIdleConn is called when the connection is returned to
    // the idle pool. If err is nil, the connection was
    // successfully returned to the idle pool. If err is non-nil,
    // it describes why not. PutIdleConn is not called if
    // connection reuse is disabled via Transport.DisableKeepAlives.
    // PutIdleConn is called before the caller's Response.Body.Close
    // call returns.
    // For HTTP/2, this hook is not currently used.
    PutIdleConn func(err error)

    // GotFirstResponseByte is called when the first byte of the response
    // headers is available.
    GotFirstResponseByte func()

    // Got100Continue is called if the server replies with a "100
    // Continue" response.
    Got100Continue func()

    // DNSStart is called when a DNS lookup begins.
    DNSStart func(DNSStartInfo)

    // DNSDone is called when a DNS lookup ends.
    DNSDone func(DNSDoneInfo)

    // ConnectStart is called when a new connection's Dial begins.
    // If net.Dialer.DualStack (IPv6 "Happy Eyeballs") support is
    // enabled, this may be called multiple times.
    ConnectStart func(network, addr string)

    // ConnectDone is called when a new connection's Dial
    // completes. The provided err indicates whether the
    // connection completedly successfully.
    // If net.Dialer.DualStack ("Happy Eyeballs") support is
    // enabled, this may be called multiple times.
    ConnectDone func(network, addr string, err error)

    // TLSHandshakeStart is called when the TLS handshake is started. When
    // connecting to a HTTPS site via a HTTP proxy, the handshake happens after
    // the CONNECT request is processed by the proxy.
    TLSHandshakeStart func()

    // TLSHandshakeDone is called after the TLS handshake with either the
    // successful handshake's connection state, or a non-nil error on handshake
    // failure.
    TLSHandshakeDone func(tls.ConnectionState, error)

    // WroteHeaders is called after the Transport has written
    // the request headers.
    WroteHeaders func()

    // Wait100Continue is called if the Request specified
    // "Expected: 100-continue" and the Transport has written the
    // request headers but is waiting for "100 Continue" from the
    // server before writing the request body.
    Wait100Continue func()

    // WroteRequest is called with the result of writing the
    // request and any body. It may be called multiple times
    // in the case of retried requests.
    WroteRequest func(WroteRequestInfo)
}

ClientTrace是一组挂钩,可以在传出HTTP请求的各个阶段运行。 任何特定的钩子都可以为零。 可以从不同的goroutine并发调用函数,某些函数可以在请求完成或失败后调用。

ClientTrace当前在单个往返过程中跟踪单个HTTP请求和响应,并且没有跨越一系列重定向请求的钩子。

See https://blog.golang.org/http-tracing for more.

func ContextClientTrace

func ContextClientTrace(ctx context.Context) *ClientTrace

ContextClientTrace返回与提供的上下文关联的ClientTrace。 如果没有,则返回nil。

type DNSDoneInfo

type DNSDoneInfo struct {
    // Addrs are the IPv4 and/or IPv6 addresses found in the DNS
    // lookup. The contents of the slice should not be mutated.
    Addrs []net.IPAddr

    // Err is any error that occurred during the DNS lookup.
    Err error

    // Coalesced is whether the Addrs were shared with another
    // caller who was doing the same DNS lookup concurrently.
    Coalesced bool
}

DNSDoneInfo包含有关DNS查找结果的信息。

type DNSStartInfo

type DNSStartInfo struct {
    Host string
}

DNSStartInfo包含有关DNS请求的信息。

type GotConnInfo

type GotConnInfo struct {
    // Conn is the connection that was obtained. It is owned by
    // the http.Transport and should not be read, written or
    // closed by users of ClientTrace.
    Conn net.Conn

    // Reused is whether this connection has been previously
    // used for another HTTP request.
    Reused bool

    // WasIdle is whether this connection was obtained from an
    // idle pool.
    WasIdle bool

    // IdleTime reports how long the connection was previously
    // idle, if WasIdle is true.
    IdleTime time.Duration
}

GotConnInfo是ClientTrace.GotConn函数的参数,并包含有关获得的连接的信息。

type WroteRequestInfo

type WroteRequestInfo struct {
    // Err is any error encountered while writing the Request.
    Err error
}

WroteRequestInfo包含提供给WroteRequest挂钩的信息。

http/httputil

httputil包提供了HTTP公用函数,是对net/http包的更常见函数的补充。

Variables

var (
    ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"}
    ErrClosed     = &http.ProtocolError{ErrorString: "connection closed by user"}
    ErrPipeline   = &http.ProtocolError{ErrorString: "pipeline error"}
)
var ErrLineTooLong = errors.New("header line too long")

func DumpRequest

func DumpRequest(req *http.Request, body bool) (dump []byte, err error)

DumpRequest返回req的和被服务端接收到时一样的有线表示,可选地包括请求的主体,用于debug。本函数在语义上是无操作的,但为了转储请求主体,他会读取主体的数据到内存中,并将req.Body修改为指向内存中的拷贝。req的字段的使用细节请参见http.Request的文档。

func DumpRequestOut

func DumpRequestOut(req *http.Request, body bool) ([]byte, error)

DumpRequestOut类似DumpRequest,但会包括标准http.Transport类型添加的头域,如User-Agent。

func DumpResponse

func DumpResponse(resp *http.Response, body bool) (dump []byte, err error)

DumpResponse类似DumpRequest,但转储的是一个回复。

func NewChunkedReader

func NewChunkedReader(r io.Reader) io.Reader

NewChunkedReader返回一个io.Reader。返回值的Read方法会将从r读取的采用HTTP "chunked"传输编码的数据翻译之后返回。当读取到最后的零长chunk时,返回值的Read会返回io.EOF。

NewChunkedReader在正常的应用中是不需要的,http包在读取回复主体时会自动将"chunked"编码进行解码。

func NewChunkedWriter

func NewChunkedWriter(w io.Writer) io.WriteCloser

NewChunkedWriter返回一个io.Writer。返回值的Write方法会将写入的数据编码为HTTP "chunked"传输编码格式后再写入w。其Close方法会将最后的零长chunk写入w,标注数据流的结尾。

正常的应用中不需要NewChunkedWriter,http包会在处理器未设置Content-Length头时主动进行chunked编码。在处理器内部使用本函数会导致双重chunked或者有Content-Length头的chunked,两个都是错误的。

type ClientConn

type ClientConn struct {
    mu              sync.Mutex // read-write protects the following fields
    c               net.Conn
    r               *bufio.Reader
    re, we          error // read/write errors
    lastbody        io.ReadCloser
    nread, nwritten int
    pipereq         map[*http.Request]uint

    pipe     textproto.Pipeline
    writeReq func(*http.Request, io.Writer) error
}

ClientConn类型会在尊重HTTP keepalive逻辑的前提下,在下层的连接上发送请求和接收回复的头域。ClientConn类型支持通过Hijack方法劫持下层连接,取回对下层连接的控制权,按照调用者的预期处理该连接。

ClientConn是旧的、低层次的。应用程序应使用net/http包的Client类型和Transport类型代替它。

func NewClientConn

func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewClientConn返回一个对c进行读写的ClientConn。如果r不是nil,它是从c读取时使用的缓冲。

func NewProxyClientConn

func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn

NewProxyClientConn类似NewClientConn,但使用Request.WriteProxy方法将请求写入c。

func (*ClientConn) Pending

func (cc *ClientConn) Pending() int

Pending返回该连接上已发送但还未接收到回复的请求的数量。

func (*ClientConn) Write

func (cc *ClientConn) Write(req *http.Request) (err error)

Write写入一个请求。如果该连接已经在HTTP keepalive逻辑上关闭了(表示该连接不会再发送新的请求)返回ErrPersistEOF。如果req.Close设置为真,keepalive连接会在这次请求后逻辑上关闭,并通知远端的服务器。ErrUnexpectedEOF表示远端关闭了下层的TCP连接,这一般被视为优雅的(正常的)关闭。

func (*ClientConn) Read

func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error)

Read读取下一个回复。合法的回复可能会和ErrPersistEOF一起返回,这表示远端要求该请求是最后一个被服务的请求。Read可以和Write同时调用,但不能和另一个Read同时调用。

func (*ClientConn) Do

func (cc *ClientConn) Do(req *http.Request) (resp *http.Response, err error)

Do是一个便利方法,它会写入一个请求,并读取一个回复。(能不能保证二者对应?不知道)

func (*ClientConn) Hijack

func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader)

Hijack拆开ClientConn返回下层的连接和读取侧的缓冲,其中可能有部分剩余的数据。Hijack可以在调用者自身或者其Read方法发出keepalive逻辑的终止信号之前调用。调用者不应在Write或Read执行过程中调用Hijack。

func (*ClientConn) Close

func (cc *ClientConn) Close() error

Close调用Hijack,然后关闭下层的连接。

type ServerConn

type ServerConn struct {
    mu              sync.Mutex // read-write protects the following fields
    c               net.Conn
    r               *bufio.Reader
    re, we          error // read/write errors
    lastbody        io.ReadCloser
    nread, nwritten int
    pipereq         map[*http.Request]uint

    pipe textproto.Pipeline
}

ServerConn类型在下层的连接上接收请求和发送回复,直到HTTP keepalive逻辑结束。ServerConn类型支持通过Hijack方法劫持下层连接,取回对下层连接的控制权,按照调用者的预期处理该连接。ServerConn支持管道内套,例如,请求可以不和回复的发送同步的读取(但仍按照相同的顺序)。

ServerConn是旧的、低层次的。应用程序应使用net/http包的Server类型代替它。

func NewServerConn

func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn

NewServerConn返回一个新的从c读写的ServerConn。如果r补位nil,它将作为从c读取时的缓冲。

func (*ServerConn) Pending

func (sc *ServerConn) Pending() int

Pending返回该连接上已接收到但还未回复的请求的数量。

func (*ServerConn) Read

func (sc *ServerConn) Read() (req *http.Request, err error)

Read读取下一个请求。如果它优雅的决定不会再有更多的请求(例如,在HTTP/1.0连接的第一个请求之后,或者HTTP/1.1的一个具有" Connection:close "头的请求之后),会返回ErrPersistEOF。

func (*ServerConn) Write

func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error

Write写入req的回复resp。如要优雅的关闭该连接,可以设置resp.Close字段为真。Write方法应该尽量执行(以回复尽量多的请求),直到Write本身返回错误,而不应考虑读取侧返回的任何错误。

func (*ServerConn) Hijack

func (sc *ServerConn) Hijack() (c net.Conn, r *bufio.Reader)

Hijack拆开ServerConn返回下层的连接和读取侧的缓冲,其中可能有部分剩余的数据。Hijack可以在调用者自身或者其Read方法发出keepalive逻辑的终止信号之前调用。调用者不应在Write或Read执行过程中调用Hijack。

func (*ServerConn) Close

func (sc *ServerConn) Close() error

Close调用Hijack,然后关闭下层的连接。

type ReverseProxy

type ReverseProxy struct {
    // Director必须是将请求修改为新的请求的函数。
    // 修改后的请求会使用Transport发送,得到的回复会不经修改的返回给客户端。
    Director func(*http.Request)
    // Transport用于执行代理请求。
    // 如果本字段为nil,会使用http.DefaultTransport。
    Transport http.RoundTripper
    // FlushInterval指定拷贝回复的主体时将数据刷新给客户端的时间间隔。
    // 如果本字段为零值,不会进行周期的刷新。(拷贝完回复主体后再刷新)
    FlushInterval time.Duration
}

ReverseProxy是一个HTTP处理器,它接收一个请求,发送给另一个服务端,将回复转发给客户端。

func NewSingleHostReverseProxy

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy

NewSingleHostReverseProxy返回一个新的ReverseProxy。返回值会将请求的URL重写为target参数提供的协议、主机和基路径。如果target参数的Path字段为"/base",接收到的请求的URL.Path为"/dir",修改后的请求的URL.Path将会是"/base/dir"。

func (*ReverseProxy) ServeHTTP

func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)

http/pprof

pprof包通过它的HTTP服务端提供pprof可视化工具期望格式的运行时剖面文件数据服务。关于pprof的更多信息,参见http://code.google.com/p/google-perftools/

本包一般只需导入获取其注册HTTP处理器的副作用。处理器的路径以/debug/pprof/开始。

要使用pprof,在你的程序里导入本包:

import _ "net/http/pprof"

如果你的应用还没有运行http服务器,你需要开始一个http服务器。添加"net/http"包和"log"包到你的导入列表,然后在main函数开始处添加如下代码:

go func() {
    log.Println(http.ListenAndServe("localhost:6060", nil))
}()

然后使用pprof工具查看堆剖面:

go tool pprof http://localhost:6060/debug/pprof/heap

或查看周期30秒的CPU剖面:

go tool pprof http://localhost:6060/debug/pprof/profile

或查看go程阻塞剖面:

go tool pprof http://localhost:6060/debug/pprof/block

要查看所有可用的剖面,在你的浏览器阅读http://localhost:6060/debug/pprof/。要学习这些运转的设施,访问:

http://blog.golang.org/2011/06/profiling-go-programs.html

func Handler

func Handler(name string) http.Handler

Handler返回一个提供name指定的剖面文件的服务的HTTP处理器。

func Cmdline

func Cmdline(w http.ResponseWriter, r *http.Request)

Cmdline回应执行中程序的命令行,采用NUL字节分隔的参数。本包将它注册在/debug/pprof/cmdline。

func Index

func Index(w http.ResponseWriter, r *http.Request)

Index回复请求要求的pprof格式的剖面。例如,"/debug/pprof/heap"会回复"heap"剖面。Index会回复"/debug/pprof/" 请求一个列出所有可用的剖面的HTML页面。

func Profile

func Profile(w http.ResponseWriter, r *http.Request)

Profile回复pprof格式的CPU剖面。本包将它注册在/debug/pprof/profile。

func Symbol

func Symbol(w http.ResponseWriter, r *http.Request)

Symbol查看请求中列出的程序计数器,回复一个映射程序计数器到函数名的表格。本包将它注册在/debug/pprof/symbol。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348