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 uint32N 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 know | What 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
.protofile. You see#1,#2,#3instead ofuser_id,created_at,status. - Enums show as varints. You’ll see
2instead ofROLE_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
The detail view supports both binary application/grpc-web and base64
application/grpc-web-text bodies. It splits data messages from the in-band
trailer frame and surfaces grpc-status / grpc-message; a truncated trailer
is reported as unknown instead of being mistaken for success.
Named-field decoding
ProxyPro uses server reflection when the upstream exposes it:
- Server reflection — when the upstream gRPC server exposes
grpc.reflection.v1alpha.ServerReflection, engine fetches descriptors and caches them. Subsequent flows decode with real field names. - Fallback — without reflection, the heuristic wire walker remains
available. Manual
.protoupload is not currently implemented.
Reflection descriptors are cached per host; the heuristic walker is still useful for servers that intentionally disable reflection.
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
- Capture list — the
grpckind badge. - Architecture overview — how the engine routes h2 streams to the gRPC detection path.