【问题标题】:How to do a 302 redirect in grpc-gateway如何在 grpc-gateway 中进行 302 重定向
【发布时间】:2018-04-17 13:00:14
【问题描述】:

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

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

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

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

不知道有没有类似做302重定向的东西?

据我从this page 得到的,这似乎不太可能。我希望我忽略了一些东西。

【问题讨论】:

    标签: go grpc-gateway


    【解决方案1】:

    您还可以使用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),
    )
    

    【讨论】:

    【解决方案2】:

    没有简单的方法。但是有一个解决方法。

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

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

    【讨论】:

    • 我遇到了同样的用例,但是如何从消息中提取redirectURL?如果我这样做resp.redirectURL,编译器会告诉我 proto.Message 没有实现它。我必须先做一些投射,还是类似的?
    • @Markus 对此有何解决方案?
    【解决方案3】:

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

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

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

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

    【讨论】:

    • 嗨,这是一种选择,但是,我的意图是直接将此端点用作<img src="https://host/endpoint" /> 的一部分,而不在前端进行处理。
    • 那么你可能会受到更多限制。我能想到的就是用你想要的功能修改网关。
    • @captncraig 在转发响应之前不能在 grpc 服务器端完成吗?
    • @UmutBenzer 你最后做了什么?
    • 我最终在客户端实现了我们的逻辑。在一个请求中,我获取图像的 URL,在第二个请求中,我们通过使用第一个请求的响应来获取图像本身。这是在我得知WithOutgoingHeaderMatcher 存在这样的事情之前实施的。我不知道这是否对我有用。
    猜你喜欢
    • 2020-02-11
    • 2021-08-01
    • 2013-10-08
    • 1970-01-01
    • 2017-02-06
    • 2012-03-10
    • 1970-01-01
    • 2021-09-13
    • 2020-03-16
    相关资源
    最近更新 更多