?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
import "net/http/httputil"
概述
索引
示例
軟件包httputil提供HTTP實用程序功能,補充了net/http軟件包中較常見的功能。
變量
func DumpRequest(req *http.Request, body bool) ([]byte, error)
func DumpRequestOut(req *http.Request, body bool) ([]byte, error)
func DumpResponse(resp *http.Response, body bool) ([]byte, error)
func NewChunkedReader(r io.Reader) io.Reader
func NewChunkedWriter(w io.Writer) io.WriteCloser
type BufferPool
type ClientConn
func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn
func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn
func (cc *ClientConn) Close() error
func (cc *ClientConn) Do(req *http.Request) (*http.Response, error)
func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader)
func (cc *ClientConn) Pending() int
func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error)
func (cc *ClientConn) Write(req *http.Request) error
type ReverseProxy
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)
type ServerConn
func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn
func (sc *ServerConn) Close() error
func (sc *ServerConn) Hijack() (net.Conn, *bufio.Reader)
func (sc *ServerConn) Pending() int
func (sc *ServerConn) Read() (*http.Request, error)
func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error
DumpRequest DumpRequestOut DumpResponse ReverseProxy
dump.go httputil.go persist.go reverseproxy.go
var ( // Deprecated: No longer used. ErrPersistEOF = &http.ProtocolError{ErrorString: "persistent connection closed"} // Deprecated: No longer used. ErrClosed = &http.ProtocolError{ErrorString: "connection closed by user"} // Deprecated: No longer used. ErrPipeline = &http.ProtocolError{ErrorString: "pipeline error"})
使用太長的行讀取格式不正確的分塊數(shù)據(jù)時,會返回ErrLineTooLong。
var ErrLineTooLong = internal.ErrLineTooLong
func DumpRequest(req *http.Request, body bool) ([]byte, error)
DumpRequest以HTTP/1.x線表示形式返回給定的請求。它只能被服務(wù)器用來調(diào)試客戶端請求。返回的表示只是一個近似值; 解析為http.Request時,初始請求的某些細(xì)節(jié)會丟失。特別是頭字段名稱的順序和大小寫會丟失。多值頭中值的順序保持不變。HTTP/2請求以HTTP/1.x形式轉(zhuǎn)儲,而不是以其原始二進(jìn)制表示。
如果body正確,DumpRequest也返回正文。為此,它使用req.Body,然后用一個新的產(chǎn)生相同字節(jié)的io.ReadCloser來替換它。如果DumpRequest返回錯誤,則req的狀態(tài)是未定義的。
http.Request.Write的文檔詳細(xì)說明了哪些req字段包含在轉(zhuǎn)儲中。
package mainimport ("fmt""io/ioutil""log""net/http""net/http/httptest""net/http/httputil""strings")func main() { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { dump, err := httputil.DumpRequest(r, true)if err != nil { http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)return} fmt.Fprintf(w, "%q", dump)})) defer ts.Close()const body = "Go is a general-purpose language designed with systems programming in mind." req, err := http.NewRequest("POST", ts.URL, strings.NewReader(body))if err != nil { log.Fatal(err)} req.Host = "www.example.org" resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)} defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body)if err != nil { log.Fatal(err)} fmt.Printf("%s", b)}
func DumpRequestOut(req *http.Request, body bool) ([]byte, error)
DumpRequestOut就像DumpRequest,但是用于傳出客戶端請求。它包括標(biāo)準(zhǔn)http.Transport添加的任何標(biāo)題,例如User-Agent。
package mainimport ("fmt""log""net/http""net/http/httputil""strings")func main() {const body = "Go is a general-purpose language designed with systems programming in mind." req, err := http.NewRequest("PUT", "http://www.example.org", strings.NewReader(body))if err != nil { log.Fatal(err)} dump, err := httputil.DumpRequestOut(req, true)if err != nil { log.Fatal(err)} fmt.Printf("%q", dump)}
func DumpResponse(resp *http.Response, body bool) ([]byte, error)
DumpResponse與DumpRequest類似,但會轉(zhuǎn)儲響應(yīng)。
package mainimport ("fmt""log""net/http""net/http/httptest""net/http/httputil")func main() {const body = "Go is a general-purpose language designed with systems programming in mind." ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Date", "Wed, 19 Jul 1972 19:00:00 GMT") fmt.Fprintln(w, body)})) defer ts.Close() resp, err := http.Get(ts.URL)if err != nil { log.Fatal(err)} defer resp.Body.Close() dump, err := httputil.DumpResponse(resp, true)if err != nil { log.Fatal(err)} fmt.Printf("%q", dump)}
func NewChunkedReader(r io.Reader) io.Reader
NewChunkedReader返回一個新的chunkedReader,它在返回之前將從r讀出的數(shù)據(jù)轉(zhuǎn)換成HTTP“chunked”格式。chunkedReader在讀取最后的0長度塊時返回io.EOF。
普通應(yīng)用程序不需要NewChunkedReader。在閱讀響應(yīng)主體時,http包會自動解碼分塊。
func NewChunkedWriter(w io.Writer) io.WriteCloser
NewChunkedWriter返回一個新的chunkedWriter,在寫入w之前將寫入轉(zhuǎn)換為HTTP“分塊”格式。關(guān)閉返回的chunkedWriter將發(fā)送標(biāo)記流結(jié)束的最終0長度塊。
普通應(yīng)用程序不需要NewChunkedWriter。如果處理程序未設(shè)置Content-Length標(biāo)頭,則http包會自動添加分塊。在處理程序中使用NewChunkedWriter會導(dǎo)致雙重組塊或使用Content-Length長度分塊,這兩者都是錯誤的。
BufferPool是一個獲取和返回io.CopyBuffer使用的臨時字節(jié)片的接口。
type BufferPool interface { Get() []byte Put([]byte)}
ClientConn是Go早期HTTP實現(xiàn)的產(chǎn)物。它是Go的當(dāng)前HTTP堆棧的低級,舊的和未使用的。我們應(yīng)該在Go 1之前刪除它。
Deprecated:在net/http包中使用客戶端或傳輸。
type ClientConn struct { // contains filtered or unexported fields}
func NewClientConn(c net.Conn, r *bufio.Reader) *ClientConn
NewClientConn是Go早期HTTP實現(xiàn)的一個工件。它是Go的當(dāng)前HTTP堆棧的低級,舊的和未使用的。我們應(yīng)該在Go 1之前刪除它。
Deprecated:使用客戶端或傳輸net/http包代替。
func NewProxyClientConn(c net.Conn, r *bufio.Reader) *ClientConn
NewProxyClientConn是Go早期HTTP實現(xiàn)的工件。它是Go的當(dāng)前HTTP堆棧的低級,舊的和未使用的。我們應(yīng)該在Go 1之前刪除它。
Deprecated:使用客戶端或傳輸net/http包代替。
func (cc *ClientConn) Close() error
Close調(diào)用Hijack,然后關(guān)閉底層連接。
func (cc *ClientConn) Do(req *http.Request) (*http.Response, error)
Do是寫請求并讀取響應(yīng)的便利方法。
func (cc *ClientConn) Hijack() (c net.Conn, r *bufio.Reader)
劫持分離ClientConn并返回底層連接以及可能留下數(shù)據(jù)的讀取端bufio??梢栽谟脩艋騌ead之前調(diào)用劫持標(biāo)志保持活動邏輯的結(jié)束。在讀取或?qū)懭脒^程中,用戶不應(yīng)該調(diào)用劫持。
func (cc *ClientConn) Pending() int
Pending返回已經(jīng)在連接上發(fā)送的未應(yīng)答請求的數(shù)量。
func (cc *ClientConn) Read(req *http.Request) (resp *http.Response, err error)
Read從電線讀取下一個響應(yīng)。有效的響應(yīng)可能會與ErrPersistEOF一起返回,這意味著遠(yuǎn)程請求這是最后一次請求服務(wù)。Read可以與Write同時調(diào)用,但不能與另一個Read一起調(diào)用。
func (cc *ClientConn) Write(req *http.Request) error
Write寫入請求。如果連接已經(jīng)以HTTP Keepalive意義關(guān)閉,則返回ErrPersistEOF錯誤。如果req.Close等于true,則在此請求和對端服務(wù)器被通知后,保持連接在邏輯上關(guān)閉。ErrUnexpectedEOF指示遠(yuǎn)程關(guān)閉了底層TCP連接,通常認(rèn)為該連接處于優(yōu)雅關(guān)閉狀態(tài)。
ReverseProxy是一個HTTP處理程序,它接收傳入的請求并將其發(fā)送到另一個服務(wù)器,將響應(yīng)代理回客戶端。
type ReverseProxy struct { // Director must be a function which modifies // the request into a new request to be sent // using Transport. Its response is then copied // back to the original client unmodified. // Director must not access the provided Request // after returning. Director func(*http.Request) // The transport used to perform proxy requests. // If nil, http.DefaultTransport is used. Transport http.RoundTripper // FlushInterval specifies the flush interval // to flush to the client while copying the // response body. // If zero, no periodic flushing is done. FlushInterval time.Duration // ErrorLog specifies an optional logger for errors // that occur when attempting to proxy the request. // If nil, logging goes to os.Stderr via the log package's // standard logger. ErrorLog *log.Logger // BufferPool optionally specifies a buffer pool to // get byte slices for use by io.CopyBuffer when // copying HTTP response bodies. BufferPool BufferPool // ModifyResponse is an optional function that // modifies the Response from the backend. // If it returns an error, the proxy returns a StatusBadGateway error. ModifyResponse func(*http.Response) error}
package mainimport ("fmt""io/ioutil""log""net/http""net/http/httptest""net/http/httputil""net/url")func main() { backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "this call was relayed by the reverse proxy")})) defer backendServer.Close() rpURL, err := url.Parse(backendServer.URL)if err != nil { log.Fatal(err)} frontendProxy := httptest.NewServer(httputil.NewSingleHostReverseProxy(rpURL)) defer frontendProxy.Close() resp, err := http.Get(frontendProxy.URL)if err != nil { log.Fatal(err)} b, err := ioutil.ReadAll(resp.Body)if err != nil { log.Fatal(err)} fmt.Printf("%s", b)}
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
NewSingleHostReverseProxy返回一個新的ReverseProxy,它將URL路由到目標(biāo)中提供的方案,主機和基本路徑。如果目標(biāo)路徑為“/base”,并且傳入請求為“/dir”,則目標(biāo)請求將為/base/dir。NewSingleHostReverseProxy不重寫Host頭。要重寫Host頭文件,請使用ReverseProxy直接使用自定義Director策略。
func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)
ServerConn是Go早期HTTP實現(xiàn)的產(chǎn)物。它是Go的當(dāng)前HTTP堆棧的低級,舊的和未使用的。我們應(yīng)該在Go 1之前刪除它。
Deprecated:改為在net/http包中使用Server。
type ServerConn struct { // contains filtered or unexported fields}
func NewServerConn(c net.Conn, r *bufio.Reader) *ServerConn
NewServerConn是Go早期HTTP實現(xiàn)的產(chǎn)物。它是Go的當(dāng)前HTTP堆棧的低級,舊的和未使用的。我們應(yīng)該在Go 1之前刪除它。
Deprecated:改為在net/http包中使用Server。
func (sc *ServerConn) Close() error
Close調(diào)用劫持,然后關(guān)閉底層連接。
func (sc *ServerConn) Hijack() (net.Conn, *bufio.Reader)
劫持分離ServerConn并返回底層連接以及可能有一些遺留數(shù)據(jù)的讀取端bufio。在Read已經(jīng)發(fā)出keep-alive邏輯的結(jié)束信號之前,可能會調(diào)用劫持。在讀取或?qū)懭脒^程中,用戶不應(yīng)該調(diào)用劫持。
func (sc *ServerConn) Pending() int
掛起返回在連接上收到的未應(yīng)答請求的數(shù)量。
func (sc *ServerConn) Read() (*http.Request, error)
讀取將返回線路上的下一個請求。如果優(yōu)雅地確定沒有更多請求(例如,在HTTP / 1.0連接上的第一個請求之后,或在HTTP/1.1連接上的Connection:close之后),則返回ErrPersistEOF。
func (sc *ServerConn) Write(req *http.Request, resp *http.Response) error
Write寫入resp響應(yīng)請求。要正常關(guān)閉連接,請將Response.Close字段設(shè)置為true。寫操作應(yīng)該被認(rèn)為是可操作的,直到它返回一個錯誤,而不管在讀方面返回的任何錯誤。