最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang反向代理設(shè)置host不生效的問題解決

 更新時(shí)間:2023年05月27日 10:03:45   作者:鐵柱同學(xué)  
在使用golang的httputil做反向代理的時(shí)候,發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,上游網(wǎng)關(guān)必須要設(shè)置host才行,不設(shè)置host的話,golang服務(wù)反向代理請(qǐng)求下游會(huì)出現(xiàn)http 503錯(cuò)誤,接下來通過本文給大家介紹golang反向代理設(shè)置host不生效問題,感興趣的朋友一起看看吧

一、背景

在使用golanghttputil做反向代理的時(shí)候,發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,上游網(wǎng)關(guān)必須要設(shè)置host才行,不設(shè)置host的話,golang服務(wù)反向代理請(qǐng)求下游會(huì)出現(xiàn)http 503錯(cuò)誤。服務(wù)調(diào)用順序如下:

在這里插入圖片描述

二、排查過程

1、打印req.header

差異字段主要是:ForwardedGFS.scg.ip字段。

(1)GFS.scg.ip
Gfs.scg.ip 是 Spring Cloud Gateway 中的一個(gè)自定義請(qǐng)求頭部字段,用于在路由
中傳遞客戶端的 IP 地址信息。
(2)Forwarded
在 HTTP 請(qǐng)求中,F(xiàn)orwarded 是一種標(biāo)準(zhǔn)化的請(qǐng)求頭,用于識(shí)別原始客戶端和代理之間
的連接信息。該字段的值包括一系列鍵值對(duì),每個(gè)鍵值對(duì)都表示一個(gè)不同的屬性。

此時(shí)為了排除網(wǎng)關(guān)設(shè)置header對(duì)請(qǐng)求的影響,在goproxy中清空header且重新嘗試,發(fā)現(xiàn)請(qǐng)求依然是503

req.Header = http.Header{}
req.Header.Set("traceId", traceId)
req.Header.Set("host", "XXX")

2、tcpdump抓包分析

# 抓取請(qǐng)求本機(jī)8080端口的請(qǐng)求
sudo tcpdump -i wlo1 -A  port 8080
# 抓取本機(jī)發(fā)出的http請(qǐng)求
sudo tcpdump -i wlo1 -A dst host 下游域名

(1)先抓取8080端口的請(qǐng)求,查看header差異

host: xxx # 網(wǎng)關(guān)不設(shè)置header的時(shí)候,host是本機(jī)ip
host: localization.xx # 網(wǎng)關(guān)設(shè)置header的時(shí)候,host為目標(biāo)主機(jī)域名

如上所示,可以得到結(jié)論,host本來就代表目標(biāo)主機(jī),網(wǎng)關(guān)那邊設(shè)置host的時(shí)候,golang服務(wù)進(jìn)行轉(zhuǎn)發(fā),會(huì)把host帶到下游python服務(wù),此時(shí)host是符合預(yù)期的,因此可以請(qǐng)求成功。

網(wǎng)關(guān)不帶host的時(shí)候,host地址為本機(jī)ip,此時(shí)發(fā)送http請(qǐng)求,對(duì)下游python服務(wù)來說,host是不符合預(yù)期的,因此請(qǐng)求失敗。

因此,當(dāng)網(wǎng)關(guān)不設(shè)置host的時(shí)候,golang服務(wù)必需要設(shè)置host才能訪問到算法服務(wù)。

(2)抓取目標(biāo)域名請(qǐng)求體

1)網(wǎng)關(guān)沒有配置header,且proxy清空header

# sudo tcpdump -i wlo1 -A dst host 下游python服務(wù)域名
......Pa.I.....P...(...POST /xxx?xxx=test HTTP/1.1
Host: 10.xx:8080
Content-Length: 3013
Traceid: f70cef79265d41be80002ab8ee10abf5
Traceparent: 00-f70cef79265d41be80002ab8ee10abf5-07f71cc5604c734a-00

2)網(wǎng)關(guān)配置header,且proxy清空header

