From 8f2d7d1e6d8edc95704b499e4d47b786adfcc26f Mon Sep 17 00:00:00 2001 From: becomeStar Date: Sat, 21 Mar 2026 16:35:44 +0900 Subject: [PATCH] core: Clarify missing content-type on HTTP error responses Improve the client-side diagnostic for HTTP error responses that are missing `content-type`. grpc-java currently may report a missing header as `invalid content-type: null`. Keep the existing HTTP-to-gRPC status mapping unchanged and replace that detail with a more accurate message. --- .../Http2ClientStreamTransportState.java | 7 +++++-- .../Http2ClientStreamTransportStateTest.java | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/io/grpc/internal/Http2ClientStreamTransportState.java b/core/src/main/java/io/grpc/internal/Http2ClientStreamTransportState.java index 5560a1abb6d..7124f2fc88a 100644 --- a/core/src/main/java/io/grpc/internal/Http2ClientStreamTransportState.java +++ b/core/src/main/java/io/grpc/internal/Http2ClientStreamTransportState.java @@ -223,8 +223,11 @@ private Status validateInitialMetadata(Metadata headers) { } String contentType = headers.get(GrpcUtil.CONTENT_TYPE_KEY); if (!GrpcUtil.isGrpcContentType(contentType)) { - return GrpcUtil.httpStatusToGrpcStatus(httpStatus) - .augmentDescription("invalid content-type: " + contentType); + Status status = GrpcUtil.httpStatusToGrpcStatus(httpStatus); + if (contentType == null) { + return status.augmentDescription("missing content-type in response headers"); + } + return status.augmentDescription("invalid content-type: " + contentType); } return null; } diff --git a/core/src/test/java/io/grpc/internal/Http2ClientStreamTransportStateTest.java b/core/src/test/java/io/grpc/internal/Http2ClientStreamTransportStateTest.java index 9d32bf1af7d..66df062a3e0 100644 --- a/core/src/test/java/io/grpc/internal/Http2ClientStreamTransportStateTest.java +++ b/core/src/test/java/io/grpc/internal/Http2ClientStreamTransportStateTest.java @@ -301,6 +301,24 @@ public void transportTrailersReceived_missingStatusUsesHttpStatus() { assertTrue(statusCaptor.getValue().getDescription().contains("401")); } + @Test + public void transportTrailersReceived_missingContentTypeUsesHttpStatus() { + BaseTransportState state = new BaseTransportState(transportTracer); + state.setListener(mockListener); + Metadata trailers = new Metadata(); + trailers.put(testStatusMashaller, "431"); + + state.transportTrailersReceived(trailers); + + verify(mockListener, never()).headersRead(any(Metadata.class)); + verify(mockListener).closed(statusCaptor.capture(), same(PROCESSED), same(trailers)); + assertEquals(Code.INTERNAL, statusCaptor.getValue().getCode()); + assertTrue(statusCaptor.getValue().getDescription().contains("HTTP status code 431")); + assertTrue( + statusCaptor.getValue().getDescription().contains( + "missing content-type in response headers")); + } + @Test public void transportTrailersReceived_missingHttpStatus() { BaseTransportState state = new BaseTransportState(transportTracer);