首頁  >  文章  >  後端開發  >  在golang中覆蓋gRPC客戶端的http主機頭

在golang中覆蓋gRPC客戶端的http主機頭

王林
王林轉載
2024-02-09 08:18:181267瀏覽

在golang中覆蓋gRPC客戶端的http主機頭

在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 標頭的值是使用者撥號目標的端點部分,其格式為

url://authority/endpoint

###gRPC-Go 也支援撥號選項來覆寫此 ###authority###。請參閱:###https://pkg.go.dev/google.golang.org/ grpc#WithAuthority###。但也要注意,此撥號選項會覆寫 TLS 握手期間使用的 ###ServerName### 值。 ### ###如果您有更多問題/疑慮,請隨時透過我們的 GitHub 儲存庫與我們聯絡。您的查詢將在那裡得到更好的回應時間。 ###

以上是在golang中覆蓋gRPC客戶端的http主機頭的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除