欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

一、背景

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

在這里插入圖片描述

二、排查過程

1、打印req.header

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

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

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

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

2、tcpdump抓包分析

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

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

host: xxx # 網(wǎng)關不設置header的時候,host是本機ip
host: localization.xx # 網(wǎng)關設置header的時候,host為目標主機域名

如上所示,可以得到結論,host本來就代表目標主機,網(wǎng)關那邊設置host的時候,golang服務進行轉發(fā),會把host帶到下游python服務,此時host是符合預期的,因此可以請求成功。

網(wǎng)關不帶host的時候,host地址為本機ip,此時發(fā)送http請求,對下游python服務來說,host是不符合預期的,因此請求失敗。

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

(2)抓取目標域名請求體

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

# sudo tcpdump -i wlo1 -A dst host 下游python服務域名
......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)關配置header,且proxy清空header

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

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

3、go設置host方式

目前go中設置host一共有三種方式:

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

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

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

(1)打印req.URL.HOST

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

req.url:(\u0026url.URL{Scheme:\"http\", Opaque:\"\", User:(*url.Userinfo)(nil), 
Host:\"下游python服務域名\", 
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)設置req.Host

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

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

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

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

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

相關文章

  • Golang 模塊引入及表格讀寫業(yè)務快速實現(xiàn)示例

    Golang 模塊引入及表格讀寫業(yè)務快速實現(xiàn)示例

    這篇文章主要為大家介紹了Golang模塊引入及表格讀寫業(yè)務的快速實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • go Gin安裝及初始化操作示例

    go Gin安裝及初始化操作示例

    這篇文章主要介紹了gin安裝及初始化,修改啟動端口,get/post?請求參數(shù),模型綁定shouldbind,自定義驗證器/表單驗證,等操作步驟,有需要的朋友可以借鑒參考下
    2022-04-04
  • ubuntu安裝golang并設置goproxy的方法步驟

    ubuntu安裝golang并設置goproxy的方法步驟

    在Ubuntu系統(tǒng)上安裝Go語言(Golang)有多種方法,包括使用包管理器、從源代碼編譯安裝以及使用版本管理工具如gvm,安裝完成后,為了方便管理Go語言項目依賴,需要設置GOPATH環(huán)境變量并配置Go代理,本文介紹ubuntu安裝golang并設置goproxy的方法,感興趣的朋友一起看看吧
    2024-10-10
  • goland最新激活辦法

    goland最新激活辦法

    這篇文章主要介紹了goland最新激活辦法,激活方法真的超級簡單,只需要把腳本內(nèi)容復制到對應文件,并運行該腳本就可以了,需要的朋友可以參考下
    2021-12-12
  • 使用go在mangodb中進行CRUD操作

    使用go在mangodb中進行CRUD操作

    這篇文章主要介紹了使用go在mangodb中進行CRUD操作,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-10-10
  • go內(nèi)存緩存BigCache實現(xiàn)BytesQueue源碼解讀

    go內(nèi)存緩存BigCache實現(xiàn)BytesQueue源碼解讀

    這篇文章主要為大家介紹了go內(nèi)存緩存BigCache實現(xiàn)BytesQueue源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • Golang如何調(diào)用Python代碼詳解

    Golang如何調(diào)用Python代碼詳解

    這篇文章主要給大家介紹了關于Golang如何調(diào)用Python代碼的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-10-10
  • GO日志打印如何添加goroutineid

    GO日志打印如何添加goroutineid

    今天想給日志添加一個前綴,以區(qū)分不同goroutine的日志,方便做并發(fā)問題的排查,做日志跟蹤,下面給大家分享GO日志打印如何添加goroutineid,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • Golang使用Gin框架實現(xiàn)路由分類處理請求流程詳解

    Golang使用Gin框架實現(xiàn)路由分類處理請求流程詳解

    Gin是一個golang的微框架,封裝比較優(yōu)雅,具有快速靈活,容錯方便等特點,這篇文章主要介紹了Golang使用Gin框架實現(xiàn)路由分類處理請求,感興趣的同學可以參考下文
    2023-05-05
  • 使用Go實現(xiàn)一個百行聊天服務器的示例代碼

    使用Go實現(xiàn)一個百行聊天服務器的示例代碼

    前段時間, redis作者整了個c語言版本的聊天服務器,代碼量攏共不過百行,于是, 心血來潮下, 我也整了個Go語言版本, 簡單來說就是實現(xiàn)了一個聊天室的功能,文中通過代碼示例給大家介紹的非常詳細,需要的朋友可以參考下
    2023-12-12

最新評論