Class GrpcResponseStatusResolver
HttpResponse, independently
of transport.
This lives in core, and is shared by every gRPC response path -- GrpcToHttpResponseHandler
(HTTP/1.1 and HTTP/2), GrpcHttp3Adapter and Http3GrpcResponseWriter (HTTP/3) --
because the resolution rules are a property of the gRPC contract, not of the wire protocol.
Duplicating them per transport is how the two defects this class was extracted to fix arose:
an expectation authored with withTrailer("grpc-status", ...) returned NOT_FOUND
over HTTP/2 but OK over HTTP/3, and an unmatched request over HTTP/3 fabricated a
success.
Resolution order:
grpc-status-nameheader (a MockServer convenience, mapped by name)- numeric
grpc-status, read from the headers or the trailers -- consumer documentation recommends authoring it as a trailer, so both must work - for a non-2xx HTTP status, the gRPC-over-HTTP/2 specification's HTTP-status mapping
(see
GrpcStatusMapper.fromHttpTransportStatus(int)) -- this is a transport failure, and its body must be discarded rather than framed - otherwise
OK
GrpcStatusMapper.fromCode(int)
-- that lookup is getOrDefault(code, UNKNOWN), so a non-standard or future code such as
42 would be silently rewritten to 2.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final classThe resolved status, plus whether it came from an HTTP-level failure (in which case the response body is not a protobuf message of the method's output type and must be dropped). -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final StringMockServer's internal marker identifying a synthesized DEADLINE_EXCEEDED response. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionstatic StringexplicitStatus(HttpResponse response) Returns the explicitly-authored gRPC status as a decimal string, ornullif the response carries none.static StringfirstHeaderOrTrailer(HttpResponse response, String name) Reads a value from the response headers, falling back to the trailers.static StringfirstTrailer(HttpResponse response, String name) Reads the first value of a response trailer, ornull.static booleanisGrpcProtocolMetadata(String name) Returnstrueif the header or trailer name is gRPC protocol metadata that a transport emits itself, or a connection-specific field that is illegal on HTTP/2 and HTTP/3, and which must therefore not be copied through from an expectation's response headers.static HeaderspassThroughHeaders(HttpResponse response) Returns the response's headers that should be passed through to a gRPC client, excluding gRPC protocol metadata the transport emits itself.static HeaderspassThroughTrailers(HttpResponse response) Returns the response's trailers that should be passed through to a gRPC client as trailing metadata, excluding gRPC protocol metadata the transport emits itself.resolve(HttpResponse response) Resolves the status for a response, including the HTTP-status fallback.
-
Field Details
-
GRPC_DEADLINE_RESPONSE_MARKER
MockServer's internal marker identifying a synthesized DEADLINE_EXCEEDED response.Defined here so core and netty cannot drift;
GrpcToHttpResponseHandler.DEADLINE_RESPONSE_HEADERis an alias of this constant, andGrpcToHttpResponseHandlerTestpins them equal.- See Also:
-
-
Constructor Details
-
GrpcResponseStatusResolver
public GrpcResponseStatusResolver()
-
-
Method Details
-
resolve
Resolves the status for a response, including the HTTP-status fallback. -
explicitStatus
Returns the explicitly-authored gRPC status as a decimal string, ornullif the response carries none. A non-numericgrpc-status(a protocol violation) is treated as absent. -
firstHeaderOrTrailer
Reads a value from the response headers, falling back to the trailers. -
firstTrailer
Reads the first value of a response trailer, ornull. -
isGrpcProtocolMetadata
Returnstrueif the header or trailer name is gRPC protocol metadata that a transport emits itself, or a connection-specific field that is illegal on HTTP/2 and HTTP/3, and which must therefore not be copied through from an expectation's response headers. -
passThroughHeaders
Returns the response's headers that should be passed through to a gRPC client, excluding gRPC protocol metadata the transport emits itself. -
passThroughTrailers
Returns the response's trailers that should be passed through to a gRPC client as trailing metadata, excluding gRPC protocol metadata the transport emits itself.This is the trailer twin of
passThroughHeaders(HttpResponse)and exists for the same reason: the exclusion rule is a property of the gRPC contract rather than of a wire protocol, so it must not be re-derived per transport. Filtering outgrpc-status/grpc-message/grpc-status-nameis what stops a user-authored trailer overriding or spoofing the status the transport itself resolved and emits -- the same exclusion the HTTP/2 path applies throughGrpcToHttpResponseHandler.remainingTrailers. Connection-specific fields, pseudo-header names andcontent-length/content-typeare excluded too because RFC 9114 forbids all of them in a trailer section, and a conforming client "MUST treat" a message carrying one as malformed.
-