如何在grpc-gateway中进行302重定向

时间:2018-04-17 13:00:14

标签: go grpc-gateway

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

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

如果您想通过grpc-gateway返回错误,可以像

一样返回
nil, status.Error(codes.Unauthenticated, "Nope")

我想知道302重定向是否有类似内容?

据我所知this page,似乎不太可能。我希望我忽视了一些事情。

3 个答案:

答案 0 :(得分:3)

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

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

  1. 使用元数据在GRPC方法中设置Location头。这会在您的响应中添加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响应标头中存在Grpc-Metadata-Location标头,请同时设置HTTP Location标头和状态代码。
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),
)

答案 1 :(得分:2)

没有直截了当的方式。但是有一种解决方法。

gRPC中没有与302类似的概念。如此简单的错误代码映射将无法正常工作。 但是您可以为每个方法覆盖一个响应转发器,以便从响应中提取redirectURL并设置HTTP状态代码和Location标头。

https://grpc-ecosystem.github.io/grpc-gateway/docs/customizingyourgateway.html#replace-a-response-forwarder-per-method

答案 2 :(得分:1)

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

我的建议是以某种方式重定向到协议。如果对某些方法的响应如下:

,该怎么办?
message HelloResponse {
  string reply = 1;
  bool shouldRedirect = 2;
  string redirectURL = 3;
}

然后,如果接收方可以从响应中检测到并重定向客户端。不那么神奇,但如果需要,仍然允许你进行重定向。