StreamingHttpServiceFilter 的 ServiceTalk gRPC 错误代码映射
ServiceTalk gRPC error code mapping for StreamingHttpServiceFilter
我们已经实现了 StreamingHttpServiceFilter
对每个请求执行身份验证。
在身份验证不成功时,我们使用以下代码 return 401 未授权错误:
private StreamingHttpResponse createUnauthorizedResponse(final StreamingHttpResponseFactory responseFactory) {
return responseFactory.unauthorized();
}
当过滤器 return 出错时,在客户端我们收到以下消息
GrpcStatus{code=INTERNAL, cause=null, description='HTTP status code:
401 Unauthorized invalid content-type: null headers:
NettyH2HeadersToHttpHeaders[transfer-encoding: ]'}
如您所见,GrpcStatus 有 code=INTERNAL
,这意味着客户端需要解析 description
,并找出错误代码。
是否可以在准备来自过滤器的响应时添加任何额外的元数据,以便代码可以是 UNAUTHENTICATED
或者是否有任何可用的客户端实用程序读取描述并转换为 http 状态代码?
gRPC 协议不太关注 HTTP 响应状态码,它总是期望 200 OK
。其他状态代码将映射到 INTERNAL
gRPC 代码。相反,它依赖于 HTTP/2 响应消息的 grpc-status
和 grpc-message
作为尾部(或 headers,当没有负载 body 时)。请参阅 gRPC over HTTP2 文档中的 Responses 部分。
当您处于 HTTP 级别并编写 StreamingHttpServiceFilter
时,您负责根据 gRPC 协议生成响应。最小响应是 Trailers-Only
并包含 HTTP-Status Content-Type Status [Status-Message] *Custom-Metadata
.
对于所描述的 use-case,手动生成适当的响应应该很容易。
另一种方法是从 gRPC 级别抛出 GrpcStatusException
:从服务端点或 gRPC-filter。然后 ServiceTalk 将该异常映射到适当的 HTTP/2 响应,其中包含所有必需的 header 字段。
// Throws GrpcStatusException:
throw new GrpcStatus(GrpcStatusCode.UNAUTHENTICATED, null, "Your message for the client")
.asException();
但是,在您的情况下,通过 AsyncContext
将身份验证信息从 StreamingHttpServiceFilter
级别传输到 gRPC-filter 可能会更加复杂。可能不值得。
我们已经实现了 StreamingHttpServiceFilter
对每个请求执行身份验证。
在身份验证不成功时,我们使用以下代码 return 401 未授权错误:
private StreamingHttpResponse createUnauthorizedResponse(final StreamingHttpResponseFactory responseFactory) {
return responseFactory.unauthorized();
}
当过滤器 return 出错时,在客户端我们收到以下消息
GrpcStatus{code=INTERNAL, cause=null, description='HTTP status code: 401 Unauthorized invalid content-type: null headers: NettyH2HeadersToHttpHeaders[transfer-encoding: ]'}
如您所见,GrpcStatus 有 code=INTERNAL
,这意味着客户端需要解析 description
,并找出错误代码。
是否可以在准备来自过滤器的响应时添加任何额外的元数据,以便代码可以是 UNAUTHENTICATED
或者是否有任何可用的客户端实用程序读取描述并转换为 http 状态代码?
gRPC 协议不太关注 HTTP 响应状态码,它总是期望 200 OK
。其他状态代码将映射到 INTERNAL
gRPC 代码。相反,它依赖于 HTTP/2 响应消息的 grpc-status
和 grpc-message
作为尾部(或 headers,当没有负载 body 时)。请参阅 gRPC over HTTP2 文档中的 Responses 部分。
当您处于 HTTP 级别并编写 StreamingHttpServiceFilter
时,您负责根据 gRPC 协议生成响应。最小响应是 Trailers-Only
并包含 HTTP-Status Content-Type Status [Status-Message] *Custom-Metadata
.
对于所描述的 use-case,手动生成适当的响应应该很容易。
另一种方法是从 gRPC 级别抛出 GrpcStatusException
:从服务端点或 gRPC-filter。然后 ServiceTalk 将该异常映射到适当的 HTTP/2 响应,其中包含所有必需的 header 字段。
// Throws GrpcStatusException:
throw new GrpcStatus(GrpcStatusCode.UNAUTHENTICATED, null, "Your message for the client")
.asException();
但是,在您的情况下,通过 AsyncContext
将身份验证信息从 StreamingHttpServiceFilter
级别传输到 gRPC-filter 可能会更加复杂。可能不值得。