Fix outbound message size checking (#10739)

This fixes two bugs in outbound message size checking:

* When thet checke failed, the thrown StatusRuntimeException with a status code
  of RESOURCE_EXHAUSTED was been caught and rewrapped in another
  StatusRuntimeException but this time with status code UNKNOWN.
* This applies the max outbound message size check to messages prior to, and
  after compression, since compression of a message that is smaller than the
  maximum send size can result in a larger message that exceeds the maximum
  send size.
This commit is contained in:
James Roper 2023-12-19 06:02:51 +11:00 committed by GitHub
parent 0a704a52ee
commit 67b67f8382
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 7 deletions

View File

@ -27,6 +27,7 @@ import io.grpc.Compressor;
import io.grpc.Drainable; import io.grpc.Drainable;
import io.grpc.KnownLength; import io.grpc.KnownLength;
import io.grpc.Status; import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -147,6 +148,8 @@ public class MessageFramer implements Framer {
.withDescription("Failed to frame message") .withDescription("Failed to frame message")
.withCause(e) .withCause(e)
.asRuntimeException(); .asRuntimeException();
} catch (StatusRuntimeException e) {
throw e;
} catch (RuntimeException e) { } catch (RuntimeException e) {
throw Status.INTERNAL throw Status.INTERNAL
.withDescription("Failed to frame message") .withDescription("Failed to frame message")
@ -170,13 +173,6 @@ public class MessageFramer implements Framer {
} }
BufferChainOutputStream bufferChain = new BufferChainOutputStream(); BufferChainOutputStream bufferChain = new BufferChainOutputStream();
int written = writeToOutputStream(message, bufferChain); int written = writeToOutputStream(message, bufferChain);
if (maxOutboundMessageSize >= 0 && written > maxOutboundMessageSize) {
throw Status.RESOURCE_EXHAUSTED
.withDescription(
String.format(
Locale.US, "message too large %d > %d", written , maxOutboundMessageSize))
.asRuntimeException();
}
writeBufferChain(bufferChain, false); writeBufferChain(bufferChain, false);
return written; return written;
} }
@ -238,6 +234,13 @@ public class MessageFramer implements Framer {
*/ */
private void writeBufferChain(BufferChainOutputStream bufferChain, boolean compressed) { private void writeBufferChain(BufferChainOutputStream bufferChain, boolean compressed) {
int messageLength = bufferChain.readableBytes(); int messageLength = bufferChain.readableBytes();
if (maxOutboundMessageSize >= 0 && messageLength > maxOutboundMessageSize) {
throw Status.RESOURCE_EXHAUSTED
.withDescription(
String.format(
Locale.US, "message too large %d > %d", messageLength , maxOutboundMessageSize))
.asRuntimeException();
}
headerScratch.clear(); headerScratch.clear();
headerScratch.put(compressed ? COMPRESSED : UNCOMPRESSED).putInt(messageLength); headerScratch.put(compressed ? COMPRESSED : UNCOMPRESSED).putInt(messageLength);
WritableBuffer writeableHeader = bufferAllocator.allocate(HEADER_LENGTH); WritableBuffer writeableHeader = bufferAllocator.allocate(HEADER_LENGTH);