diff --git a/grpc-java/grpc-servlet-jakarta/src/main/java/io/grpc/servlet/jakarta/web/GrpcWebFilter.java b/grpc-java/grpc-servlet-jakarta/src/main/java/io/grpc/servlet/jakarta/web/GrpcWebFilter.java index 66fba1f93a9..98de22577f5 100644 --- a/grpc-java/grpc-servlet-jakarta/src/main/java/io/grpc/servlet/jakarta/web/GrpcWebFilter.java +++ b/grpc-java/grpc-servlet-jakarta/src/main/java/io/grpc/servlet/jakarta/web/GrpcWebFilter.java @@ -74,9 +74,17 @@ public void complete() { payload.putInt(trailerLength); for (Map.Entry entry : map.entrySet()) { payload.put(entry.getKey().getBytes(StandardCharsets.US_ASCII)); - payload.put(": ".getBytes(StandardCharsets.US_ASCII)); + payload.put((byte) ':'); + payload.put((byte) ' '); payload.put(entry.getValue().getBytes(StandardCharsets.US_ASCII)); - payload.put("\r\n".getBytes(StandardCharsets.US_ASCII)); + payload.put((byte) '\r'); + payload.put((byte) '\n'); + } + if (payload.hasRemaining()) { + // Normally we must not throw, but this is an exceptional case. Complete + // the stream, _then_ throw. + super.complete(); + throw new IllegalStateException("Incorrectly sized buffer, trailer payload will be sized wrong"); } wrappedResponse.getOutputStream().write(payload.array()); } @@ -105,8 +113,7 @@ private static boolean isGrpcWeb(ServletRequest request) { return request.getContentType() != null && request.getContentType().startsWith(CONTENT_TYPE_GRPC_WEB); } - // Technically we should throw away content-length too, but the impl won't care - public static class GrpcWebHttpResponse extends HttpServletResponseWrapper { + private static class GrpcWebHttpResponse extends HttpServletResponseWrapper { private Supplier> trailers; public GrpcWebHttpResponse(HttpServletResponse response) {