| 
1 | 1 | import parseRawProto from 'rawprotoparse';  | 
 | 2 | +import { gunzipSync, inflateSync } from 'zlib';  | 
 | 3 | + | 
 | 4 | +const GZIP_MAGIC_BYTES = '1f8b';  | 
 | 5 | +const DEFLATE_MAGIC_BYTES = new Set<string>(['7801', '785e', '789c', '78da', '7820', '787d', '78bb', '78f9']);  | 
2 | 6 | 
 
  | 
3 | 7 | export function isProbablyProtobuf(input: Uint8Array) {  | 
4 | 8 |     // Protobuf data starts with a varint, consisting of a field  | 
@@ -38,12 +42,24 @@ export const extractProtobufFromGrpc = (input: Buffer) => {  | 
38 | 42 |     const protobufMessasges: Buffer[] = [];  | 
39 | 43 | 
 
  | 
40 | 44 |     while (input.length > 0) {  | 
41 |  | -        if (input.readInt8() != 0) {  | 
42 |  | -            throw new Error("Compressed gRPC messages not yet supported")  | 
 | 45 | +        const compressionFlag = input.readInt8();  | 
 | 46 | +        const length = input.readInt32BE(1);  | 
 | 47 | +        let message = input.slice(5, 5 + length);  | 
 | 48 | + | 
 | 49 | +        if (compressionFlag != 0) {  | 
 | 50 | +            // TODO: In theory we should check consistency of actual content encoding  | 
 | 51 | +            // with 'grpc-encoding' header, but we do not have access to it in this context  | 
 | 52 | +            const magicBytes = message.toString('hex', 0, 2);  | 
 | 53 | +            if (magicBytes == GZIP_MAGIC_BYTES) {  | 
 | 54 | +                message = gunzipSync(message);  | 
 | 55 | +            } else if (DEFLATE_MAGIC_BYTES.has(magicBytes)) {  | 
 | 56 | +                message = inflateSync(message);  | 
 | 57 | +            } else {  | 
 | 58 | +                throw new Error(`Unknown gRPC compression scheme, magic bytes = '${magicBytes}'`);  | 
 | 59 | +            }  | 
43 | 60 |         }  | 
44 | 61 | 
 
  | 
45 |  | -        const length = input.readInt32BE(1);  | 
46 |  | -        protobufMessasges.push(input.slice(5, 5 + length));  | 
 | 62 | +        protobufMessasges.push(message);  | 
47 | 63 |         input = input.subarray(5 + length);  | 
48 | 64 |     }  | 
49 | 65 | 
 
  | 
 | 
0 commit comments