Golang標(biāo)準(zhǔn)庫——net(2)

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

http

http包提供了HTTP客戶端和服務(wù)端的實現(xiàn)。

Get乾蛤、Head险毁、Post和PostForm函數(shù)發(fā)出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"}})

程序在使用完回復(fù)后必須關(guān)閉回復(fù)的主體劣坊。

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

要管理HTTP客戶端的頭域拉一、重定向策略和其他設(shè)置政勃,創(chuàng)建一個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训貌、壓縮和其他設(shè)置尺栖,創(chuàng)建一個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程同時使用。出于效率考慮懒叛,應(yīng)該一次建立丸冕、盡量重用。

ListenAndServe使用指定的監(jiān)聽地址和處理器啟動一個HTTP服務(wù)端薛窥。處理器參數(shù)通常是nil胖烛,這表示采用包變量DefaultServeMux作為處理器。Handle和HandleFunc函數(shù)可以向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))

要管理服務(wù)端的行為佩番,可以創(chuàng)建一個自定義的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狀態(tài)碼,參見RFC 2616

const DefaultMaxHeaderBytes = 1 << 20 // 1 MB

DefaultMaxHeaderBytes是HTTP請求的頭域最大允許長度罢杉√宋罚可以通過設(shè)置Server.MaxHeaderBytes字段來覆蓋。

const DefaultMaxIdleConnsPerHost = 2

DefaultMaxIdleConnsPerHost是Transport的MaxIdleConnsPerHost的默認(rèn)值滩租。

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

TimeFormat是當(dāng)解析或生產(chǎn)HTTP頭域中的時間時赋秀,用與time.Parse或time.Format函數(shù)的時間格式。這種格式類似time.RFC1123但強(qiáng)制采用GMT時區(qū)持际。

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服務(wù)端返回的錯誤。

var DefaultClient = &Client{}

DefaultClient是用于包函數(shù)Get蜘欲、Head和Post的默認(rèn)Client益眉。

var DefaultServeMux = NewServeMux()

DefaultServeMux是用于Serve的默認(rèn)ServeMux。

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

在Resquest或Response的Body字段已經(jīng)關(guān)閉后,試圖從中讀取時郭脂,就會返回ErrBodyReadAfterClose年碘。這個錯誤一般發(fā)生在:HTTP處理器中調(diào)用完ResponseWriter 接口的WriteHeader或Write后從請求中讀取數(shù)據(jù)的時候。

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

在處理器超時以后調(diào)用ResponseWriter接口的Write方法展鸡,就會返回ErrHandlerTimeout屿衅。

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

當(dāng)請求中沒有提供給FormFile函數(shù)的文件字段名,或者該字段名不是文件字段時莹弊,該函數(shù)就會返回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函數(shù)返回頭域(表示為Header類型)的鍵s的規(guī)范化格式忍弛。規(guī)范化過程中讓單詞首字母和'-'后的第一個字母大寫响迂,其余字母小寫。例如细疚,"accept-encoding"規(guī)范化為"Accept-Encoding"蔗彤。

func DetectContentType

func DetectContentType(data []byte) string

DetectContentType函數(shù)實現(xiàn)了http://mimesniff.spec.whatwg.org/描述的算法,用于確定數(shù)據(jù)的Content-Type疯兼。函數(shù)總是返回一個合法的MIME類型然遏;如果它不能確定數(shù)據(jù)的類型,將返回"application/octet-stream"吧彪。它最多檢查數(shù)據(jù)的前512字節(jié)待侵。

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狀態(tài)碼code對應(yīng)的文本香拉,如220對應(yīng)"OK"啦扬。如果code是未知的狀態(tài)碼,會返回""凫碌。

type ConnState

type ConnState int

ConnState代表一個客戶端到服務(wù)端的連接的狀態(tài)扑毡。本類型用于可選的Server.ConnState回調(diào)函數(shù)。

const (
    // StateNew代表一個新的連接盛险,將要立刻發(fā)送請求瞄摊。
    // 連接從這個狀態(tài)開始,然后轉(zhuǎn)變?yōu)镾tateAlive或StateClosed苦掘。
    StateNew ConnState = iota
    // StateActive代表一個已經(jīng)讀取了請求數(shù)據(jù)1到多個字節(jié)的連接换帜。
    // 用于StateAlive的Server.ConnState回調(diào)函數(shù)在將連接交付給處理器之前被觸發(fā),
    // 等到請求被處理完后鹤啡,Server.ConnState回調(diào)函數(shù)再次被觸發(fā)惯驼。
    // 在請求被處理后,連接狀態(tài)改變?yōu)镾tateClosed、StateHijacked或StateIdle祟牲。
    StateActive
    // StateIdle代表一個已經(jīng)處理完了請求隙畜、處在閑置狀態(tài)、等待新請求的連接说贝。
    // 連接狀態(tài)可以從StateIdle改變?yōu)镾tateActive或StateClosed议惰。
    StateIdle
    // 代表一個被劫持的連接。這是一個終止?fàn)顟B(tài)乡恕,不會轉(zhuǎn)變?yōu)镾tateClosed言询。
    StateHijacked
    // StateClosed代表一個關(guān)閉的連接。
    // 這是一個終止?fàn)顟B(tài)傲宜。被劫持的連接不會轉(zhuǎn)變?yōu)镾tateClosed倍试。
    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返回鍵對應(yīng)的第一個值蛋哭,如果鍵不存在會返回""县习。如要獲取該鍵對應(yīng)的值切片,請直接用規(guī)范格式的鍵訪問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以有線格式將頭域?qū)懭雡跷叉。

func (Header) WriteSubset

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

WriteSubset以有線格式將頭域?qū)懭雡逸雹。當(dāng)exclude不為nil時,如果h的鍵值對的鍵在exclude中存在且其對應(yīng)值為真云挟,該鍵值對就不會被寫入w梆砸。

type Cookie

type Cookie struct {
    Name       string
    Value      string
    Path       string
    Domain     string
    Expires    time.Time
    RawExpires string
    // MaxAge=0表示未設(shè)置Max-Age屬性
    // MaxAge<0表示立刻刪除該cookie,等價于"Max-Age: 0"
    // MaxAge>0表示存在Max-Age屬性园欣,單位是秒
    MaxAge   int
    Secure   bool
    HttpOnly bool
    Raw      string
    Unparsed []string // 未解析的“屬性-值”對的原始文本
}

Cookie代表一個出現(xiàn)在HTTP回復(fù)的頭域中Set-Cookie頭的值里或者HTTP請求的頭域中Cookie頭的值里的HTTP cookie帖世。

func (*Cookie) String

func (c *Cookie) String() string

String返回該cookie的序列化結(jié)果。如果只設(shè)置了Name和Value字段沸枯,序列化結(jié)果可用于HTTP請求的Cookie頭或者HTTP回復(fù)的Set-Cookie頭日矫;如果設(shè)置了其他字段,序列化結(jié)果只能用于HTTP回復(fù)的Set-Cookie頭绑榴。

type CookieJar

type CookieJar interface {
    // SetCookies管理從u的回復(fù)中收到的cookie
    // 根據(jù)其策略和實現(xiàn)哪轿,它可以選擇是否存儲cookie
    SetCookies(u *url.URL, cookies []*Cookie)
    // Cookies返回發(fā)送請求到u時應(yīng)使用的cookie
    // 本方法有責(zé)任遵守RFC 6265規(guī)定的標(biāo)準(zhǔn)cookie限制
    Cookies(u *url.URL) []*Cookie
}

CookieJar管理cookie的存儲和在HTTP請求中的使用。CookieJar的實現(xiàn)必須能安全的被多個go程同時使用翔怎。

net/http/cookiejar包提供了一個CookieJar的實現(xiàn)窃诉。

type Request