# sudo tcpdump -i wlo1 -A dst host 下游python服務(wù)域名
......P!.....Q`P...(...POST /location?map_id=test HTTP/1.1
Host: 下游python服務(wù)域名
Content-Length: 3013
Traceid: 972e155927b3fcf665550ab0824acb87
Traceparent: 00-972e155927b3fcf665550ab0824acb87-627675466a61796b-7462733d667273

可以發(fā)現(xiàn),差異主要就在host部分。也就說,網(wǎng)關(guān)設(shè)置了header之后,tcpdump抓包的host是符合預(yù)期的。
我們?cè)?code>golang服務(wù)中設(shè)置req.Header發(fā)現(xiàn)依然沒有效果,抓包結(jié)果顯示host不符合預(yù)期,預(yù)期是下游python服務(wù)域名才對(duì)。

3、go設(shè)置host方式

目前go中設(shè)置host一共有三種方式:

req.Host
	req.Host 是一個(gè)字符串類型的字段,表示了 HTTP 請(qǐng)求頭部中的 Host 信息。
	如果該字段為空,則默認(rèn)使用請(qǐng)求的目標(biāo)地址(即 req.URL.Host)作為 Host 信息。
req.Header.Set("host")  # 目前使用且設(shè)置host失效
	header中的host字段。
req.URL.HOST
	request.URL.Host 是一個(gè)字符串類型的字段,表示 HTTP 請(qǐng)求中目標(biāo)
	地址的 HOST信息,跟URL是對(duì)應(yīng)的。

代碼中使用的是req.Header.Set("host")的方式,但是沒有生效。

proxy.Director = func(req *http.Request) {
		originalDirector(req)
		modifyRequest(req)
		// 添加自定義標(biāo)頭
		req.Header.Set("traceId", traceId)
		req.Header.Set("host", "xxx")
		log.Infof("req.Header:(%#v)", req.Header)
	}
打印結(jié)果,沒有host!!!

(1)打印req.URL.HOST

打印req.URL,發(fā)現(xiàn)url中的host已經(jīng)被替換了。因?yàn)?code>httputil包在使用反向代理的時(shí)候,會(huì)觸發(fā)一個(gè)rewrite方法,把targethost設(shè)置到req.URL.HOST

req.url:(\u0026url.URL{Scheme:\"http\", Opaque:\"\", User:(*url.Userinfo)(nil), 
Host:\"下游python服務(wù)域名\", 
Path:\"/xx\", RawPath:\"\", OmitHost:false, ForceQuery:false, 
RawQuery:\"map_id=test\", Fragment:\"\", RawFragment:\"\"}
# proxy源碼
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
	director := func(req *http.Request) {
		rewriteRequestURL(req, target)
	}
	return &ReverseProxy{Director: director}
}
func rewriteRequestURL(req *http.Request, target *url.URL) {
	targetQuery := target.RawQuery
	req.URL.Scheme = target.Scheme
	req.URL.Host = target.Host
	req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
	if targetQuery == "" || req.URL.RawQuery == "" {
		req.URL.RawQuery = targetQuery + req.URL.RawQuery
	} else {
		req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
	}
}

(2)設(shè)置req.Host

設(shè)置之后進(jìn)行tcpdump抓包,發(fā)現(xiàn)host已經(jīng)被成功設(shè)置,http請(qǐng)求成功。

......P.H......P...(...POST /location?map_id=test HTTP/1.1
Host: 下游python服務(wù)域名
Content-Length: 3013
Traceid: 447e2cc680bed4f2fbfd3941bcda4a42
Traceparent: 00-447e2cc680bed4f2fbfd3941bcda4a42-fffc5c1b967b3f70-7462733d667273

4、為什么設(shè)置header里面的host沒有生效?

參考資料:
如何正確在 Golang 中在處理 Http Request 之前修改 Host 字段內(nèi)容
這篇文章解釋的很清晰了,go官方的http策略,大無語。

到此這篇關(guān)于golang反向代理設(shè)置host不生效的文章就介紹到這了,更多相關(guān)golang反向代理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • GoLand無法Debug問題的解決辦法

    GoLand無法Debug問題的解決辦法

    今天突然要寫下go代碼的項(xiàng)目,突然發(fā)現(xiàn)無法debug,下面這篇文章主要介紹了GoLand無法Debug問題的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-10-10
  • Golang 內(nèi)存管理簡(jiǎn)單技巧詳解

    Golang 內(nèi)存管理簡(jiǎn)單技巧詳解

    這篇文章主要為大家介紹了Golang 內(nèi)存管理簡(jiǎn)單技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • go語言返回1-99之間隨機(jī)數(shù)的方法

    go語言返回1-99之間隨機(jī)數(shù)的方法

    這篇文章主要介紹了go語言返回1-99之間隨機(jī)數(shù)的方法,實(shí)例分析了Go語言中rand的使用技巧,需要的朋友可以參考下
    2015-03-03
  • Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲是一種高效抓取大量數(shù)據(jù)的利器。Golang語言天生支持并發(fā)和多線程,可以輕松實(shí)現(xiàn)多線程爬蟲的開發(fā)。通過使用Golang的協(xié)程和通道,可以實(shí)現(xiàn)爬蟲的高效并發(fā)抓取、數(shù)據(jù)處理和存儲(chǔ)
    2023-05-05
  • Golang的鎖機(jī)制與使用技巧小結(jié)

    Golang的鎖機(jī)制與使用技巧小結(jié)

    本文主要介紹了Golang的鎖機(jī)制與使用技巧小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用

    Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用

    這篇文章主要介紹了Golang協(xié)程池的實(shí)現(xiàn)與應(yīng)用,使用協(xié)程池的好處是減少在創(chuàng)建和銷毀協(xié)程上所花的時(shí)間以及資源的開銷,解決資源不足的問題,需要詳細(xì)了解可以參考下文
    2023-05-05
  • Go語言中程序是怎么編譯的實(shí)現(xiàn)

    Go語言中程序是怎么編譯的實(shí)現(xiàn)

    本文主要介紹了Go語言中程序是怎么編譯的實(shí)現(xiàn),深入探討Go語言的編譯機(jī)制和最新的模塊管理系統(tǒng)Go Modules的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 關(guān)于golang監(jiān)聽rabbitmq消息隊(duì)列任務(wù)斷線自動(dòng)重連接的問題

    關(guān)于golang監(jiān)聽rabbitmq消息隊(duì)列任務(wù)斷線自動(dòng)重連接的問題

    這篇文章主要介紹了golang監(jiān)聽rabbitmq消息隊(duì)列任務(wù)斷線自動(dòng)重連接,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • golang針對(duì)map的判斷,刪除操作示例

    golang針對(duì)map的判斷,刪除操作示例

    這篇文章主要介紹了golang針對(duì)map的判斷,刪除操作,結(jié)合具體實(shí)例形式分析了Go語言map判斷與刪除相關(guān)操作技巧,需要的朋友可以參考下
    2017-03-03
  • jenkins配置golang?代碼工程自動(dòng)發(fā)布的實(shí)現(xiàn)方法

    jenkins配置golang?代碼工程自動(dòng)發(fā)布的實(shí)現(xiàn)方法

    這篇文章主要介紹了jenkins配置golang?代碼工程自動(dòng)發(fā)布,jks是個(gè)很好的工具,使用方法也很多,我只用了它簡(jiǎn)單的功能,對(duì)jenkins配置golang相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-07-07

最新評(píng)論

亚东县| 克拉玛依市| 通化县| 大城县| 临沂市| 大兴区| 陕西省| 安乡县| 武鸣县| 靖远县| 德化县| 蕉岭县| 弥渡县| 洪湖市| 鲁甸县| 清丰县| 安远县| 萨迦县| 浦北县| 河津市| 黄梅县| 博兴县| 冕宁县| 木兰县| 成武县| 黔东| 峨山| 贵港市| 叙永县| 长沙县| 广东省| 东莞市| 红安县| 鲜城| 彭山县| 德清县| 尤溪县| 阿拉善左旗| 漳浦县| 黄石市| 新丰县|