go語(yǔ)言請(qǐng)求http的簡(jiǎn)單介紹

如何實(shí)現(xiàn)Golang的http請(qǐng)求處理中間件

大多數(shù)現(xiàn)代Web組件棧允許通過(guò)棧式/組件式中間件“過(guò)濾”請(qǐng)求,這樣就能干凈地從web應(yīng)用中分離出橫切關(guān)注點(diǎn)(譯注:面向方面程序設(shè)計(jì)中的概念?)。 本周我嘗試在Go語(yǔ)言的 http.FileServer 中植入鉤子,發(fā)現(xiàn)實(shí)現(xiàn)起來(lái)十分簡(jiǎn)便,讓我非常驚訝。

獨(dú)山子ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:13518219792(備注:SSL證書(shū)合作)期待與您的合作!

讓我們從一個(gè)基本的文件服務(wù)器開(kāi)始說(shuō)起:

func main() {

http.ListenAndServe(":8080", http.FileServer(http.Dir("/tmp")))

}

go語(yǔ)言聊天室實(shí)現(xiàn)(六)創(chuàng)建HTTP連接,并升級(jí)為長(zhǎng)連接

我們?cè)趍ian函數(shù)中,首先初始化配置文件,然后新建http連接。

這個(gè)連接創(chuàng)建之后,監(jiān)聽(tīng)服務(wù)器的9999端口。如果url的路徑后綴為 "/ws",就轉(zhuǎn)發(fā)到ws/ws.go中的IndexHandler方法中。

這個(gè)方法中首先我們創(chuàng)建一個(gè)websocket的Upgrader實(shí)例,然后我們使用Upgrader的upgrade方法來(lái)升級(jí)一下我們的連接為長(zhǎng)連接。

升級(jí)完成之后會(huì)返回一個(gè)*websocket.Conn的連接,我們之后所有的關(guān)于連接的操作,都是基于該conn的。

在該連接完成之后,我們將連接存放到一個(gè)名為Client的map中,以便之后管理更為方便。

之后,我們啟動(dòng)一個(gè)goroutine來(lái)讀取連接中發(fā)送的信息內(nèi)容,再根據(jù)內(nèi)容進(jìn)行相應(yīng)的操作。

golang net/http包 http請(qǐng)求的字節(jié)碼讀取與解析。

先配置Header最長(zhǎng)讀取時(shí)間、req最長(zhǎng)讀取時(shí)間、req最大讀取長(zhǎng)度默認(rèn)6M。

RFC7230禁止\r\n參數(shù),Url中只允許包含英文字母(a-zA-Z)、數(shù)字(0-9)、-_.~4個(gè)特殊字符以及所有保留字符。但go net/http包放寬了這個(gè)要求。

先構(gòu)建newTextprotoReader,由于緩沖區(qū)是對(duì)象復(fù)用的,用完后要defer put。共完以以下解析任務(wù):

TextprotoReader數(shù)據(jù)結(jié)構(gòu),將字節(jié)碼Reader轉(zhuǎn)成文本Reader。

第一步,從第一行解析出method uri prototype。

第二步解析URL。url.URL數(shù)據(jù)結(jié)構(gòu):

解析Scheme,協(xié)議前綴(小寫(xiě))。有查詢(xún)參數(shù)?,則配置url.ForceQuery url.RawQuery。有認(rèn)證信息///...//,則解析url.User url.Host。最后配置url.Path和url.RawPath,如果Path==RawPath,則RawPath=""。

第三步解析MIMEHeader。

第四步readTransfer。重新配置如下參數(shù):RequestMethod ProtoMajor ProtoMinor Header Trailer ContentLength Close。對(duì)于Body,如果encodings支持chunked,讀取流用chunkedReader包裹。默認(rèn)情況用LimitedReader,無(wú)body賦空的struct{}。

以下情況返回非空err,示得到正確的請(qǐng)求:

最后配置req.ctx req.RemoteAddr req.TLS body.doEarlyClose = true。

構(gòu)建Response:

其中closeNotifyCh必須在構(gòu)建時(shí)初始化,沒(méi)有content所以先置contentLength為-1。