type Request struct {
    // Method指定HTTP方法(GET、POST、PUT等)褐奴。對客戶端按脚,""代表GET。
    Method string
    // URL在服務(wù)端表示被請求的URI敦冬,在客戶端表示要訪問的URL辅搬。
    //
    // 在服務(wù)端,URL字段是解析請求行的URI(保存在RequestURI字段)得到的脖旱,
    // 對大多數(shù)請求來說堪遂,除了Path和RawQuery之外的字段都是空字符串。
    // (參見RFC 2616, Section 5.1.2)
    //
    // 在客戶端萌庆,URL的Host字段指定了要連接的服務(wù)器溶褪,
    // 而Request的Host字段(可選地)指定要發(fā)送的HTTP請求的Host頭的值。
    URL *url.URL
    // 接收到的請求的協(xié)議版本践险。本包生產(chǎn)的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規(guī)定頭域的鍵名(頭名)是大小寫敏感的,請求的解析器通過規(guī)范化頭域的鍵名來實現(xiàn)這點(diǎn)巍虫。
    // 在客戶端的請求彭则,可能會被自動添加或重寫Header中的特定的頭,參見Request.Write方法占遥。
    Header Header
    // Body是請求的主體俯抖。
    //
    // 在客戶端,如果Body是nil表示該請求沒有主體買入GET請求瓦胎。
    // Client的Transport字段會負(fù)責(zé)調(diào)用Body的Close方法芬萍。
    //
    // 在服務(wù)端,Body字段總是非nil的搔啊;但在沒有主體時柬祠,讀取Body會立刻返回EOF。
    // Server會關(guān)閉請求的主體坯癣,ServeHTTP處理器不需要關(guān)閉Body字段瓶盛。
    Body io.ReadCloser
    // ContentLength記錄相關(guān)內(nèi)容的長度最欠。
    // 如果為-1示罗,表示長度未知,如果>=0芝硬,表示可以從Body字段讀取ContentLength字節(jié)數(shù)據(jù)蚜点。
    // 在客戶端,如果Body非nil而該字段為0拌阴,表示不知道Body的長度绍绘。
    ContentLength int64
    // TransferEncoding按從最外到最里的順序列出傳輸編碼,空切片表示"identity"編碼。
    // 本字段一般會被忽略陪拘。當(dāng)發(fā)送或接受請求時厂镇,會自動添加或移除"chunked"傳輸編碼。
    TransferEncoding []string
    // Close在服務(wù)端指定是否在回復(fù)請求后關(guān)閉連接左刽,在客戶端指定是否在發(fā)送請求后關(guān)閉連接捺信。
    Close bool
    // 在服務(wù)端,Host指定URL會在其上尋找資源的主機(jī)欠痴。
    // 根據(jù)RFC 2616迄靠,該值可以是Host頭的值,或者URL自身提供的主機(jī)名喇辽。
    // Host的格式可以是"host:port"晾捏。
    //
    // 在客戶端丁逝,請求的Host字段(可選地)用來重寫請求的Host頭。
    // 如過該字段為"",Request.Write方法會使用URL字段的Host补履。
    Host string
    // Form是解析好的表單數(shù)據(jù),包括URL字段的query參數(shù)和POST或PUT的表單數(shù)據(jù)铅协。
    // 本字段只有在調(diào)用ParseForm后才有效尉间。在客戶端,會忽略請求中的本字段而使用Body替代缨硝。
    Form url.Values
    // PostForm是解析好的POST或PUT的表單數(shù)據(jù)摩钙。
    // 本字段只有在調(diào)用ParseForm后才有效。在客戶端查辩,會忽略請求中的本字段而使用Body替代胖笛。
    PostForm url.Values
    // MultipartForm是解析好的多部件表單,包括上傳的文件宜岛。
    // 本字段只有在調(diào)用ParseMultipartForm后才有效长踊。
    // 在客戶端,會忽略請求中的本字段而使用Body替代萍倡。
    MultipartForm *multipart.Form
    // Trailer指定了會在請求主體之后發(fā)送的額外的頭域身弊。
    //
    // 在服務(wù)端,Trailer字段必須初始化為只有trailer鍵列敲,所有鍵都對應(yīng)nil值阱佛。
    // (客戶端會聲明哪些trailer會發(fā)送)
    // 在處理器從Body讀取時,不能使用本字段戴而。
    // 在從Body的讀取返回EOF后凑术,Trailer字段會被更新完畢并包含非nil的值。
    // (如果客戶端發(fā)送了這些鍵值對)所意,此時才可以訪問本字段淮逊。
    //
    // 在客戶端催首,Trail必須初始化為一個包含將要發(fā)送的鍵值對的映射。(值可以是nil或其終值)
    // ContentLength字段必須是0或-1泄鹏,以啟用"chunked"傳輸編碼發(fā)送請求郎任。
    // 在開始發(fā)送請求后,Trailer可以在讀取請求主體期間被修改备籽,
    // 一旦請求主體返回EOF涝滴,調(diào)用者就不可再修改Trailer。
    //
    // 很少有HTTP客戶端胶台、服務(wù)端或代理支持HTTP trailer歼疮。
    Trailer Header
    // RemoteAddr允許HTTP服務(wù)器和其他軟件記錄該請求的來源地址,一般用于日志诈唬。
    // 本字段不是ReadRequest函數(shù)填寫的韩脏,也沒有定義格式。
    // 本包的HTTP服務(wù)器會在調(diào)用處理器之前設(shè)置RemoteAddr為"IP:port"格式的地址铸磅。
    // 客戶端會忽略請求中的RemoteAddr字段赡矢。
    RemoteAddr string
    // RequestURI是被客戶端發(fā)送到服務(wù)端的請求的請求行中未修改的請求URI
    // (參見RFC 2616, Section 5.1)
    // 一般應(yīng)使用URI字段,在客戶端設(shè)置請求的本字段會導(dǎo)致錯誤阅仔。
    RequestURI string
    // TLS字段允許HTTP服務(wù)器和其他軟件記錄接收到該請求的TLS連接的信息
    // 本字段不是ReadRequest函數(shù)填寫的吹散。
    // 對啟用了TLS的連接,本包的HTTP服務(wù)器會在調(diào)用處理器之前設(shè)置TLS字段八酒,否則將設(shè)TLS為nil空民。
    // 客戶端會忽略請求中的TLS字段。
    TLS *tls.ConnectionState
}

Request類型代表一個服務(wù)端接受到的或者客戶端發(fā)送出去的HTTP請求羞迷。

Request各字段的意義和用途在服務(wù)端和客戶端是不同的界轩。除了字段本身上方文檔,還可參見Request.Write方法和RoundTripper接口的文檔衔瓮。

func NewRequest

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

NewRequest使用指定的方法浊猾、網(wǎng)址和可選的主題創(chuàng)建并返回一個新的*Request。

如果body參數(shù)實現(xiàn)了io.Closer接口热鞍,Request返回值的Body 字段會被設(shè)置為body葫慎,并會被Client類型的Do、Post和PostFOrm方法以及Transport.RoundTrip方法關(guān)閉薇宠。

func ReadRequest

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

ReadRequest從b讀取并解析出一個HTTP請求偷办。(本函數(shù)主要用在服務(wù)端從下層獲取請求)

func (*Request) ProtoAtLeast

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

ProtoAtLeast報告該請求使用的HTTP協(xié)議版本至少是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內(nèi)部用逗號分隔屬性)蚓再。

func (*Request) SetBasicAuth

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

SetBasicAuth使用提供的用戶名和密碼,采用HTTP基本認(rèn)證包各,設(shè)置請求的Authorization頭摘仅。HTTP基本認(rèn)證會明碼傳送用戶名和密碼。

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字段未顯式設(shè)置為["identity"],Write方法會顯式添加"Transfer-Encoding: chunked"到請求的頭域护姆。Body字段會在發(fā)送完請求后關(guān)閉矾端。

func (*Request) WriteProxy

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

WriteProxy類似Write但會將請求以HTTP代理期望的格式發(fā)送。

尤其是卵皂,按照RFC 2616 Section 5.1.2秩铆,WriteProxy會使用絕對URI(包括協(xié)議和主機(jī)名)來初始化請求的第1行(Request-URI行)。無論何種情況灯变,WriteProxy都會使用r.Host或r.URL.Host設(shè)置Host頭豺旬。

func (*Request) Cookies

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

Cookies解析并返回該請求的Cookie頭設(shè)置的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中的查詢字符串,并將解析結(jié)果更新到r.Form字段膝捞。

對于POST或PUT請求坦刀,ParseForm還會將body當(dāng)作表單解析,并將結(jié)果既更新到r.PostForm也更新到r.Form蔬咬。解析結(jié)果中鲤遥,POST或PUT請求主體要優(yōu)先于URL查詢字符串(同名變量,主體的值在查詢字符串的值前面)林艘。

如果請求的主體的大小沒有被MaxBytesReader函數(shù)設(shè)定限制盖奈,其大小默認(rèn)限制為開頭10MB。

ParseMultipartForm會自動調(diào)用ParseForm狐援。重復(fù)調(diào)用本方法是無意義的钢坦。

func (*Request) ParseMultipartForm

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

ParseMultipartForm將請求的主體作為multipart/form-data解析究孕。請求的整個主體都會被解析,得到的文件記錄最多maxMemery字節(jié)保存在內(nèi)存爹凹,其余部分保存在硬盤的temp文件里厨诸。如果必要,ParseMultipartForm會自行調(diào)用ParseForm禾酱。重復(fù)調(diào)用本方法是無意義的微酬。

func (*Request) FormValue

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

FormValue返回key為鍵查詢r.Form字段得到結(jié)果[]string切片的第一個值。POST和PUT主體中的同名參數(shù)優(yōu)先于URL查詢字符串颤陶。如果必要颗管,本函數(shù)會隱式調(diào)用ParseMultipartForm和ParseForm。

func (*Request) PostFormValue

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

PostFormValue返回key為鍵查詢r.PostForm字段得到結(jié)果[]string切片的第一個值滓走。如果必要垦江,本函數(shù)會隱式調(diào)用ParseMultipartForm和ParseForm。

func (*Request) FormFile

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

FormFile返回以key為鍵查詢r.MultipartForm字段得到結(jié)果中的第一個文件和它的信息闲坎。如果必要疫粥,本函數(shù)會隱式調(diào)用ParseMultipartForm和ParseForm。查詢失敗會返回ErrMissingFile錯誤腰懂。

func (*Request) MultipartReader

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

