6

我使用grpc-gateway从我的原型定义中托管一个 HTTP 服务器。整体效果很好。

但是,对于一个特殊的端点,我不想返回一个值,而是想做一个 302 重定向到托管在 s3 中的图像。

如果你想通过 grpc-gateway 返回一个错误,你可以像这样返回

nil, status.Error(codes.Unauthenticated, "Nope")

我想知道是否有类似的东西可以做 302 重定向?

据我从这个页面得到的似乎不太可能。我希望我忽略了一些东西。

4

3 回答 3

5

您还可以使用WithForwardResponseOption方法,该方法允许您修改响应和响应标头。

这是我为Location响应设置标题所做的。

  1. Location使用元数据在 GRPC 方法中设置标头。这会Grpc-Metadata-Location在您的回复中添加标题。
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
}
  1. 如果Grpc-Metadata-Location您的 GRPC 响应标头中存在标头,请同时设置 HTTPLocation标头和状态代码。
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
}
  1. 将此函数设置为选项NewServeMux
grpcGatewayMux := runtime.NewServeMux(
    runtime.WithForwardResponseOption(responseHeaderMatcher),
)
于 2020-01-27T05:07:11.130 回答
3

没有直接的方法。但是有一个解决方法。

gRPC 中没有类似 302 的概念。所以简单的错误码映射是行不通的。但是您可以覆盖每个方法的响应转发器,以便它redirectURL从响应中提取并设置 HTTP 状态代码和Location标头。

文档链接: https ://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_your_gateway/#mutate-response-messages-or-set-response-headers

于 2018-05-01T06:54:27.360 回答
1

查看您提到的代码,它似乎只是将grpc 状态代码直接映射到它们最接近的 http 等效项。规范中似乎没有任何代码真正映射到 http 重定向。假设您使用网关将浏览器连接到 grpc 服务,我是否正确?

我的建议是以某种方式将重定向工作到协议中。如果对某些方法的响应类似于:

message HelloResponse {
  string reply = 1;
  bool shouldRedirect = 2;
  string redirectURL = 3;
}

然后,如果接收者可以从响应中检测到这一点并重定向客户端。有点不那么神奇,但仍然可以让您在需要时进行重定向。

于 2018-04-17T17:36:13.693 回答