配置w.cw并被w.w包裹。w.cw緩沖默認(rèn)大小2M。

獲取Request可能出現(xiàn)如下錯(cuò)誤:

先上響應(yīng)數(shù)據(jù)結(jié)構(gòu):

response字段可以分類(lèi)為:大對(duì)象、緩沖、KV對(duì)或bool型的狀態(tài)參數(shù)。

大對(duì)象有:

狀態(tài)字段:

chunkWriter數(shù)據(jù)結(jié)構(gòu):

chunkWriter包裹了Response,功能之一是完成Header設(shè)置,包括Content-Type Content-Length chunk-header。bufio.Writer是chunkWriter是緩沖包裹。

handler將響應(yīng)寫(xiě)入到response.w。

調(diào)用w.w.Flush()將w寫(xiě)入到cw,注意到Flush()操作,如果未刷空緩存并報(bào)錯(cuò),觸發(fā)拷貝操作。報(bào)錯(cuò)不會(huì)退回已寫(xiě)出的數(shù)據(jù)。

進(jìn)而調(diào)用cw.Write(),根據(jù)cw.chunking參數(shù)。

putBufioWriter(w.w)清空resp.w緩沖,如果池化放回sync.pool。

根據(jù)chunkWriter的定義,w.cw.close()負(fù)責(zé)cw的結(jié)束工作:寫(xiě)入換行符和resp.trailers數(shù)據(jù)。

最后刷新TCP緩沖w.conn.bufw.Flush(),完成響應(yīng)包發(fā)送。并正確關(guān)閉request。

Golang http request 報(bào)錯(cuò)dial tcp: lookup xxx.com: no such host

使用golang自帶的http包創(chuàng)建http客戶(hù)端調(diào)用遠(yuǎn)程服務(wù),如果出現(xiàn) : no such host

第一種可能是服務(wù)器的最大打開(kāi)文件數(shù)

```

ulimit -n? ? ? ? ?#顯示最大打開(kāi)文件數(shù)

ulimit -n? ? ? ? #修改最大打開(kāi)文件數(shù)

```

第二種可能是沒(méi)有關(guān)閉http請(qǐng)求導(dǎo)致的,加上下面這句話(huà)

```

defer resp.Body.Close()

```

golang中http請(qǐng)求體多次讀取的坑

報(bào)錯(cuò)信息如下:

[logid: 3628171316][json.err: EOF] [exception:EOF] goroutine 20521 [running]:

原因:

在請(qǐng)求體為json的請(qǐng)求中,調(diào)用了parsePostForm方法,方法大致內(nèi)容如下:

在這個(gè)方法中,會(huì)讀取http的請(qǐng)求體。

在這里被讀取的時(shí)候,后面又重新讀取一次,之后解json

后面讀到的請(qǐng)求體是空的,解json的時(shí)候就會(huì)報(bào)錯(cuò)EOF

總結(jié):golang中http請(qǐng)求報(bào)錯(cuò)eof,多半是因?yàn)槎啻巫x取了請(qǐng)求體

【golang】context上下文與http請(qǐng)求妙用

1.在后端服務(wù)開(kāi)發(fā)中,如過(guò)一個(gè)HTTP請(qǐng)求,請(qǐng)求一致占用,將會(huì)帶來(lái)大的性能影響,所以需要為每個(gè)請(qǐng)求加上超時(shí)設(shè)置

2.在go語(yǔ)言中利用 context 進(jìn)行上下文控制,要想達(dá)到精確時(shí)間控制,如下:

3.同時(shí)我們也可以利用context的context.WithDeadline()函數(shù)來(lái)進(jìn)行超時(shí)控制

網(wǎng)站欄目:go語(yǔ)言請(qǐng)求http的簡(jiǎn)單介紹
轉(zhuǎn)載來(lái)源:http://www.muchs.cn/article2/hsseic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、商城網(wǎng)站網(wǎng)站維護(hù)、面包屑導(dǎo)航、做網(wǎng)站企業(yè)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站建設(shè)