在golang中覆盖gRPC客户端的http主机头

yzuktlbb  于 2023-09-28  发布在  Go
关注(0)|答案(1)|浏览(176)

我通过一个gRPC客户端发送了一个连接请求

conn, err := grpc.Dial("hostname:port",opts...)

从服务器端,我在http.request中看到了host。然后,我有我的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上下文中(将填充在http 2请求的报头中)。此请求将被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)update:原来在http 2中主机头被:Authority伪头取代了。

wpcxdonn

wpcxdonn1#

gRPC使用HTTP/2,不使用:host头,而是使用:authority伪头。此标头的值在此处确定:https://github.com/grpc/grpc-go/blob/aa6ce35c792863305e0f42acc27f2c7153275f89/clientconn.go#L1942
医生
默认情况下,用于:authority标头的值是用户拨号目标的端点部分,格式为url://authority/endpoint
gRPC-Go还支持覆盖此authority的拨号选项。请参阅:https://pkg.go.dev/google.golang.org/grpc#WithAuthority。但也要注意,此拨号选项覆盖了TLS握手期间使用的ServerName值。
如果您有更多问题/疑虑,请随时通过我们的GitHub存储库与我们联系。您的查询将在那里看到更好的响应时间。

相关问题