如果請求是multipart/form-data POST請求梗逮,MultipartReader返回一個multipart.Reader接口,否則返回nil和一個錯誤绣溜。使用本函數(shù)代替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保管頭域的鍵值對怖喻。
    // 如果回復(fù)中有多個頭的鍵相同底哗,Header中保存為該鍵對應(yīng)用逗號分隔串聯(lián)起來的這些頭的值
    // (參見RFC 2616 Section 4.2)
    // 被本結(jié)構(gòu)體中的其他字段復(fù)制保管的頭(如ContentLength)會從Header中刪掉。
    //
    // Header中的鍵都是規(guī)范化的锚沸,參見CanonicalHeaderKey函數(shù)
    Header Header
    // Body代表回復(fù)的主體跋选。
    // Client類型和Transport類型會保證Body字段總是非nil的,即使回復(fù)沒有主體或主體長度為0哗蜈。
    // 關(guān)閉主體是調(diào)用者的責(zé)任前标。
    // 如果服務(wù)端采用"chunked"傳輸編碼發(fā)送的回復(fù),Body字段會自動進(jìn)行解碼距潘。
    Body io.ReadCloser
    // ContentLength記錄相關(guān)內(nèi)容的長度炼列。
    // 其值為-1表示長度未知(采用chunked傳輸編碼)
    // 除非對應(yīng)的Request.Method是"HEAD",其值>=0表示可以從Body讀取的字節(jié)數(shù)
    ContentLength int64
    // TransferEncoding按從最外到最里的順序列出傳輸編碼音比,空切片表示"identity"編碼俭尖。
    TransferEncoding []string
    // Close記錄頭域是否指定應(yīng)在讀取完主體后關(guān)閉連接。(即Connection頭)
    // 該值是給客戶端的建議,Response.Write方法的ReadResponse函數(shù)都不會關(guān)閉連接稽犁。
    Close bool
    // Trailer字段保存和頭域相同格式的trailer鍵值對焰望,和Header字段相同類型
    Trailer Header
    // Request是用來獲取此回復(fù)的請求
    // Request的Body字段是nil(因為已經(jīng)被用掉了)
    // 這個字段是被Client類型發(fā)出請求并獲得回復(fù)后填充的
    Request *Request
    // TLS包含接收到該回復(fù)的TLS連接的信息。 對未加密的回復(fù)缭付,本字段為nil柿估。
    // 返回的指針是被(同一TLS連接接收到的)回復(fù)共享的循未,不應(yīng)被修改陷猫。
    TLS *tls.ConnectionState
}

Response代表一個HTTP請求的回復(fù)。

func ReadResponse

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

ReadResponse從r讀取并返回一個HTTP 回復(fù)的妖。req參數(shù)是可選的绣檬,指定該回復(fù)對應(yīng)的請求(即是對該請求的回復(fù))。如果是nil嫂粟,將假設(shè)請求是GET請求娇未。客戶端必須在結(jié)束resp.Body的讀取后關(guān)閉它办悟。讀取完畢并關(guān)閉后颈娜,客戶端可以檢查resp.Trailer字段獲取回復(fù)的trailer的鍵值對凿试。(本函數(shù)主要用在客戶端從下層獲取回復(fù))

func (*Response) ProtoAtLeast

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

ProtoAtLeast報告該回復(fù)使用的HTTP協(xié)議版本至少是major.minor。

func (*Response) Cookies

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

Cookies解析并返回該回復(fù)中的Set-Cookie頭設(shè)置的cookie平夜。

func (*Response) Location

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

Location返回該回復(fù)的Location頭設(shè)置的URL。相對地址的重定向會相對于該回復(fù)對應(yīng)的請求來確定絕對地址卸亮。如果回復(fù)中沒有Location頭忽妒,會返回nil, ErrNoLocation。

func (*Response) Write

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

Write以有線格式將回復(fù)寫入w(用于將回復(fù)寫入下層TCPConn等)兼贸。本方法會考慮如下字段:

StatusCode
ProtoMajor
ProtoMinor
Request.Method
TransferEncoding
Trailer
Body
ContentLength
Header(不規(guī)范的鍵名和它對應(yīng)的值會導(dǎo)致不可預(yù)知的行為)

Body字段在發(fā)送完回復(fù)后會被關(guān)閉段直。

type ResponseWriter

type ResponseWriter interface {
    // Header返回一個Header類型值,該值會被WriteHeader方法發(fā)送溶诞。
    // 在調(diào)用WriteHeader或Write方法后再改變該對象是沒有意義的鸯檬。
    Header() Header
    // WriteHeader該方法發(fā)送HTTP回復(fù)的頭域和狀態(tài)碼。
    // 如果沒有被顯式調(diào)用螺垢,第一次調(diào)用Write時會觸發(fā)隱式調(diào)用WriteHeader(http.StatusOK)
    // WriterHeader的顯式調(diào)用主要用于發(fā)送錯誤碼喧务。
    WriteHeader(int)
    // Write向連接中寫入作為HTTP的一部分回復(fù)的數(shù)據(jù)。
    // 如果被調(diào)用時還未調(diào)用WriteHeader甩苛,本方法會先調(diào)用WriteHeader(http.StatusOK)
    // 如果Header中沒有"Content-Type"鍵蹂楣,
    // 本方法會使用包函數(shù)DetectContentType檢查數(shù)據(jù)的前512字節(jié),將返回值作為該鍵的值讯蒲。
    Write([]byte) (int, error)
}

ResponseWriter接口被HTTP處理器用于構(gòu)造HTTP回復(fù)痊土。

type Flusher

type Flusher interface {
    // Flush將緩沖中的所有數(shù)據(jù)發(fā)送到客戶端
    Flush()
}

HTTP處理器ResponseWriter接口參數(shù)的下層如果實現(xiàn)了Flusher接口,可以讓HTTP處理器將緩沖中的數(shù)據(jù)發(fā)送到客戶端墨林。

注意:即使ResponseWriter接口的下層支持Flush方法赁酝,如果客戶端是通過HTTP代理連接的犯祠,緩沖中的數(shù)據(jù)也可能直到回復(fù)完畢才被傳輸?shù)娇蛻舳恕?/p>

type CloseNotifier

type CloseNotifier interface {
    // CloseNotify返回一個通道,該通道會在客戶端連接丟失時接收到唯一的值
    CloseNotify() <-chan bool
}

HTTP處理器ResponseWriter接口參數(shù)的下層如果實現(xiàn)了CloseNotifier接口酌呆,可以讓用戶檢測下層的連接是否停止衡载。如果客戶端在回復(fù)準(zhǔn)備好之前關(guān)閉了連接,該機(jī)制可以用于取消服務(wù)端耗時較長的操作隙袁。

type Hijacker

type Hijacker interface {
    // Hijack讓調(diào)用者接管連接痰娱,返回連接和關(guān)聯(lián)到該連接的一個緩沖讀寫器。
    // 調(diào)用本方法后菩收,HTTP服務(wù)端將不再對連接進(jìn)行任何操作梨睁,
    // 調(diào)用者有責(zé)任管理、關(guān)閉返回的連接娜饵。
    Hijack() (net.Conn, *bufio.ReadWriter, error)
}

HTTP處理器ResponseWriter接口參數(shù)的下層如果實現(xiàn)了Hijacker接口坡贺,可以讓HTTP處理器接管該連接。

type RoundTripper

type RoundTripper interface {
    // RoundTrip執(zhí)行單次HTTP事務(wù)箱舞,接收并發(fā)揮請求req的回復(fù)遍坟。
    // RoundTrip不應(yīng)試圖解析/修改得到的回復(fù)。
    // 尤其要注意晴股,只要RoundTrip獲得了一個回復(fù)愿伴,不管該回復(fù)的HTTP狀態(tài)碼如何,
    // 它必須將返回值err設(shè)置為nil队魏。
    // 非nil的返回值err應(yīng)該留給獲取回復(fù)失敗的情況公般。
    // 類似的,RoundTrip不能試圖管理高層次的細(xì)節(jié)胡桨,如重定向官帘、認(rèn)證、cookie昧谊。
    //
    // 除了從請求的主體讀取并關(guān)閉主體之外刽虹,RoundTrip不應(yīng)修改請求,包括(請求的)錯誤呢诬。
    // RoundTrip函數(shù)接收的請求的URL和Header字段可以保證是(被)初始化了的涌哲。
    RoundTrip(*Request) (*Response, error)
}

RoundTripper接口是具有執(zhí)行單次HTTP事務(wù)的能力(接收指定請求的回復(fù))的接口。

RoundTripper接口的類型必須可以安全的被多線程同時使用尚镰。

type Transport

