package http

import "net/http"

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

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

<pre>resp, err := http.Get("[http://example.com/](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”}})

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

<pre>resp, err := http.Get("[http://example.com/](http://example.com/)")

if err != nil { // handle error } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) // …

要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:

<pre>client := &amp;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:

<pre>tr := &amp;http.Transport{
TLSClientConfig:    &amp;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添加处理器。

<pre>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:

<pre>s := &amp;http.Server{
Addr:           ":8080",
Handler:        myHandler,
ReadTimeout:    10 * time.Second,
WriteTimeout:   10 * time.Second,
MaxHeaderBytes: 1 &lt;&lt; 20,

} log.Fatal(s.ListenAndServe())

Index

[

返回首页

](../main.html)

    <li>[Constants](#pkg-constants)</li>
    <li>[Variables](#pkg-variables)</li>
    <li>[type ProtocolError](#ProtocolError)</li>

Examples

[

返回首页

](../main.html)

    <li>[FileServer](#example-FileServer)</li>
    <li>[FileServer (StripPrefix)](#example-FileServer--StripPrefix)</li>
    <li>[Get](#example-Get)</li>
    <li>[Hijacker](#example-Hijacker)</li>
    <li>[ServeMux.Handle](#example-ServeMux-Handle)</li>
    <li>[StripPrefix](#example-StripPrefix)</li>

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

)

HTTP状态码,参见RFC 2616

<pre>const <span id="DefaultMaxHeaderBytes">DefaultMaxHeaderBytes</span> = 1 &lt;&lt; 20 <span class="com">// 1 MB</span>

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

<pre>const <span id="DefaultMaxIdleConnsPerHost">DefaultMaxIdleConnsPerHost</span> = 2</pre>

DefaultMaxIdleConnsPerHost是Transport的MaxIdleConnsPerHost的默认值。

<pre>const <span id="TimeFormat">TimeFormat</span> = "Mon, 02 Jan 2006 15:04:05 GMT"</pre>

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

Variables

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

)

HTTP请求的解析错误。

<pre>var (
<span id="ErrWriteAfterFlush">ErrWriteAfterFlush</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("Conn.Write called after Flush")
<span id="ErrBodyNotAllowed">ErrBodyNotAllowed</span>  = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: request method or response status code does not allow body")
<span id="ErrHijacked">ErrHijacked</span>        = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("Conn has been hijacked")
<span id="ErrContentLength">ErrContentLength</span>   = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("Conn.Write wrote more than the declared Content-Length")

)

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

<pre>var <span id="DefaultClient">DefaultClient</span> = &amp;[Client](#Client){}</pre>

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

<pre>var <span id="DefaultServeMux">DefaultServeMux</span> = [NewServeMux](#NewServeMux)()</pre>

DefaultServeMux是用于Serve的默认ServeMux。

<pre>var <span id="ErrBodyReadAfterClose">ErrBodyReadAfterClose</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: invalid Read on closed Body")</pre>

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

<pre>var <span id="ErrHandlerTimeout">ErrHandlerTimeout</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: Handler timeout")</pre>

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

<pre>var <span id="ErrLineTooLong">ErrLineTooLong</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("header line too long")</pre>
<pre>var <span id="ErrMissingFile">ErrMissingFile</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: no such file")</pre>

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

<pre>var <span id="ErrNoCookie">ErrNoCookie</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: named cookie not present")</pre>
<pre>var <span id="ErrNoLocation">ErrNoLocation</span> = [errors](http://godoc.org/errors).[New](http://godoc.org/errors#New)("http: no Location header in response")</pre>

type ProtocolError

<pre>type ProtocolError struct {
<span id="ProtocolError.ErrorString">ErrorString</span> [string](http://godoc.org/builtin#string)

}

HTTP请求解析错误。

func (*ProtocolError) Error

<pre class="funcdecl">func (err *[ProtocolError](#ProtocolError)) Error() [string](http://godoc.org/builtin#string)</pre>

func CanonicalHeaderKey

<pre class="funcdecl">func CanonicalHeaderKey(s [string](http://godoc.org/builtin#string)) [string](http://godoc.org/builtin#string)</pre>

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

func DetectContentType

<pre class="funcdecl">func DetectContentType(data [][byte](http://godoc.org/builtin#byte)) [string](http://godoc.org/builtin#string)</pre>

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

func ParseHTTPVersion

<pre class="funcdecl">func ParseHTTPVersion(vers [string](http://godoc.org/builtin#string)) (major, minor [int](http://godoc.org/builtin#int), ok [bool](http://godoc.org/builtin#bool))</pre>

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

func ParseTime

<pre class="funcdecl">func ParseTime(text [string](http://godoc.org/builtin#string)) (t [time](http://godoc.org/time).[Time](http://godoc.org/time#Time), err [error](http://godoc.org/builtin#error))</pre>

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

func StatusText

<pre class="funcdecl">func StatusText(code [int](http://godoc.org/builtin#int)) [string](http://godoc.org/builtin#string)</pre>

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

type ConnState

<pre>type ConnState [int](http://godoc.org/builtin#int)</pre>

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

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

)

func (ConnState) String

<pre class="funcdecl">func (c [ConnState](#ConnState)) String() [string](http://godoc.org/builtin#string)</pre>

type Header

<pre>type Header map[[string](http://godoc.org/builtin#string)][][string](http://godoc.org/builtin#string)</pre>

Header代表HTTP头域的键值对。

func (Header) Get

<pre class="funcdecl">func (h [Header](#Header)) Get(key [string](http://godoc.org/builtin#string)) [string](http://godoc.org/builtin#string)</pre>

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

func (Header) Set

<pre class="funcdecl">func (h [Header](#Header)) Set(key, value [string](http://godoc.org/builtin#string))</pre>

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

func (Header) Add

<pre class="funcdecl">func (h [Header](#Header)) Add(key, value [string](http://godoc.org/builtin#string))</pre>

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

func (Header) Del

<pre class="funcdecl">func (h [Header](#Header)) Del(key [string](http://godoc.org/builtin#string))</pre>

Del删除键值对。

func (Header) Write

<pre class="funcdecl">func (h [Header](#Header)) Write(w [io](http://godoc.org/io).[Writer](http://godoc.org/io#Writer)) [error](http://godoc.org/builtin#error)</pre>

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

func (Header) WriteSubset

<pre class="funcdecl">func (h [Header](#Header)) WriteSubset(w [io](http://godoc.org/io).[Writer](http://godoc.org/io#Writer), exclude map[[string](http://godoc.org/builtin#string)][bool](http://godoc.org/builtin#bool)) [error](http://godoc.org/builtin#error)</pre>

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

type Cookie

<pre>type Cookie struct {
<span id="Cookie.Name">Name</span>       [string](http://godoc.org/builtin#string)
<span id="Cookie.Value">Value</span>      [string](http://godoc.org/builtin#string)
<span id="Cookie.Path">Path</span>       [string](http://godoc.org/builtin#string)
<span id="Cookie.Domain">Domain</span>     [string](http://godoc.org/builtin#string)
<span id="Cookie.Expires">Expires</span>    [time](http://godoc.org/time).[Time](http://godoc.org/time#Time)
<span id="Cookie.RawExpires">RawExpires</span> [string](http://godoc.org/builtin#string)
<span class="com">// MaxAge=0表示未设置Max-Age属性</span>
<span class="com">// MaxAge&lt;0表示立刻删除该cookie,等价于"Max-Age: 0"</span>
<span class="com">// MaxAge&gt;0表示存在Max-Age属性,单位是秒</span>
<span id="Cookie.MaxAge">MaxAge</span>   [int](http://godoc.org/builtin#int)
<span id="Cookie.Secure">Secure</span>   [bool](http://godoc.org/builtin#bool)
<span id="Cookie.HttpOnly">HttpOnly</span> [bool](http://godoc.org/builtin#bool)
<span id="Cookie.Raw">Raw</span>      [string](http://godoc.org/builtin#string)
<span id="Cookie.Unparsed">Unparsed</span> [][string](http://godoc.org/builtin#string) <span class="com">// 未解析的“属性-值”对的原始文本</span>

}

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

<pre class="funcdecl">func (c *[Cookie](#Cookie)) String() [string](http://godoc.org/builtin#string)</pre>

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

type CookieJar

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

}

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

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

type Request

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

}

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

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

func NewRequest

<pre class="funcdecl">func NewRequest(method, urlStr [string](http://godoc.org/builtin#string), body [io](http://godoc.org/io).[Reader](http://godoc.org/io#Reader)) (*[Request](#Request), [error](http://godoc.org/builtin#error))</pre>

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

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

func ReadRequest

<pre class="funcdecl">func ReadRequest(b *[bufio](http://godoc.org/bufio).[Reader](http://godoc.org/bufio#Reader)) (req *[Request](#Request), err [error](http://godoc.org/builtin#error))</pre>

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

func (*Request) ProtoAtLeast

<pre class="funcdecl">func (r *[Request](#Request)) ProtoAtLeast(major, minor [int](http://godoc.org/builtin#int)) [bool](http://godoc.org/builtin#bool)</pre>

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

func (*Request) UserAgent

<pre class="funcdecl">func (r *[Request](#Request)) UserAgent() [string](http://godoc.org/builtin#string)</pre>

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

func (*Request) Referer

<pre class="funcdecl">func (r *[Request](#Request)) Referer() [string](http://godoc.org/builtin#string)</pre>

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

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

func (*Request) AddCookie

<pre class="funcdecl">func (r *[Request](#Request)) AddCookie(c *[Cookie](#Cookie))</pre>

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

func (*Request) SetBasicAuth

<pre class="funcdecl">func (r *[Request](#Request)) SetBasicAuth(username, password [string](http://godoc.org/builtin#string))</pre>

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

func (*Request) Write

<pre class="funcdecl">func (r *[Request](#Request)) Write(w [io](http://godoc.org/io).[Writer](http://godoc.org/io#Writer)) [error](http://godoc.org/builtin#error)</pre>

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

<pre>Host

URL Method (defaults to “GET”) Header ContentLength TransferEncoding Body

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

func (*Request) WriteProxy

<pre class="funcdecl">func (r *[Request](#Request)) WriteProxy(w [io](http://godoc.org/io).[Writer](http://godoc.org/io#Writer)) [error](http://godoc.org/builtin#error)</pre>

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

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

func (*Request) Cookies

<pre class="funcdecl">func (r *[Request](#Request)) Cookies() []*[Cookie](#Cookie)</pre>

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

func (*Request) Cookie

<pre class="funcdecl">func (r *[Request](#Request)) Cookie(name [string](http://godoc.org/builtin#string)) (*[Cookie](#Cookie), [error](http://godoc.org/builtin#error))</pre>

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

func (*Request) ParseForm

<pre class="funcdecl">func (r *[Request](#Request)) ParseForm() [error](http://godoc.org/builtin#error)</pre>

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

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

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

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

func (*Request) ParseMultipartForm

<pre class="funcdecl">func (r *[Request](#Request)) ParseMultipartForm(maxMemory [int64](http://godoc.org/builtin#int64)) [error](http://godoc.org/builtin#error)</pre>

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

func (*Request) FormValue

<pre class="funcdecl">func (r *[Request](#Request)) FormValue(key [string](http://godoc.org/builtin#string)) [string](http://godoc.org/builtin#string)</pre>

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

func (*Request) PostFormValue

<pre class="funcdecl">func (r *[Request](#Request)) PostFormValue(key [string](http://godoc.org/builtin#string)) [string](http://godoc.org/builtin#string)</pre>

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

func (*Request) FormFile

<pre class="funcdecl">func (r *[Request](#Request)) FormFile(key [string](http://godoc.org/builtin#string)) ([multipart](http://godoc.org/mime/multipart).[File](http://godoc.org/mime/multipart#File), *[multipart](http://godoc.org/mime/multipart).[FileHeader](http://godoc.org/mime/multipart#FileHeader), [error](http://godoc.org/builtin#error))</pre>

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

func (*Request) MultipartReader

<pre class="funcdecl">func (r *[Request](#Request)) MultipartReader() (*[multipart](http://godoc.org/mime/multipart).[Reader](http://godoc.org/mime/multipart#Reader), [error](http://godoc.org/builtin#error))</pre>

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

type Response

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

}

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

func ReadResponse

<pre class="funcdecl">func ReadResponse(r *[bufio](http://godoc.org/bufio).[Reader](http://godoc.org/bufio#Reader), req *[Request](#Request)) (*[Response](#Response), [error](http://godoc.org/builtin#error))</pre>

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

func (*Response) ProtoAtLeast

<pre class="funcdecl">func (r *[Response](#Response)) ProtoAtLeast(major, minor [int](http://godoc.org/builtin#int)) [bool](http://godoc.org/builtin#bool)</pre>

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

func (*Response) Cookies

<pre class="funcdecl">func (r *[Response](#Response)) Cookies() []*[Cookie](#Cookie)</pre>

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

func (*Response) Location

<pre class="funcdecl">func (r *[Response](#Response)) Location() (*[url](http://godoc.org/net/url).[URL](http://godoc.org/net/url#URL), [error](http://godoc.org/builtin#error))</pre>

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

func (*Response) Write

<pre class="funcdecl">func (r *[Response](#Response)) Write(w [io](http://godoc.org/io).[Writer](http://godoc.org/io#Writer)) [error](http://godoc.org/builtin#error)</pre>

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

<pre>StatusCode

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

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

type ResponseWriter

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

}

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

type Flusher

<pre>type Flusher interface {
<span class="com">// Flush将缓冲中的所有数据发送到客户端</span>
<span id="Flusher.Flush">Flush</span>()

}

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

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

type CloseNotifier

<pre>type CloseNotifier interface {
<span class="com">// CloseNotify返回一个通道,该通道会在客户端连接丢失时接收到唯一的值</span><span class="com"></span>
<span id="CloseNotifier.CloseNotify">CloseNotify</span>() &lt;-chan [bool](http://godoc.org/builtin#bool)

}

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

type Hijacker

<pre>type Hijacker interface {
<span class="com">// Hijack让调用者接管连接,返回连接和关联到该连接的一个缓冲读写器。</span>
<span class="com">// 调用本方法后,HTTP服务端将不再对连接进行任何操作,</span>
<span class="com">// 调用者有责任管理、关闭返回的连接。</span><span class="com"></span>
<span id="Hijacker.Hijack">Hijack</span>() ([net](http://godoc.org/net).[Conn](http://godoc.org/net#Conn), *[bufio](http://godoc.org/bufio).[ReadWriter](http://godoc.org/bufio#ReadWriter), [error](http://godoc.org/builtin#error))

}

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

<div class="panel-group">
    <div class="panel panel-default" id="example-Hijacker">
        <div class="panel-heading" onclick="document.getElementById('ex-Hijacker').style.display = document.getElementById('ex-Hijacker').style.display=='none'?'block':'none';">Example</div>
        <div id="ex-Hijacker" class="panel-collapse collapse">
            <div class="panel-body">
                <pre>http.HandleFunc("/hijack", func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
    http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
    return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}
<span class="com">// Don't forget to close the connection:</span>
defer conn.Close()
bufrw.WriteString("Now we're speaking raw TCP. Say hi: ")
bufrw.Flush()
s, err := bufrw.ReadString('\n')
if err != nil {
    log.Printf("error reading string: %v", err)
    return
}
fmt.Fprintf(bufrw, "You said: %q\nBye.\n", s)
bufrw.Flush()

})