【问题标题】:ServiceTalk gRPC error code mapping for StreamingHttpServiceFilterStreamingHttpServiceFilter 的 ServiceTalk gRPC 错误代码映射
【发布时间】:2021-02-25 21:43:46
【问题描述】:

我们实现了StreamingHttpServiceFilter,它对每个请求执行身份验证。

在身份验证不成功时,我们使用以下代码返回 401 Unauthorized 错误:

private StreamingHttpResponse createUnauthorizedResponse(final StreamingHttpResponseFactory responseFactory) {
        return responseFactory.unauthorized();
    }

当过滤器返回错误时,在客户端我们会收到以下消息

GrpcStatus{code=INTERNAL, cause=null, description='HTTP状态码: 401 未经授权的无效内容类型:空标头: NettyH2HeadersToHttpHeaders[传输编码:]'}

如您所见,GrpcStatus 有code=INTERNAL,这意味着客户端需要解析description,并找出错误代码。

是否可以在准备来自过滤器的响应时添加任何额外的元数据,以便代码可以是 UNAUTHENTICATED,或者是否有任何客户端可用的工具可以读取描述并转换为 http 状态代码?

【问题讨论】:

    标签: java grpc servicetalk


    【解决方案1】:

    gRPC 协议不太关注 HTTP 响应状态码,它总是期待200 OK。其他状态代码将映射到INTERNAL gRPC 代码。相反,它依赖于grpc-statusgrpc-message,它们作为 HTTP/2 响应消息的尾部(或没有有效负载主体时的头部)出现。请参阅 gRPC over HTTP2 文档中的 Responses 部分。

    当您处于 HTTP 级别并编写 StreamingHttpServiceFilter 时,您负责根据 gRPC 协议生成响应。最小响应是Trailers-Only 并包含HTTP-Status Content-Type Status [Status-Message] *Custom-Metadata

    对于所描述的用例,手动生成适当的响应应该很容易。

    另一种方法是从 gRPC 级别抛出 GrpcStatusException:从服务端点或从 gRPC 过滤器。然后 ServiceTalk 会将该异常映射到具有所有必需标头字段的适当 HTTP/2 响应。

    // Throws GrpcStatusException:
    throw new GrpcStatus(GrpcStatusCode.UNAUTHENTICATED, null, "Your message for the client")
            .asException();
    

    但是,在您的情况下,通过AsyncContext 将身份验证信息从StreamingHttpServiceFilter 级别传输到 gRPC 过滤器可能会更加复杂。可能不值得。

    【讨论】:

      猜你喜欢
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 2015-09-14
      • 1970-01-01
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多