Go的net/http
生活随笔
收集整理的這篇文章主要介紹了
Go的net/http
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
函數(shù)
服務(wù)端函數(shù)
func Handle(pattern string, handler Handler)將handler按照指定的格式注冊到 DefaultServeMux,ServeMux解釋了模式匹配規(guī)則 func HandleFunc(pattern string, handler func(ResponseWriter, *Request))同上,主要用來實(shí)現(xiàn)動(dòng) 態(tài)文件內(nèi)容的展示,這點(diǎn)與ServerFile()不同的地方。 func ListenAndServe(addr string, handler Handler) error監(jiān)聽TCP網(wǎng)絡(luò)地址addr然后調(diào)用具有 handler的Serve去處理連接請求.通常情況下Handler是nil,使用默認(rèn)的DefaultServeMux func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error該函數(shù)與ListenAndServe功能基本相同,二者不同之處是該函數(shù)需要HTTPS連接.也就是說,必須給該服務(wù) Serve提供一個(gè)包含整數(shù)的秘鑰的文件,如果證書是由證書機(jī)構(gòu)簽署的,那么證書文件必須是服務(wù)證書之后跟著CA 證書. func ServeFile(w ResponseWriter, r *Request, name string)利用指定的文件或者目錄的內(nèi)容來響應(yīng) 相應(yīng)的請求. func SetCookie(w ResponseWriter, cookie *Cookie)給w設(shè)定cookie func StatusText(code int) string對于http狀態(tài)碼返回文本表示,如果這個(gè)code未知,則返回空的字符串 func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser該函數(shù)類似于 io.LimitReader但是該函數(shù)是用來限制請求體的大小.與io.LimitReader不同的是,該函數(shù)返回一個(gè) ReaderCloser,當(dāng)讀超過限制時(shí),返回一個(gè)non-EOF,并且當(dāng)Close方法調(diào)用時(shí),關(guān)閉底層的reader.該函數(shù)組織 客戶端惡意發(fā)送大量請求,浪費(fèi)服務(wù)器資源. func ParseHTTPVersion(vers string) (major, minor int, ok bool)解析http字符串版本進(jìn)行解 析,”HTTP/1.0” 返回 (1, 0, true) func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error)返回一個(gè)用于傳輸?shù)拇砗?數(shù),該函數(shù)總是返回相同的URL func Redirect(w ResponseWriter, r *Request, urlStr string, code int)返回一個(gè)重定向的url給指 定的請求,這個(gè)重定向url可能是一個(gè)相對請求路徑的一個(gè)相對路徑. func Serve(l net.Listener, handler Handler) error該函數(shù)接受listener l的傳入http連接,對于每 一個(gè)連接創(chuàng)建一個(gè)新的服務(wù)協(xié)程,這個(gè)服務(wù)協(xié)程讀取請求然后調(diào)用handler來給他們響應(yīng).handler一般為nil,這 樣默認(rèn)的DefaultServeMux被使用.客戶端函數(shù)
Client具有Do,Get,Head,Post以及PostForm等方法。 其中Do方法可以對Request進(jìn)行一系列的設(shè)定,而其 他的對request設(shè)定較少。如果Client使用默認(rèn)的Client,則其中的Get,Head,Post以及PostForm方法相當(dāng)于 默認(rèn)的http.Get,http.Post,http.Head以及http.PostForm函數(shù)。 func (c *Client) Do(req *Request) (resp *Response, err error)Do發(fā)送http請求并且返回一個(gè)http響 應(yīng),遵守client的策略,如重定向,cookies以及auth等.錯(cuò)誤經(jīng)常是由于策略引起的,當(dāng)err是nil時(shí),resp總會(huì)包含 一個(gè)非nil的resp.body.當(dāng)調(diào)用者讀完resp.body之后應(yīng)該關(guān)閉它,如果resp.body沒有關(guān)閉,則Client底層 RoundTripper將無法重用存在的TCP連接去服務(wù)接下來的請求,如果resp.body非nil,則必須對其進(jìn)行關(guān)閉.通常 來說,經(jīng)常使用Get,Post,或者PostForm來替代Do. func (c *Client) Get(url string) (resp *Response, err error)利用get方法請求指定的url.Get請求 指定的頁面信息,并返回實(shí)體主體。 func (c *Client) Head(url string) (resp *Response, err error)利用head方法請求指定的url,Head 只返回頁面的首部。 func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error)利用post方法請求指定的URl,如果body也是一個(gè)io.Closer,則在請求之后關(guān)閉它 func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)利用post方 法請求指定的url,利用data的key和value作為請求體. Do方法可以靈活的對request進(jìn)行配置,然后進(jìn)行請求。利用http.Client以及http.NewRequest來模擬請求。模 擬request中帶有cookie的請求。示例如下:例子
package main import (// "encoding/json""fmt""io/ioutil""net/http""strconv" ) func main() {client := &http.Client{}request, err := http.NewRequest("GET", "http://www.baidu.com", nil)if err != nil {fmt.Println(err)}cookie := &http.Cookie{Name: "userId", Value: strconv.Itoa(12345)}request.AddCookie(cookie) //request中添加cookie//設(shè)置request的headerrequest.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")request.Header.Set("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.3")request.Header.Set("Accept-Encoding", "gzip,deflate,sdch")request.Header.Set("Accept-Language", "zh-CN,zh;q=0.8")request.Header.Set("Cache-Control", "max-age=0")request.Header.Set("Connection", "keep-alive")response, err := client.Do(request)if err != nil {fmt.Println(err)return}defer response.Body.Close()fmt.Println(response.StatusCode)if response.StatusCode == 200 {r, err := ioutil.ReadAll(response.Body)if err != nil {fmt.Println(err)}fmt.Println(string(r))} }結(jié)構(gòu)
客戶端
type ClientClient是一個(gè)http客戶端,默認(rèn)客戶端(DefaultClient)將使用默認(rèn)的發(fā)送機(jī)制的客戶端.Client的Transport字段一般會(huì)含有內(nèi)部狀態(tài)(緩存TCP連接),因此Client類型值應(yīng)盡量被重用而不是創(chuàng)建新的。多個(gè)協(xié)程并發(fā)使用Clients是安全的.
type Client struct { // Transport指定執(zhí)行獨(dú)立、單次HTTP請求的機(jī)制如果Transport為nil,則使用DefaultTransport。Transport RoundTripper // CheckRedirect指定處理重定向的策略,如果CheckRedirect非nil,client將會(huì)在調(diào)用重定向之前調(diào)用它。參 數(shù)req和via是將要執(zhí)行的請求和已經(jīng)執(zhí)行的請求(時(shí)間越久的請求優(yōu)先執(zhí)行),如果CheckRedirect返回一個(gè)錯(cuò) 誤,client的GetGet方法不會(huì)發(fā)送請求req,而是回之前得到的響應(yīng)和該錯(cuò)誤。如果CheckRedirect為nil,會(huì)采用 默認(rèn)策略:在連續(xù)10次請求后停止。CheckRedirect func(req *Request, via []*Request) error// Jar指定cookie管理器,如果Jar為nil,在請求中不會(huì)發(fā)送cookie,在回復(fù)中cookie也會(huì)被忽略。Jar CookieJar // Timeout指定Client請求的時(shí)間限制,該超時(shí)限制包括連接時(shí)間、重定向和讀取response body時(shí)間。計(jì)時(shí)器 會(huì)在Head,Get,Post或Do方法返回后開始計(jì)時(shí)并在讀到response.body后停止計(jì)時(shí)。Timeout為零值表示不設(shè)置超 時(shí)。Client的Transport字段必須支持CancelRequest方法,否則Client會(huì)在嘗試用Head,Get,Post或Do方法執(zhí) 行請求時(shí)返回錯(cuò)誤。Client的Transport字段默認(rèn)值(DefaultTransport)支持CancelRequest方法。Timeout time.Duration }?
type ConnState表示客戶端連接服務(wù)端的狀態(tài),其中ConnState常用狀態(tài)變量如下:const (// StateNew代表一個(gè)新的連接,將要立刻發(fā)送請求。// 連接從這個(gè)狀態(tài)開始,然后轉(zhuǎn)變?yōu)镾tateAlive或StateClosed。StateNew ConnState = iota// StateActive代表一個(gè)已經(jīng)讀取了請求數(shù)據(jù)1到多個(gè)字節(jié)的連接。// 用于StateAlive的Server.ConnState回調(diào)函數(shù)在將連接交付給處理器之前被觸發(fā),// 等到請求被處理完后,Server.ConnState回調(diào)函數(shù)再次被觸發(fā)。// 在請求被處理后,連接狀態(tài)改變?yōu)镾tateClosed、StateHijacked或StateIdle。StateActive// StateIdle代表一個(gè)已經(jīng)處理完了請求、處在閑置狀態(tài)、等待新請求的連接。// 連接狀態(tài)可以從StateIdle改變?yōu)镾tateActive或StateClosed。StateIdle// 代表一個(gè)被劫持的連接。這是一個(gè)終止?fàn)顟B(tài),不會(huì)轉(zhuǎn)變?yōu)镾tateClosed。StateHijacked// StateClosed代表一個(gè)關(guān)閉的連接。// 這是一個(gè)終止?fàn)顟B(tài)。被劫持的連接不會(huì)轉(zhuǎn)變?yōu)镾tateClosed。StateClosed ) type Cookie常用SetCooker用來給http的請求或者h(yuǎn)ttp的response設(shè)置cookietype Cookie struct {Name string //名字Value string //值Path string //路徑Domain string Expires time.Time //過期時(shí)間RawExpires string// MaxAge=0 意味著 沒有'Max-Age'屬性指定.// MaxAge<0 意味著 立即刪除cookie// MaxAge>0 意味著設(shè)定了MaxAge屬性,并且其單位是秒MaxAge intSecure boolHttpOnly boolRaw stringUnparsed []string // 未解析的屬性值對 }func (c *Cookie) String() string該函數(shù)返回cookie的序列化結(jié)果。如果只設(shè)置了Name和Value字段,序列化結(jié)果可用于HTTP請求的Cookie頭或者HTTP回復(fù)的Set-Cookie頭;如果設(shè)置了其他字段,序列化結(jié)果只能用于HTTP回復(fù)的Set-Cookie頭。?
type CookieJar在http請求中,CookieJar管理存儲(chǔ)和使用cookies.Cookiejar的實(shí)現(xiàn)必須被多協(xié)程并發(fā)使用時(shí)是安全的.
服務(wù)端
type Handler實(shí)現(xiàn)Handler接口的對象可以注冊到HTTP服務(wù)端,為指定的路徑或者子樹提供服務(wù)。ServeHTTP應(yīng)該將回復(fù)的header和數(shù)據(jù)寫入ResponseWriter接口然后返回。返回意味著該請求已經(jīng)結(jié)束,HTTP服務(wù)端可以轉(zhuǎn)移向該連接上的下一個(gè)請求。如果ServeHTTP崩潰panic,那么ServeHTTP的調(diào)用者假定這個(gè)panic的影響與活動(dòng)請求是隔離的,二者互不影響.調(diào)用者恢復(fù)panic,將stack trace記錄到錯(cuò)誤日志中,然后掛起這個(gè)連接.type Handler interface {ServeHTTP(ResponseWriter, *Request) }func FileServer(root FileSystem) HandlerFileServer返回一個(gè)使用FileSystem接口提供文件訪問服務(wù)的HTTP處理器。可以使用httpDir來使用操作系統(tǒng)的FileSystem接口實(shí)現(xiàn)。其主要用來實(shí)現(xiàn)靜態(tài)文件的展示。 func NotFoundHandler() Handler返回一個(gè)簡單的請求處理器,該處理器對任何請求都會(huì)返回”404 page not found” func RedirectHandler(url string, code int) Handler使用給定的狀態(tài)碼將它接受到的任何請求都重定向到給定的url func StripPrefix(prefix string, h Handler) Handler將請求url.path中移出指定的前綴,然后將省下的請求交給handler h來處理,對于那些不是以指定前綴開始的路徑請求,該函數(shù)返回一個(gè)http 404 not found 的錯(cuò)誤. func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler具有超時(shí)限制的handler,該函數(shù)返回的新Handler調(diào)用h中的ServerHTTP來處理每次請求,但是如果一次調(diào)用超出時(shí)間限制,那么就會(huì)返回給請求者一個(gè)503服務(wù)請求不可達(dá)的消息,并且在ResponseWriter返回超時(shí)錯(cuò)誤. 其中FileServer經(jīng)常和StripPrefix一起連用,用來實(shí)現(xiàn)靜態(tài)文件展示,舉例如下:package main import ("fmt""net/http" ) func main() {http.Handle("/test/", http.FileServer(http.Dir("/home/work/"))) ///home/work/test/中必須有內(nèi)容http.Handle("/download/", http.StripPrefix("/download/", http.FileServer(http.Dir("/home/work/"))))http.Handle("/tmpfiles/", http.StripPrefix("/tmpfiles/", http.FileServer(http.Dir("/tmp")))) //127.0.0.1:9999/tmpfiles/訪問的本地文件/tmp中的內(nèi)容http.ListenAndServe(":9999", nil) }type HandlerFuncHandlerFunc type是一個(gè)適配器,通過類型轉(zhuǎn)換我們可以將普通的函數(shù)作為HTTP處理器使用。如果f是一個(gè)具有適當(dāng)簽名的函數(shù),HandlerFunc(f)通過調(diào)用f實(shí)現(xiàn)了Handler接口。type Hijacker interface {// Hijack讓調(diào)用者接管連接,在調(diào)用Hijack()后,http server庫將不再對該連接進(jìn)行處理,對于該連接的管理和關(guān)閉責(zé)任將由調(diào)用者接管.Hijack() (net.Conn, *bufio.ReadWriter, error) //conn表示連接對象,bufrw代表該連接的讀寫緩存對象。 }Hijacker用法如下所示:package main import ("fmt""net/http" ) func HiJack(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}defer conn.Close()bufrw.WriteString("Now we're speaking raw TCP. Say hi: \n")bufrw.Flush()fmt.Fprintf(bufrw, "You said: %s Bye.\n", "Good")bufrw.Flush() } func main() {http.HandleFunc("/hijack", HiJack)err := http.ListenAndServe(":9999", nil)if err != nil {fmt.Println(err)} }?
總結(jié)
以上是生活随笔為你收集整理的Go的net/http的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 哪些食物吃完后能让你感觉心情好起来?
- 下一篇: 为什么中式快餐越来越少人吃