parseHeader static method

RpcMessageHeader parseHeader(
  1. Uint8List headerBytes
)

Reads compression and length out of a 5-byte gRPC prefix.

Throws RpcStatusException with INTERNAL if headerBytes is short or the flag is not 0 or 1.

INTERNAL and not RESOURCE_EXHAUSTED, and the two are raised on the same path so the distinction has to live on the TYPE: these are MALFORMED framing, which no amount of sending less will fix, where the parser's limits are a size the peer can correct. Read as a resource limit, a corrupt frame would come back retryable.

Implementation

static RpcMessageHeader parseHeader(Uint8List headerBytes) {
  // Both refusals are the PEER's malformed prefix (RpcPeerFaultException): INTERNAL
  // on the wire, as gRPC answers it, but not a fault of this side.
  if (headerBytes.length < RpcConstants.messagePrefixSize) {
    throw RpcPeerFaultException(
      RpcStatus.internal,
      'Invalid gRPC message header length',
    );
  }

  final compressionFlag = headerBytes[RpcConstants.compressionFlagIndex];
  if (compressionFlag != RpcConstants.noCompression &&
      compressionFlag != RpcConstants.compressed) {
    throw RpcPeerFaultException(
      RpcStatus.internal,
      'Invalid compression flag in gRPC message: $compressionFlag',
    );
  }

  final isCompressed = compressionFlag == RpcConstants.compressed;

  // Big-endian unsigned, which is what the prefix declares.
  final length = ByteData.sublistView(
    headerBytes,
  ).getUint32(RpcConstants.messageLengthIndex);

  return RpcMessageHeader(isCompressed, length);
}