Skip to content

gRPC decoding

ProxyPro detects gRPC by sniffing Content-Type: application/grpc[+proto|+json|-web] on the response. Matching flows are reclassified to kind=grpc and the detail view gets a fourth tab labeled gRPC.

Native gRPC envelope

Each message in a gRPC stream has a 5-byte envelope:

1 byte compressed flag (0 = identity, 1 = gzip)
4 bytes payload length, big-endian uint32
N bytes payload (protobuf-encoded)

A unary RPC has one envelope. Server-streaming, client-streaming, and bidirectional RPCs concatenate multiple envelopes back-to-back.

The renderer parses these into a list of GrpcMessage records and displays them per request / response.

Per-message gzip

If grpc-encoding: gzip is set on the response, the renderer decompresses each envelope’s payload via the browser’s DecompressionStream before walking. (Engine-side gzip decode ships in P04.5.)

Heuristic protobuf walker

We don’t have your .proto file. The walker reads the wire format and recovers:

What we knowWhat we guess
Field number (1, 2, 3, …)
Wire type (varint, fixed64, length-delimited, fixed32)
Raw bytes”is this UTF-8 text?” — strict decode
“is this a nested message?” — re-walk
“is this binary blob?” — hex preview

For a varint field, value 0 or 1 is guessed as bool; otherwise varint. A length-delimited field is tried as a nested message first (recurse), then as UTF-8 string (strict decode), then falls back to binary.

Limits of heuristic decoding

  • Field names are unrecoverable without the .proto file. You see #1, #2, #3 instead of user_id, created_at, status.
  • Enums show as varints. You’ll see 2 instead of ROLE_ADMIN.
  • Packed repeated fields decode as length-delimited blobs that the walker may misclassify.
  • Fixed64 / fixed32 don’t distinguish signed vs unsigned vs float; we show them as unsigned.

Accuracy

In practice the walker handles ~85% of real-world gRPC payloads usefully. The “message vs string vs bytes” heuristic is the main failure mode — the strict UTF-8 decode catches most binary blobs, but ambiguous content (short ASCII-only binary) can show as text.

gRPC-Web

Not yet supported. P04.5 adds base64 + binary envelope variants.

Named-field decoding (P04.5)

Two paths planned:

  1. Server reflection — if the upstream gRPC server exposes grpc.reflection.v1alpha.ServerReflection, engine fetches descriptors and caches them. Subsequent flows decode with real field names.
  2. .proto upload — drag a .proto file or FileDescriptorSet into the rules / settings UI. Engine compiles it and applies to matching services.

Until P04.5, the heuristic walker is what you get. It’s usually enough to figure out which field is the user ID.

HTTP/3 downgrade

gRPC servers often advertise HTTP/3 via Alt-Svc. ProxyPro strips that header from every response so clients can’t switch to QUIC behind our back. See Configure the proxy.

See also