type Transport struct {
    // Proxy指定一個對給定請求返回代理的函數(shù)阀圾。
    // 如果該函數(shù)返回了非nil的錯誤值,請求的執(zhí)行就會中斷并返回該錯誤狗唉。
    // 如果Proxy為nil或返回nil的*URL置初烘,將不使用代理。
    Proxy func(*Request) (*url.URL, error)
    // Dial指定創(chuàng)建TCP連接的撥號函數(shù)。如果Dial為nil肾筐,會使用net.Dial哆料。
    Dial func(network, addr string) (net.Conn, error)
    // TLSClientConfig指定用于tls.Client的TLS配置信息。
    // 如果該字段為nil吗铐,會使用默認(rèn)的配置信息东亦。
    TLSClientConfig *tls.Config
    // TLSHandshakeTimeout指定等待TLS握手完成的最長時間。零值表示不設(shè)置超時唬渗。
    TLSHandshakeTimeout time.Duration
    // 如果DisableKeepAlives為真典阵,會禁止不同HTTP請求之間TCP連接的重用。
    DisableKeepAlives bool
    // 如果DisableCompression為真谣妻,會禁止Transport在請求中沒有Accept-Encoding頭時萄喳,
    // 主動添加"Accept-Encoding: gzip"頭卒稳,以獲取壓縮數(shù)據(jù)蹋半。
    // 如果Transport自己請求gzip并得到了壓縮后的回復(fù),它會主動解壓縮回復(fù)的主體充坑。
    // 但如果用戶顯式的請求gzip壓縮數(shù)據(jù)减江,Transport是不會主動解壓縮的。
    DisableCompression bool
    // 如果MaxIdleConnsPerHost!=0捻爷,會控制每個主機(jī)下的最大閑置連接辈灼。
    // 如果MaxIdleConnsPerHost==0,會使用DefaultMaxIdleConnsPerHost也榄。
    MaxIdleConnsPerHost int
    // ResponseHeaderTimeout指定在發(fā)送完請求(包括其可能的主體)之后巡莹,
    // 等待接收服務(wù)端的回復(fù)的頭域的最大時間。零值表示不設(shè)置超時甜紫。
    // 該時間不包括獲取回復(fù)主體的時間降宅。
    ResponseHeaderTimeout time.Duration
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

Transport類型實現(xiàn)了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使用的默認(rèn)RoundTripper接口拓型。它會根據(jù)需要創(chuàng)建網(wǎng)絡(luò)連接额嘿,并緩存以便在之后的請求中重用這些連接。它使用環(huán)境變量HTTP_PROXY和NO_PROXY(或http_proxy和no_proxy)指定的HTTP代理劣挫。

func (*Transport) RegisterProtocol

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

RegisterProtocol注冊一個新的名為scheme的協(xié)議册养。t會將使用scheme協(xié)議的請求轉(zhuǎn)交給rt。rt有責(zé)任模擬HTTP請求的語義压固。

RegisterProtocol可以被其他包用于提供"ftp"或"file"等協(xié)議的實現(xiàn)球拦。

func (*Transport) RoundTrip

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

RoundTrip方法實現(xiàn)了RoundTripper接口。

高層次的HTTP客戶端支持(如管理cookie和重定向)請參見Get、Post等函數(shù)和Client類型刘莹。

func (*Transport) CloseIdleConnections

func (t *Transport) CloseIdleConnections()

CloseIdleConnections關(guān)閉所有之前的請求建立但目前處于閑置狀態(tài)的連接阎毅。本方法不會中斷正在使用的連接。

func (*Transport) CancelRequest

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

CancelRequest通過關(guān)閉請求所在的連接取消一個執(zhí)行中的請求点弯。

type Client

type Client struct {
    // Transport指定執(zhí)行獨(dú)立扇调、單次HTTP請求的機(jī)制。
    // 如果Transport為nil抢肛,則使用DefaultTransport狼钮。
    Transport RoundTripper
    // CheckRedirect指定處理重定向的策略。
    // 如果CheckRedirect不為nil捡絮,客戶端會在執(zhí)行重定向之前調(diào)用本函數(shù)字段熬芜。
    // 參數(shù)req和via是將要執(zhí)行的請求和已經(jīng)執(zhí)行的請求(切片,越新的請求越靠后)福稳。
    // 如果CheckRedirect返回一個錯誤涎拉,本類型的Get方法不會發(fā)送請求req,
    // 而是返回之前得到的最后一個回復(fù)和該錯誤的圆。(包裝進(jìn)url.Error類型里)
    //
    // 如果CheckRedirect為nil鼓拧,會采用默認(rèn)策略:連續(xù)10此請求后停止。
    CheckRedirect func(req *Request, via []*Request) error
    // Jar指定cookie管理器越妈。
    // 如果Jar為nil季俩,請求中不會發(fā)送cookie,回復(fù)中的cookie會被忽略梅掠。
    Jar CookieJar
    // Timeout指定本類型的值執(zhí)行請求的時間限制酌住。
    // 該超時限制包括連接時間、重定向和讀取回復(fù)主體的時間阎抒。
    // 計時器會在Head酪我、Get、Post或Do方法返回后繼續(xù)運(yùn)作并在超時后中斷回復(fù)主體的讀取挠蛉。
    //
    // Timeout為零值表示不設(shè)置超時祭示。
    //
    // Client實例的Transport字段必須支持CancelRequest方法,
    // 否則Client會在試圖用Head谴古、Get质涛、Post或Do方法執(zhí)行請求時返回錯誤。
    // 本類型的Transport字段默認(rèn)值(DefaultTransport)支持CancelRequest方法掰担。
    Timeout time.Duration
}

Client類型代表HTTP客戶端汇陆。它的零值(DefaultClient)是一個可用的使用DefaultTransport的客戶端。

Client的Transport字段一般會含有內(nèi)部狀態(tài)(緩存TCP連接)带饱,因此Client類型值應(yīng)盡量被重用而不是每次需要都創(chuàng)建新的毡代。Client類型值可以安全的被多個go程同時使用阅羹。

Client類型的層次比RoundTripper接口(如Transport)高,還會管理HTTP的cookie和重定向等細(xì)節(jié)教寂。

func (*Client) Do

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

Do方法發(fā)送請求捏鱼,返回HTTP回復(fù)。它會遵守客戶端c設(shè)置的策略(如重定向酪耕、cookie导梆、認(rèn)證)。

如果客戶端的策略(如重定向)返回錯誤或存在HTTP協(xié)議錯誤時迂烁,本方法將返回該錯誤看尼;如果回應(yīng)的狀態(tài)碼不是2xx,本方法并不會返回錯誤盟步。

如果返回值err為nil藏斩,resp.Body總是非nil的,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它却盘。如果返回值resp的主體未關(guān)閉狰域,c下層的RoundTripper接口(一般為Transport類型)可能無法重用resp主體下層保持的TCP連接去執(zhí)行之后的請求。

請求的主體谷炸,如果非nil北专,會在執(zhí)行后被c.Transport關(guān)閉,即使出現(xiàn)錯誤旬陡。

一般應(yīng)使用Get、Post或PostForm方法代替Do方法语婴。

func (*Client) Head

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

Head向指定的URL發(fā)出一個HEAD請求描孟,如果回應(yīng)的狀態(tài)碼如下,Head會在調(diào)用c.CheckRedirect后執(zhí)行重定向:

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發(fā)出一個GET請求砰左,如果回應(yīng)的狀態(tài)碼如下匿醒,Get會在調(diào)用c.CheckRedirect后執(zhí)行重定向:

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

如果c.CheckRedirect執(zhí)行失敗或存在HTTP協(xié)議錯誤時,本方法將返回該錯誤缠导;如果回應(yīng)的狀態(tài)碼不是2xx廉羔,本方法并不會返回錯誤鳞溉。如果返回值err為nil雹舀,resp.Body總是非nil的绝页,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它芹壕。

func (*Client) Post

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

Post向指定的URL發(fā)出一個POST請求嚷兔。bodyType為POST數(shù)據(jù)的類型豆村, body為POST數(shù)據(jù)趾疚,作為請求的主體奖蔓。如果參數(shù)body實現(xiàn)了io.Closer接口立膛,它會在發(fā)送請求后被關(guān)閉揪罕。調(diào)用者有責(zé)任在讀取完返回值resp的主體后關(guān)閉它梯码。

func (*Client) PostForm

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

PostForm向指定的URL發(fā)出一個POST請求,url.Values類型的data會被編碼為請求的主體好啰。POST數(shù)據(jù)的類型一般會設(shè)為"application/x-www-form-urlencoded"轩娶。如果返回值err為nil,resp.Body總是非nil的框往,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它罢坝。

type Handler

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

實現(xiàn)了Handler接口的對象可以注冊到HTTP服務(wù)端,為特定的路徑及其子樹提供服務(wù)搅窿。

ServeHTTP應(yīng)該將回復(fù)的頭域和數(shù)據(jù)寫入ResponseWriter接口然后返回嘁酿。返回標(biāo)志著該請求已經(jīng)結(jié)束,HTTP服務(wù)端可以轉(zhuǎn)移向該連接上的下一個請求男应。

func NotFoundHandler

func NotFoundHandler() Handler

NotFoundHandler返回一個簡單的請求處理器闹司,該處理器會對每個請求都回復(fù)"404 page not found"。

func RedirectHandler

func RedirectHandler(url string, code int) Handler

RedirectHandler返回一個請求處理器沐飘,該處理器會對每個請求都使用狀態(tài)碼code重定向到網(wǎng)址url游桩。

func TimeoutHandler

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

TimeoutHandler返回一個采用指定時間限制的請求處理器。

返回的Handler會調(diào)用h.ServeHTTP去處理每個請求耐朴,但如果某一次調(diào)用耗時超過了時間限制借卧,該處理器會回復(fù)請求狀態(tài)碼503 Service Unavailable,并將msg作為回復(fù)的主體(如果msg為空字符串筛峭,將發(fā)送一個合理的默認(rèn)信息)铐刘。在超時后,h對它的ResponseWriter接口參數(shù)的寫入操作會返回ErrHandlerTimeout影晓。

func StripPrefix

func StripPrefix(prefix string, h Handler) Handler

StripPrefix返回一個處理器镰吵,該處理器會將請求的URL.Path字段中給定前綴prefix去除后再交由h處理。StripPrefix會向URL.Path字段中沒有給定前綴的請求回復(fù)404 page not found挂签。

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

HandlerFunc type是一個適配器疤祭,通過類型轉(zhuǎn)換讓我們可以將普通的函數(shù)作為HTTP處理器使用。如果f是一個具有適當(dāng)簽名的函數(shù)饵婆,HandlerFunc(f)通過調(diào)用f實現(xiàn)了Handler接口勺馆。

func (HandlerFunc) ServeHTTP

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

ServeHTTP方法會調(diào)用f(w, r)

type ServeMux

type ServeMux struct {
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

ServeMux類型是HTTP請求的多路轉(zhuǎn)接器。它會將每一個接收的請求的URL與一個注冊模式的列表進(jìn)行匹配侨核,并調(diào)用和URL最匹配的模式的處理器草穆。

模式是固定的、由根開始的路徑芹关,如"/favicon.ico"续挟,或由根開始的子樹,如"/images/"(注意結(jié)尾的斜杠)侥衬。較長的模式優(yōu)先于較短的模式诗祸,因此如果模式"/images/"和"/images/thumbnails/"都注冊了處理器跑芳,后一個處理器會用于路徑以"/images/thumbnails/"開始的請求,前一個處理器會接收到其余的路徑在"/images/"子樹下的請求直颅。

注意博个,因為以斜杠結(jié)尾的模式代表一個由根開始的子樹,模式"/"會匹配所有的未被其他注冊的模式匹配的路徑功偿,而不僅僅是路徑"/"盆佣。

模式也能(可選地)以主機(jī)名開始,表示只匹配該主機(jī)上的路徑械荷。指定主機(jī)的模式優(yōu)先于一般的模式共耍,因此一個注冊了兩個模式"/codesearch"和"codesearch.google.com/"的處理器不會接管目標(biāo)為"http://www.google.com/"的請求。

ServeMux還會注意到請求的URL路徑的無害化吨瞎,將任何路徑中包含"."或".."元素的請求重定向到等價的沒有這兩種元素的URL痹兜。(參見path.Clean函數(shù))

func NewServeMux

func NewServeMux() *ServeMux

NewServeMux創(chuàng)建并返回一個新的*ServeMux

func (*ServeMux) Handle

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

Handle注冊HTTP處理器handler和對應(yīng)的模式pattern。如果該模式已經(jīng)注冊有一個處理器颤诀,Handle會panic字旭。

func (*ServeMux) HandleFunc

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

HandleFunc注冊一個處理器函數(shù)handler和對應(yīng)的模式pattern。

func (*ServeMux) Handler

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

Handler根據(jù)r.Method崖叫、r.Host和r.URL.Path等數(shù)據(jù)遗淳,返回將用于處理該請求的HTTP處理器。它總是返回一個非nil的處理器心傀。如果路徑不是它的規(guī)范格式屈暗,將返回內(nèi)建的用于重定向到等價的規(guī)范路徑的處理器。

Handler也會返回匹配該請求的的已注冊模式剧包;在內(nèi)建重定向處理器的情況下恐锦,pattern會在重定向后進(jìn)行匹配。如果沒有已注冊模式可以應(yīng)用于該請求疆液,本方法將返回一個內(nèi)建的"404 page not found"處理器和一個空字符串模式。

func (*ServeMux) ServeHTTP

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

ServeHTTP將請求派遣到與請求的URL最匹配的模式對應(yīng)的處理器陕贮。

type Server

type Server struct {
    Addr           string        // 監(jiān)聽的TCP地址堕油,如果為空字符串會使用":http"
    Handler        Handler       // 調(diào)用的處理器,如為nil會調(diào)用http.DefaultServeMux
    ReadTimeout    time.Duration // 請求的讀取操作在超時前的最大持續(xù)時間
    WriteTimeout   time.Duration // 回復(fù)的寫入操作在超時前的最大持續(xù)時間
    MaxHeaderBytes int           // 請求的頭域最大長度肮之,如為0則用DefaultMaxHeaderBytes
    TLSConfig      *tls.Config   // 可選的TLS配置掉缺,用于ListenAndServeTLS方法
    // TLSNextProto(可選地)指定一個函數(shù)來在一個NPN型協(xié)議升級出現(xiàn)時接管TLS連接的所有權(quán)。
    // 映射的鍵為商談的協(xié)議名戈擒;映射的值為函數(shù)眶明,該函數(shù)的Handler參數(shù)應(yīng)處理HTTP請求,
    // 并且初始化Handler.ServeHTTP的*Request參數(shù)的TLS和RemoteAddr字段(如果未設(shè)置)筐高。
    // 連接在函數(shù)返回時會自動關(guān)閉搜囱。
    TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
    // ConnState字段指定一個可選的回調(diào)函數(shù)丑瞧,該函數(shù)會在一個與客戶端的連接改變狀態(tài)時被調(diào)用。
    // 參見ConnState類型和相關(guān)常數(shù)獲取細(xì)節(jié)蜀肘。
    ConnState func(net.Conn, ConnState)
    // ErrorLog指定一個可選的日志記錄器绊汹,用于記錄接收連接時的錯誤和處理器不正常的行為。
    // 如果本字段為nil扮宠,日志會通過log包的標(biāo)準(zhǔn)日志記錄器寫入os.Stderr西乖。
    ErrorLog *log.Logger
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

Server類型定義了運(yùn)行HTTP服務(wù)端的參數(shù)。Server的零值是合法的配置坛增。

func (*Server) SetKeepAlivesEnabled

func (s *Server) SetKeepAlivesEnabled(v bool)

SetKeepAlivesEnabled控制是否允許HTTP閑置連接重用(keep-alive)功能获雕。默認(rèn)該功能總是被啟用的。只有資源非常緊張的環(huán)境或者服務(wù)端在關(guān)閉進(jìn)程中時收捣,才應(yīng)該關(guān)閉該功能届案。

func (*Server) Serve

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

Serve會接手監(jiān)聽器l收到的每一個連接,并為每一個連接創(chuàng)建一個新的服務(wù)go程坏晦。該go程會讀取請求萝玷,然后調(diào)用srv.Handler回復(fù)請求。

func (*Server) ListenAndServe

func (srv *Server) ListenAndServe() error

ListenAndServe監(jiān)聽srv.Addr指定的TCP地址昆婿,并且會調(diào)用Serve方法接收到的連接球碉。如果srv.Addr為空字符串,會使用":http"仓蛆。

func (*Server) ListenAndServeTLS

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

ListenAndServeTLS監(jiān)聽srv.Addr確定的TCP地址睁冬,并且會調(diào)用Serve方法處理接收到的連接。必須提供證書文件和對應(yīng)的私鑰文件看疙。如果證書是由權(quán)威機(jī)構(gòu)簽發(fā)的豆拨,certFile參數(shù)必須是順序串聯(lián)的服務(wù)端證書和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等函數(shù)用于文件訪問服務(wù)搁胆。

該接口的方法的行為應(yīng)該和*os.File類型的同名方法相同弥搞。

type FileSystem

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

FileSystem接口實現(xiàn)了對一系列命名文件的訪問。文件路徑的分隔符為'/'渠旁,不管主機(jī)操作系統(tǒng)的慣例如何攀例。

type Dir

type Dir string

Dir使用限制到指定目錄樹的本地文件系統(tǒng)實現(xiàn)了http.FileSystem接口」死埃空Dir被視為"."粤铭,即代表當(dāng)前目錄。

func (Dir) Open

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

func NewFileTransport

func NewFileTransport(fs FileSystem) RoundTripper

NewFileTransport返回一個RoundTripper接口杂靶,使用FileSystem接口fs提供文件訪問服務(wù)梆惯。 返回的RoundTripper接口會忽略接收的請求的URL主機(jī)及其他絕大多數(shù)屬性酱鸭。

NewFileTransport函數(shù)的典型使用情況是給Transport類型的值注冊"file"協(xié)議,如下所示:

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提供文件訪問服務(wù)的HTTP處理器加袋。要使用操作系統(tǒng)的FileSystem接口實現(xiàn)凛辣,可使用http.Dir:

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

func ProxyURL

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

ProxyURL返回一個代理函數(shù)(用于Transport類型),該函數(shù)總是返回同一個URL职烧。

func ProxyFromEnvironment

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

ProxyFromEnvironment使用環(huán)境變量HTTP_PROXY和NO_PROXY(或http_proxy和no_proxy)的配置返回用于req的代理扁誓。如果代理環(huán)境不合法將返回錯誤;如果環(huán)境未設(shè)定代理或者給定的request不應(yīng)使用代理時蚀之,將返回(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回復(fù)請求一個重定向地址urlStr和狀態(tài)碼code讶泰。該重定向地址可以是相對于請求r的相對地址。

func NotFound

func NotFound(w ResponseWriter, r *Request)

NotFound回復(fù)請求404狀態(tài)碼(not found:目標(biāo)未發(fā)現(xiàn))拂到。

func Error

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

Error使用指定的錯誤信息和狀態(tài)碼回復(fù)請求痪署,將數(shù)據(jù)寫入w。錯誤信息必須是明文兄旬。

func ServeContent

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

ServeContent使用提供的ReadSeeker的內(nèi)容回復(fù)請求狼犯。ServeContent比起io.Copy函數(shù)的主要優(yōu)點(diǎn),是可以處理范圍類請求(只要一部分內(nèi)容)领铐、設(shè)置MIME類型悯森,處理If-Modified-Since請求。

如果未設(shè)定回復(fù)的Content-Type頭绪撵,本函數(shù)首先會嘗試從name的文件擴(kuò)展名推斷數(shù)據(jù)類型瓢姻;如果失敗,會用讀取content的第1塊數(shù)據(jù)并提供給DetectContentType推斷類型音诈;之后會設(shè)置Content-Type頭汹来。參數(shù)name不會用于別的地方,甚至于它可以是空字符串改艇,也永遠(yuǎn)不會發(fā)送到回復(fù)里。

如果modtime不是Time零值坟岔,函數(shù)會在回復(fù)的頭域里設(shè)置Last-Modified頭谒兄。如果請求的頭域包含If-Modified-Since頭,本函數(shù)會使用modtime參數(shù)來確定是否應(yīng)該發(fā)送內(nèi)容社付。如果調(diào)用者設(shè)置了w的ETag頭承疲,ServeContent會使用它處理包含If-Range頭和If-None-Match頭的請求邻耕。

參數(shù)content的Seek方法必須有效:函數(shù)使用Seek來確定它的大小。

注意:本包File接口和*os.File類型都實現(xiàn)了io.ReadSeeker接口燕鸽。

func ServeFile

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

ServeFile回復(fù)請求name指定的文件或者目錄的內(nèi)容兄世。

func MaxBytesReader

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

MaxBytesReader類似io.LimitReader,但它是用來限制接收到的請求的Body的大小的啊研。不同于io.LimitReader御滩,本函數(shù)返回一個ReadCloser,返回值的Read方法在讀取的數(shù)據(jù)超過大小限制時會返回非EOF錯誤党远,其Close方法會關(guān)閉下層的io.ReadCloser接口r削解。

MaxBytesReader預(yù)防客戶端因為意外或者蓄意發(fā)送的“大”請求,以避免尺寸過大的請求浪費(fèi)服務(wù)端資源但狭。

func Head

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

Head向指定的URL發(fā)出一個HEAD請求翩剪,如果回應(yīng)的狀態(tài)碼如下箭窜,Head會在調(diào)用c.CheckRedirect后執(zhí)行重定向:

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發(fā)出一個GET請求矫废,如果回應(yīng)的狀態(tài)碼如下,Get會在調(diào)用c.CheckRedirect后執(zhí)行重定向:

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

如果c.CheckRedirect執(zhí)行失敗或存在HTTP協(xié)議錯誤時砰蠢,本方法將返回該錯誤蓖扑;如果回應(yīng)的狀態(tài)碼不是2xx,本方法并不會返回錯誤娩脾。如果返回值err為nil赵誓,resp.Body總是非nil的,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它柿赊。

Get是對包變量DefaultClient的Get方法的包裝俩功。

func Post

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

Post向指定的URL發(fā)出一個POST請求。bodyType為POST數(shù)據(jù)的類型碰声, body為POST數(shù)據(jù)诡蜓,作為請求的主體。如果參數(shù)body實現(xiàn)了io.Closer接口胰挑,它會在發(fā)送請求后被關(guān)閉蔓罚。調(diào)用者有責(zé)任在讀取完返回值resp的主體后關(guān)閉它。

Post是對包變量DefaultClient的Post方法的包裝瞻颂。

func PostForm

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

PostForm向指定的URL發(fā)出一個POST請求豺谈,url.Values類型的data會被編碼為請求的主體。如果返回值err為nil贡这,resp.Body總是非nil的茬末,調(diào)用者應(yīng)該在讀取完resp.Body后關(guān)閉它。

PostForm是對包變量DefaultClient的PostForm方法的包裝。

func Handle

func Handle(pattern string, handler Handler)

Handle注冊HTTP處理器handler和對應(yīng)的模式pattern(注冊到DefaultServeMux)丽惭。如果該模式已經(jīng)注冊有一個處理器击奶,Handle會panic。ServeMux的文檔解釋了模式的匹配機(jī)制责掏。

func HandleFunc

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

HandleFunc注冊一個處理器函數(shù)handler和對應(yīng)的模式pattern(注冊到DefaultServeMux)柜砾。ServeMux的文檔解釋了模式的匹配機(jī)制。

func Serve

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

Serve會接手監(jiān)聽器l收到的每一個連接换衬,并為每一個連接創(chuàng)建一個新的服務(wù)go程痰驱。該go程會讀取請求,然后調(diào)用handler回復(fù)請求冗疮。handler參數(shù)一般會設(shè)為nil萄唇,此時會使用DefaultServeMux。

func ListenAndServe

func ListenAndServe(addr string, handler Handler) error

ListenAndServe監(jiān)聽TCP地址addr术幔,并且會使用handler參數(shù)調(diào)用Serve函數(shù)處理接收到的連接另萤。handler參數(shù)一般會設(shè)為nil,此時會使用DefaultServeMux诅挑。

一個簡單的服務(wù)端例子:

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函數(shù)和ListenAndServe函數(shù)的行為基本一致四敞,除了它期望HTTPS連接之外。此外拔妥,必須提供證書文件和對應(yīng)的私鑰文件忿危。如果證書是由權(quán)威機(jī)構(gòu)簽發(fā)的,certFile參數(shù)必須是順序串聯(lián)的服務(wù)端證書和CA證書没龙。如果srv.Addr為空字符串铺厨,會使用":https"。

一個簡單的服務(wù)端例子:

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包實現(xiàn)了CGI(Common Gateway Interface解滓,公共網(wǎng)關(guān)協(xié)議),參見RFC 3875筝家。

注意使用CGI意味著對每一個請求開始一個新的進(jìn)程洼裤,這顯然要比使用長期運(yùn)行的服務(wù)程序要低效。本包主要是為了兼容現(xiàn)有的系統(tǒng)溪王。

func Request

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

返回一個當(dāng)前環(huán)境下的HTTP請求腮鞍。它假設(shè)當(dāng)前程序執(zhí)行在CGI環(huán)境下,成功返回的Request的Body是可讀取數(shù)據(jù)的莹菱。(如果必要)

func RequestFromMap

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

使用CGI變量集params創(chuàng)建一個HTTP請求移国。返回的Request的Body是沒有數(shù)據(jù)的。

func Serve

func Serve(handler http.Handler) error

在當(dāng)前活躍CGI環(huán)境下執(zhí)行handler道伟;如當(dāng)前無CGI環(huán)境桥狡,會返回錯誤。handler為nil時將使用http.DefaultServeMux。

type Handler

type Handler struct {
    Path string // CGI可執(zhí)行文件的路徑
    Root string // handler的根URI前綴裹芝,""代表"/"
    // Dir指定CGI程序的工作目錄。
    // 如果Dir為""則使用Path的基目錄娜汁;如果Path沒有基目錄則使用當(dāng)前工作目錄嫂易。
    Dir string
    Env        []string    // 額外設(shè)置的環(huán)境變量(如果有),格式為"key=value"
    InheritEnv []string    // 從host繼承的環(huán)境變量掐禁,只有"key"
    Logger     *log.Logger // 可選的logger接口切片怜械,如為nil則使用log.Print
    Args       []string    // 可選的傳遞給子進(jìn)程的參數(shù)
    // 當(dāng)CGI進(jìn)程返回一個Location頭,且其值以"/"開始時傅事,
    // 本字段指定處理內(nèi)部重定向的根部HTTP Handler缕允。參見RFC 3875 § 6.3.2。
    // 一般會使用http.DefaultServeMux蹭越。
    // 如果為nil障本,返回一個本地URI路徑的CGI回復(fù)會發(fā)送給客戶端,不進(jìn)行內(nèi)部跳轉(zhuǎn)响鹃。
    PathLocationHandler http.Handler
}

Handler在子進(jìn)程中執(zhí)行具有一個CGI環(huán)境的可執(zhí)行程序驾霜。

func (*Handler) ServeHTTP

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

http/cookiejar

cookiejar包實現(xiàn)了保管在內(nèi)存中的符合RFC 6265標(biāo)準(zhǔn)的http.CookieJar接口。

type PublicSuffixList

type PublicSuffixList interface {
    // 返回域名的公共后綴买置。
    // TODO:域名的格式化應(yīng)該由調(diào)用者還是接口方法負(fù)責(zé)還沒有確定粪糙。
    PublicSuffix(domain string) string
    // 返回公共后綴列表的來源的說明,該說明一般應(yīng)該包含時間戳和版本號忿项。
    String() string
}

PublicSuffixList提供域名的公共后綴蓉冈。例如:

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

PublicSuffixList接口的實現(xiàn)必須是并發(fā)安全的。一個總是返回""的實現(xiàn)是合法的轩触,也可以通過測試寞酿;但卻是不安全的:它允許HTTP服務(wù)端跨域名設(shè)置cookie。推薦實現(xiàn):code.google.com/p/go.net/publicsuffix

type Options

type Options struct {
    // PublicSuffixList是公共后綴列表怕膛,用于決定HTTP服務(wù)端是否能給某域名設(shè)置cookie
    // nil值合法的熟嫩,也可以通過測試;但卻是不安全的:它允許HTTP服務(wù)端跨域名設(shè)置cookie
    PublicSuffixList PublicSuffixList
}

Options是創(chuàng)建新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類型實現(xiàn)了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)

實現(xiàn)CookieJar接口的Cookies方法昧狮,如果URL協(xié)議不是HTTP/HTTPS會返回空切片。

func (*Jar) SetCookies

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

實現(xiàn)CookieJar接口的SetCookies方法板壮,如果URL協(xié)議不是HTTP/HTTPS則不會有實際操作逗鸣。

http/fcgi

fcgi包實現(xiàn)了FastCGI協(xié)議。目前只支持響應(yīng)器的角色。

協(xié)議定義的地址:http://www.fastcgi.com/drupal/node/6?q=node/22

func Serve

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

Serve接受從監(jiān)視器l傳入的FastCGI連接撒璧,為每一個FastCGI連接創(chuàng)建一個新的go程透葛。該go程讀取請求然后調(diào)用handler回復(fù)請求。如果l是nil卿樱,Serve將從os.Stdin接受連接僚害。如果handler是nil,將使用http.DefaultServeMux繁调。

http/httptest

httptest包提供了HTTP測試的常用函數(shù)萨蚕。

Constants

const DefaultRemoteAddr = "1.2.3.4"

DefaultRemoteAddr是默認(rèn)的遠(yuǎn)端地址。如果ResponseRecorder未顯式的設(shè)置該屬性蹄胰,RemoteAddr方法就會返回該值岳遥。

func NewRequest

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

NewRequest 返回一個新的服務(wù)器訪問請求,這個請求可以傳遞給 http.Handler 以便進(jìn)行測試裕寨。

target 參數(shù)的值為 RFC 7230 中提到的“請求目標(biāo)”(request-target): 它可以是一個路徑或者一個絕對 URL浩蓉。如果 target 是一個絕對 URL,那么 URL 中的主機(jī)名(host name)將被使用帮坚;否則主機(jī)名將為 example.com妻往。

當(dāng) target 的模式為 https 時,TLS 字段的值將被設(shè)置為一個非 nil 的隨意值(dummy value)试和。

Request.Proto 總是為 HTTP/1.1讯泣。

如果 method 參數(shù)的值為空, 那么使用 GET 方法作為默認(rèn)值阅悍。

body 參數(shù)的值可以為 nil好渠;另一方面,如果 body 參數(shù)的值為 *bytes.Reader 類型节视、 *strings.Reader 類型或者 *bytes.Buffer 類型拳锚,那么 Request.ContentLength 將被設(shè)置。

為了使用的方便寻行,NewRequest 將在 panic 可以被接受的情況下霍掺,使用 panic 代替錯誤。

如果你想要生成的不是服務(wù)器訪問請求拌蜘,而是一個客戶端 HTTP 請求杆烁,那么請使用 net/http 包中的 NewRequest 函數(shù)。

type ResponseRecorder

type ResponseRecorder struct {
    Code      int           // HTTP回復(fù)的狀態(tài)碼
    HeaderMap http.Header   // HTTP回復(fù)的頭域
    Body      *bytes.Buffer // 如非nil简卧,會將Write方法寫入的數(shù)據(jù)寫入bytes.Buffer
    Flushed   bool
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

ResponseRecorder實現(xiàn)了http.ResponseWriter接口兔魂,它記錄了其修改,用于之后的檢查举娩。

func NewRecorder

func NewRecorder() *ResponseRecorder

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

func (*ResponseRecorder) Flush

func (rw *ResponseRecorder) Flush()

Flush將rw.Flushed設(shè)置為真析校。

func (*ResponseRecorder) Heade

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

Header返回回復(fù)的頭域构罗,即Header字段。

func (*ResponseRecorder) Result

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

Result 返回處理器生成的響應(yīng)智玻。

處理器返回的響應(yīng)至少會對狀態(tài)碼(StatusCode)遂唧、首部(Header)、主體(Body)以及可選的 Trailer 進(jìn)行設(shè)置尚困。 因為未來可能會有更多字段被設(shè)置蠢箩,所以用戶不應(yīng)該在測試?yán)锩鎸Y(jié)果調(diào)用 DeepEqual。

Response.Header 是寫入操作第一次調(diào)用時的首部快照(snapshot of the headers)事甜; 另一方面, 如果處理器沒有執(zhí)行過寫入操作滔韵, 那么 Response.Header 就是 Result 方法調(diào)用時的首部快照逻谦。

Response.Body 將被生成為一個非 nil 值,而 Body.Read 則保證不會返回除 io.EOF 之外的其他任何錯誤陪蜻。

Result 必須在處理器執(zhí)行完畢之后調(diào)用邦马。

func (*ResponseRecorder) Write

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

Write總是成功,如果rw.Body非nil會把數(shù)據(jù)寫入該字段宴卖。

func (*ResponseRecorder) WriteHeader

func (rw *ResponseRecorder) WriteHeader(code int)

WriteHeader設(shè)置rw.Code滋将。

func (*ResponseRecorder) WriteString

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

在 str 不為 nil 的情況下, WriteString 總會成功地將 buf 中的內(nèi)容寫入到 rw.Body 當(dāng)中症昏。

type Server

type Server struct {
    URL      string // 格式為http://ipaddr:port随闽,沒有末尾斜杠的基地址
    Listener net.Listener
    // TLS是可選的TLS配置,在TLS開始后會填寫為新的配置肝谭。
    // 如果在未啟動的Server調(diào)用StartTLS方法前設(shè)置掘宪,已經(jīng)存在的字段會拷貝進(jìn)新配置里。
    TLS *tls.Config
    // Config可能會在調(diào)用Start/StartTLS方法之前調(diào)用NewUnstartedServer時被修改攘烛。
    Config *http.Server
    // 內(nèi)含隱藏或非導(dǎo)出字段
}

Server是一個HTTP服務(wù)端魏滚,在本地環(huán)回接口的某個系統(tǒng)選擇的端口監(jiān)聽,用于點(diǎn)對點(diǎn)HTTP測試坟漱。

func NewServer

func NewServer(handler http.Handler) *Server

NewServer返回一個新的鼠次、已啟動的Server。調(diào)用者必須在用完時調(diào)用Close方法關(guān)閉它芋齿。

func NewTLSServer

func NewTLSServer(handler http.Handler) *Server

NewTLSServer返回一個新的腥寇、使用TLS的、已啟動的Server沟突。調(diào)用者必須在用完時調(diào)用Close方法關(guān)閉它花颗。

func NewUnstartedServer

func NewUnstartedServer(handler http.Handler) *Server

NewUnstartedServer返回一個新的、未啟動的Server惠拭。在修改其配置后扩劝,調(diào)用者應(yīng)該調(diào)用Start或StartTLS啟動它庸论;調(diào)在用完時用者必須調(diào)用Close方法關(guān)閉它。

func (*Server) Start

func (s *Server) Start()

Start啟動NewUnstartedServer返回的服務(wù)端棒呛。

func (*Server) StartTLS

func (s *Server) StartTLS()

StartTLS啟動NewUnstartedServer函數(shù)返回的服務(wù)端的TLS監(jiān)聽聂示。

func (*Server) CloseClientConnections

func (s *Server) CloseClientConnections()

CloseClientConnections關(guān)閉當(dāng)前任何與該服務(wù)端建立的HTTP連接。

func (*Server) Close

func (s *Server) Close()

Close關(guān)閉服務(wù)端簇秒,并阻塞直到所有該服務(wù)端未完成的請求都結(jié)束為止鱼喉。

http/httptrace

httptrace包提供了跟蹤HTTP客戶端請求中的事件的機(jī)制。

func WithClientTrace

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

WithClientTrace基于提供的父ctx返回一個新的上下文趋观。 除了先前在ctx中注冊的任何鉤子之外扛禽,使用返回的上下文發(fā)出的HTTP客戶端請求還將使用提供的跟蹤鉤子。 在提供的跟蹤中定義的任何掛鉤都將首先被調(diào)用皱坛。

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請求的各個階段運(yùn)行卑硫。 任何特定的鉤子都可以為零秕硝。 可以從不同的goroutine并發(fā)調(diào)用函數(shù),某些函數(shù)可以在請求完成或失敗后調(diào)用旋膳。

ClientTrace當(dāng)前在單個往返過程中跟蹤單個HTTP請求和響應(yīng)贩猎,并且沒有跨越一系列重定向請求的鉤子熊户。

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

func ContextClientTrace

func ContextClientTrace(ctx context.Context) *ClientTrace

ContextClientTrace返回與提供的上下文關(guān)聯(lián)的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包含有關(guān)DNS查找結(jié)果的信息。

type DNSStartInfo

type DNSStartInfo struct {
    Host string
}

DNSStartInfo包含有關(guān)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函數(shù)的參數(shù)麦到,并包含有關(guān)獲得的連接的信息。

type WroteRequestInfo

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

WroteRequestInfo包含提供給WroteRequest掛鉤的信息欠肾。

http/httputil

httputil包提供了HTTP公用函數(shù)瓶颠,是對net/http包的更常見函數(shù)的補(bǔ)充。

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的和被服務(wù)端接收到時一樣的有線表示刺桃,可選地包括請求的主體粹淋,用于debug。本函數(shù)在語義上是無操作的瑟慈,但為了轉(zhuǎn)儲請求主體桃移,他會讀取主體的數(shù)據(jù)到內(nèi)存中,并將req.Body修改為指向內(nèi)存中的拷貝葛碧。req的字段的使用細(xì)節(jié)請參見http.Request的文檔借杰。

func DumpRequestOut

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

DumpRequestOut類似DumpRequest,但會包括標(biāo)準(zhǔn)http.Transport類型添加的頭域进泼,如User-Agent蔗衡。

func DumpResponse

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

DumpResponse類似DumpRequest纤虽,但轉(zhuǎn)儲的是一個回復(fù)。

func NewChunkedReader

func NewChunkedReader(r io.Reader) io.Reader

NewChunkedReader返回一個io.Reader绞惦。返回值的Read方法會將從r讀取的采用HTTP "chunked"傳輸編碼的數(shù)據(jù)翻譯之后返回逼纸。當(dāng)讀取到最后的零長chunk時,返回值的Read會返回io.EOF济蝉。

NewChunkedReader在正常的應(yīng)用中是不需要的杰刽,http包在讀取回復(fù)主體時會自動將"chunked"編碼進(jìn)行解碼。

func NewChunkedWriter

func NewChunkedWriter(w io.Writer) io.WriteCloser

NewChunkedWriter返回一個io.Writer王滤。返回值的Write方法會將寫入的數(shù)據(jù)編碼為HTTP "chunked"傳輸編碼格式后再寫入w贺嫂。其Close方法會將最后的零長chunk寫入w,標(biāo)注數(shù)據(jù)流的結(jié)尾雁乡。

正常的應(yīng)用中不需要NewChunkedWriter涝婉,http包會在處理器未設(shè)置Content-Length頭時主動進(jìn)行chunked編碼。在處理器內(nèi)部使用本函數(shù)會導(dǎo)致雙重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邏輯的前提下吩跋,在下層的連接上發(fā)送請求和接收回復(fù)的頭域寞射。ClientConn類型支持通過Hijack方法劫持下層連接,取回對下層連接的控制權(quán)锌钮,按照調(diào)用者的預(yù)期處理該連接桥温。

ClientConn是舊的、低層次的梁丘。應(yīng)用程序應(yīng)使用net/http包的Client類型和Transport類型代替它侵浸。

func NewClientConn

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

NewClientConn返回一個對c進(jìn)行讀寫的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返回該連接上已發(fā)送但還未接收到回復(fù)的請求的數(shù)量澳腹。

func (*ClientConn) Write

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

Write寫入一個請求。如果該連接已經(jīng)在HTTP keepalive邏輯上關(guān)閉了(表示該連接不會再發(fā)送新的請求)返回ErrPersistEOF杨何。如果req.Close設(shè)置為真酱塔,keepalive連接會在這次請求后邏輯上關(guān)閉,并通知遠(yuǎn)端的服務(wù)器危虱。ErrUnexpectedEOF表示遠(yuǎn)端關(guān)閉了下層的TCP連接羊娃,這一般被視為優(yōu)雅的(正常的)關(guān)閉。

func (*ClientConn) Read

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

Read讀取下一個回復(fù)埃跷。合法的回復(fù)可能會和ErrPersistEOF一起返回蕊玷,這表示遠(yuǎn)端要求該請求是最后一個被服務(wù)的請求邮利。Read可以和Write同時調(diào)用,但不能和另一個Read同時調(diào)用集畅。

func (*ClientConn) Do

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

Do是一個便利方法近弟,它會寫入一個請求,并讀取一個回復(fù)挺智。(能不能保證二者對應(yīng)祷愉?不知道)

func (*ClientConn) Hijack

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

Hijack拆開ClientConn返回下層的連接和讀取側(cè)的緩沖,其中可能有部分剩余的數(shù)據(jù)赦颇。Hijack可以在調(diào)用者自身或者其Read方法發(fā)出keepalive邏輯的終止信號之前調(diào)用二鳄。調(diào)用者不應(yīng)在Write或Read執(zhí)行過程中調(diào)用Hijack。

func (*ClientConn) Close

func (cc *ClientConn) Close() error

Close調(diào)用Hijack媒怯,然后關(guān)閉下層的連接订讼。

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類型在下層的連接上接收請求和發(fā)送回復(fù),直到HTTP keepalive邏輯結(jié)束扇苞。ServerConn類型支持通過Hijack方法劫持下層連接欺殿,取回對下層連接的控制權(quán),按照調(diào)用者的預(yù)期處理該連接鳖敷。ServerConn支持管道內(nèi)套脖苏,例如,請求可以不和回復(fù)的發(fā)送同步的讀榷狻(但仍按照相同的順序)棍潘。

ServerConn是舊的、低層次的崖媚。應(yīng)用程序應(yīng)使用net/http包的Server類型代替它亦歉。

func NewServerConn

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

NewServerConn返回一個新的從c讀寫的ServerConn。如果r補(bǔ)位nil畅哑,它將作為從c讀取時的緩沖肴楷。

func (*ServerConn) Pending

func (sc *ServerConn) Pending() int

Pending返回該連接上已接收到但還未回復(fù)的請求的數(shù)量。

func (*ServerConn) Read

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

Read讀取下一個請求敢课。如果它優(yōu)雅的決定不會再有更多的請求(例如阶祭,在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的回復(fù)resp。如要優(yōu)雅的關(guān)閉該連接圾结,可以設(shè)置resp.Close字段為真瑰剃。Write方法應(yīng)該盡量執(zhí)行(以回復(fù)盡量多的請求),直到Write本身返回錯誤筝野,而不應(yīng)考慮讀取側(cè)返回的任何錯誤晌姚。

func (*ServerConn) Hijack

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

Hijack拆開ServerConn返回下層的連接和讀取側(cè)的緩沖粤剧,其中可能有部分剩余的數(shù)據(jù)。Hijack可以在調(diào)用者自身或者其Read方法發(fā)出keepalive邏輯的終止信號之前調(diào)用挥唠。調(diào)用者不應(yīng)在Write或Read執(zhí)行過程中調(diào)用Hijack抵恋。

func (*ServerConn) Close

func (sc *ServerConn) Close() error

Close調(diào)用Hijack,然后關(guān)閉下層的連接宝磨。

type ReverseProxy

type ReverseProxy struct {
    // Director必須是將請求修改為新的請求的函數(shù)弧关。
    // 修改后的請求會使用Transport發(fā)送,得到的回復(fù)會不經(jīng)修改的返回給客戶端唤锉。
    Director func(*http.Request)
    // Transport用于執(zhí)行代理請求世囊。
    // 如果本字段為nil,會使用http.DefaultTransport窿祥。
    Transport http.RoundTripper
    // FlushInterval指定拷貝回復(fù)的主體時將數(shù)據(jù)刷新給客戶端的時間間隔株憾。
    // 如果本字段為零值,不會進(jìn)行周期的刷新晒衩。(拷貝完回復(fù)主體后再刷新)
    FlushInterval time.Duration
}

ReverseProxy是一個HTTP處理器嗤瞎,它接收一個請求,發(fā)送給另一個服務(wù)端听系,將回復(fù)轉(zhuǎn)發(fā)給客戶端猫胁。

func NewSingleHostReverseProxy

func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy

NewSingleHostReverseProxy返回一個新的ReverseProxy。返回值會將請求的URL重寫為target參數(shù)提供的協(xié)議跛锌、主機(jī)和基路徑。如果target參數(shù)的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服務(wù)端提供pprof可視化工具期望格式的運(yùn)行時剖面文件數(shù)據(jù)服務(wù)脑豹。關(guān)于pprof的更多信息郑藏,參見http://code.google.com/p/google-perftools/

本包一般只需導(dǎo)入獲取其注冊HTTP處理器的副作用瘩欺。處理器的路徑以/debug/pprof/開始必盖。

要使用pprof,在你的程序里導(dǎo)入本包:

import _ "net/http/pprof"

如果你的應(yīng)用還沒有運(yùn)行http服務(wù)器俱饿,你需要開始一個http服務(wù)器歌粥。添加"net/http"包和"log"包到你的導(dǎo)入列表,然后在main函數(shù)開始處添加如下代碼:

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/失驶。要學(xué)習(xí)這些運(yùn)轉(zhuǎn)的設(shè)施,訪問:

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

func Handler

func Handler(name string) http.Handler

Handler返回一個提供name指定的剖面文件的服務(wù)的HTTP處理器枣购。

func Cmdline

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

Cmdline回應(yīng)執(zhí)行中程序的命令行嬉探,采用NUL字節(jié)分隔的參數(shù)擦耀。本包將它注冊在/debug/pprof/cmdline。

func Index

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

Index回復(fù)請求要求的pprof格式的剖面涩堤。例如眷蜓,"/debug/pprof/heap"會回復(fù)"heap"剖面。Index會回復(fù)"/debug/pprof/" 請求一個列出所有可用的剖面的HTML頁面胎围。

func Profile

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

Profile回復(fù)pprof格式的CPU剖面吁系。本包將它注冊在/debug/pprof/profile。

func Symbol

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

Symbol查看請求中列出的程序計數(shù)器痊远,回復(fù)一個映射程序計數(shù)器到函數(shù)名的表格垮抗。本包將它注冊在/debug/pprof/symbol。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碧聪,一起剝皮案震驚了整個濱河市冒版,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逞姿,老刑警劉巖辞嗡,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異滞造,居然都是意外死亡续室,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門谒养,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挺狰,“玉大人,你說我怎么就攤上這事买窟》岵矗” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵始绍,是天一觀的道長瞳购。 經(jīng)常有香客問我,道長亏推,這世上最難降的妖魔是什么学赛? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮吞杭,結(jié)果婚禮上盏浇,老公的妹妹穿的比我還像新娘。我一直安慰自己芽狗,他們只是感情好缠捌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般曼月。 火紅的嫁衣襯著肌膚如雪谊却。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天哑芹,我揣著相機(jī)與錄音炎辨,去河邊找鬼。 笑死聪姿,一個胖子當(dāng)著我的面吹牛碴萧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播末购,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼破喻,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盟榴?” 一聲冷哼從身側(cè)響起曹质,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎擎场,沒想到半個月后羽德,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迅办,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年宅静,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片站欺。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡姨夹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矾策,到底是詐尸還是另有隱情匀伏,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布蝴韭,位于F島的核電站,受9級特大地震影響熙侍,放射性物質(zhì)發(fā)生泄漏榄鉴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一蛉抓、第九天 我趴在偏房一處隱蔽的房頂上張望庆尘。 院中可真熱鬧,春花似錦巷送、人聲如沸驶忌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽付魔。三九已至聊品,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間几苍,已是汗流浹背翻屈。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妻坝,地道東北人伸眶。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像刽宪,于是被迫代替她去往敵國和親厘贼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350