【Golang】网络开发:net/http包

本篇为http开发前的包阅读

net/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())

type Header

type Header map[string][]string

Header代表HTTP头域的键值对。

  1. 要知道golang中的map只有hashmap一种,也就是说这个 Header map[string][]string 是一个无序字典

func (h Header) Get(key string) string

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

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

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

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

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

func (h Header) Del(key string)

Del删除键值对。

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

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

  1. 直接向header里写入数据

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 (c *Cookie) String() string

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

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接口的文档。

  1. 处理请求的结构体

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

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

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

  1. 创建一个request实例

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

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

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

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

func (r *Request) UserAgent() string

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

func (r *Request) Referer() string

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

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

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

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

  1. 这表示所有的cookie都写在同一行,用分号分隔(cookie内部用逗号分隔属性)

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

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

  1. 用来设置Authorization头
  2. 在oauth系列的验签可能会用到

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字段会在发送完请求后关闭。
  1. 直接手写一个request里的数据

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 (r *Request) Cookies() []*Cookie

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

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

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

func (r *Request) ParseForm() error

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

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

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

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

  1. 用来获取请求参数

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

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

  1. 用来获取MultipartForm的请求参数,文件上传之类的会用到

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

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

  1. 查询指定参数

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

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

  1. 查询post的指定字段

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

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

  1. 查询上传的文件的信息

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请求的回复。

  1. 处理响应的结构体

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

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

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

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

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

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

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

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

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

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

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

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

  1. body字段是个io.ReadCloser

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 (t *Transport) RegisterProtocol(scheme string, rt RoundTripper)

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

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

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

RoundTrip方法实现了RoundTripper接口。

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

func (t *Transport) CloseIdleConnections()

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

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和重定向等细节。

  1. 这个是http客户端

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 (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 (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 (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 (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 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的零值是合法的配置。

  1. 这是一个http服务端

func (s *Server) SetKeepAlivesEnabled(v bool)

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

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

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

func (srv *Server) ListenAndServe() error

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

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

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

程序幼儿员-龚学鹏
请先登录后发表评论
  • latest comments
  • 总共0条评论