在golang中覆蓋gRPC客戶端的http主機頭是常見的需求。 gRPC是一種高效能、跨語言的遠端過程呼叫框架,而在使用gRPC進行通訊時,有時需要自訂http請求的主機頭。 php小編西瓜將為您介紹如何在golang中實現這個功能,以便更好地滿足您的業務需求。
我透過 gRPC 用戶端透過連線發送了請求
conn, err := grpc.Dial("hostname:port",opts...)
從伺服器端,我看到http.request中的host
是確切的hostname:port
。然後,我的 nginx 伺服器設定如下
server { listen port http2; server_name hostname; # ... } server { listen port http2; server_name another_hostname; # ... }
這是一種常見的虛擬主機技術。
無論我在 grpc.Dial(xxx:port)
中使用哪個主機名,它都可以正常運作。然而,當我把
md := metadata.New(map[string]string{"host":"another_hostname:port"})
在grpc上下文中(將填入http2請求的標頭中)。這個請求將被 nginx 阻止,我得到了
rpc error: code = Internal desc = unexpected HTTP status code received from server: 400 (Bad Request); transport: received unexpected content-type "text/html"
之所以要手動輸入主機名,是因為grpc.Dial
中的主機名稱是固定的。而且我不能用不同的位置來做反向代理,因為port
後面是restful api的路由路徑。
如果主機名稱固定且路由也固定,還有其他方法可以進行反向代理嗎?
(23/09)更新:結果發現http2中的host頭被:Authority
偽頭取代了。
gRPC 使用 HTTP/2,不使用 :host
標頭,而是使用 :authority
偽標頭。此標頭的值在此處確定: https://github .com/grpc/grpc-go/blob/aa6ce35c792863305e0f42acc27f2c7153275f89/clientconn.go#L1942
TL;博士
預設情況下,用於 :authority
標頭的值是使用者撥號目標的端點部分,其格式為
。
###gRPC-Go 也支援撥號選項來覆寫此 ###authority###。請參閱:###https://pkg.go.dev/google.golang.org/ grpc#WithAuthority###。但也要注意,此撥號選項會覆寫 TLS 握手期間使用的 ###ServerName### 值。 ### ###如果您有更多問題/疑慮,請隨時透過我們的 GitHub 儲存庫與我們聯絡。您的查詢將在那裡得到更好的回應時間。 ###以上是在golang中覆蓋gRPC客戶端的http主機頭的詳細內容。更多資訊請關注PHP中文網其他相關文章!