如何在 grpc-gateway 中进行 302 重定向
How to do a 302 redirect in grpc-gateway
我使用 grpc-gateway 在我的原型定义之外托管一个 HTTP 服务器。整体效果很好。
但是,对于一个特殊端点,我不想 return 返回值,而是想对 s3 中托管的图像进行 302 重定向。
如果你想通过 grpc-gateway return 一个错误,你可以 return 它就像
nil, status.Error(codes.Unauthenticated, "Nope")
我想知道是否有类似的东西可以做 302 重定向?
据我所知 this page 似乎不太可能。我希望我忽略了一些东西。
查看您提到的代码,它似乎只是将 grpc status codes 直接映射到最接近的 http 等价物。规范中似乎没有任何代码真正映射到 http 重定向。我假设您使用网关将浏览器连接到 grpc 服务是否正确?
我的建议是以某种方式将重定向工作到协议中。如果对某些方法的响应类似于:
message HelloResponse {
string reply = 1;
bool shouldRedirect = 2;
string redirectURL = 3;
}
然后如果接收方可以从响应中检测到并重定向客户端。不那么神奇,但仍然可以让您在需要时进行重定向。
没有直接的方法。但有一个解决方法。
gRPC 中没有类似于 302 的概念。因此简单的错误代码映射将无法正常工作。
但是您可以覆盖每个方法的响应转发器,以便它从响应中提取 redirectURL
并设置 HTTP 状态代码和 Location
header.
您还可以使用 WithForwardResponseOption 方法来修改您的回复和回复 headers.
这是我设置 Location
header 响应的方法。
- 使用元数据在您的 GRPC 方法中设置
Location
header。这会将 Grpc-Metadata-Location
header 添加到您的回复中。
func (s *Server) CreatePayment(ctx context.Context, in *proto.Request) (*proto.Response, error) {
header := metadata.Pairs("Location", url)
grpc.SendHeader(ctx, header)
return &proto.Response{}, nil
}
- 如果您的 GRPC 响应 header 中存在
Grpc-Metadata-Location
header,请同时设置 HTTP Location
header 和状态码。
func responseHeaderMatcher(ctx context.Context, w http.ResponseWriter, resp proto.Message) error {
headers := w.Header()
if location, ok := headers["Grpc-Metadata-Location"]; ok {
w.Header().Set("Location", location[0])
w.WriteHeader(http.StatusFound)
}
return nil
}
- 将此功能设置为
NewServeMux
中的选项:
grpcGatewayMux := runtime.NewServeMux(
runtime.WithForwardResponseOption(responseHeaderMatcher),
)
我使用 grpc-gateway 在我的原型定义之外托管一个 HTTP 服务器。整体效果很好。
但是,对于一个特殊端点,我不想 return 返回值,而是想对 s3 中托管的图像进行 302 重定向。
如果你想通过 grpc-gateway return 一个错误,你可以 return 它就像
nil, status.Error(codes.Unauthenticated, "Nope")
我想知道是否有类似的东西可以做 302 重定向?
据我所知 this page 似乎不太可能。我希望我忽略了一些东西。
查看您提到的代码,它似乎只是将 grpc status codes 直接映射到最接近的 http 等价物。规范中似乎没有任何代码真正映射到 http 重定向。我假设您使用网关将浏览器连接到 grpc 服务是否正确?
我的建议是以某种方式将重定向工作到协议中。如果对某些方法的响应类似于:
message HelloResponse {
string reply = 1;
bool shouldRedirect = 2;
string redirectURL = 3;
}
然后如果接收方可以从响应中检测到并重定向客户端。不那么神奇,但仍然可以让您在需要时进行重定向。
没有直接的方法。但有一个解决方法。
gRPC 中没有类似于 302 的概念。因此简单的错误代码映射将无法正常工作。
但是您可以覆盖每个方法的响应转发器,以便它从响应中提取 redirectURL
并设置 HTTP 状态代码和 Location
header.
您还可以使用 WithForwardResponseOption 方法来修改您的回复和回复 headers.
这是我设置 Location
header 响应的方法。
- 使用元数据在您的 GRPC 方法中设置
Location
header。这会将Grpc-Metadata-Location
header 添加到您的回复中。
func (s *Server) CreatePayment(ctx context.Context, in *proto.Request) (*proto.Response, error) {
header := metadata.Pairs("Location", url)
grpc.SendHeader(ctx, header)
return &proto.Response{}, nil
}
- 如果您的 GRPC 响应 header 中存在
Grpc-Metadata-Location
header,请同时设置 HTTPLocation
header 和状态码。
func responseHeaderMatcher(ctx context.Context, w http.ResponseWriter, resp proto.Message) error {
headers := w.Header()
if location, ok := headers["Grpc-Metadata-Location"]; ok {
w.Header().Set("Location", location[0])
w.WriteHeader(http.StatusFound)
}
return nil
}
- 将此功能设置为
NewServeMux
中的选项:
grpcGatewayMux := runtime.NewServeMux(
runtime.WithForwardResponseOption(responseHeaderMatcher),
)