11use crate :: { Metadata , Prettify , Protobuf , Reencode } ;
22use anyhow:: { bail, Context , Result } ;
3+ use flate2:: read:: { DeflateDecoder , GzDecoder } ;
34use mitmproxy_highlight:: Language ;
45use serde:: Deserialize ;
56use serde_yaml:: Value ;
7+ use std:: io:: Read ;
68
79pub struct GRPC ;
810
@@ -29,20 +31,34 @@ impl Prettify for GRPC {
2931 _ => bail ! ( "invalid gRPC: first byte is not a boolean" ) ,
3032 } ;
3133 let Some ( proto) = data. get ( 5 ..5 + len) else {
32- bail ! ( "Invald gRPC: not enough data" )
34+ bail ! ( "Invalid gRPC: not enough data" )
3335 } ;
34- if compressed {
35- todo ! ( ) ;
36- }
37- protos. push ( proto) ;
36+
37+ let mut decompressed = Vec :: new ( ) ;
38+ let proto = if compressed {
39+ let encoding = metadata. get_header ( "grpc-encoding" ) . unwrap_or_default ( ) ;
40+ match encoding. as_str ( ) {
41+ "deflate" => {
42+ let mut decoder = DeflateDecoder :: new ( proto) ;
43+ decoder. read_to_end ( & mut decompressed) ?;
44+ & decompressed
45+ }
46+ "gzip" => {
47+ let mut decoder = GzDecoder :: new ( proto) ;
48+ decoder. read_to_end ( & mut decompressed) ?;
49+ & decompressed
50+ }
51+ "identity" => proto,
52+ _ => bail ! ( "unsupported compression: {}" , encoding) ,
53+ }
54+ } else {
55+ proto
56+ } ;
57+ protos. push ( Protobuf . prettify ( proto, metadata) ?) ;
3858 data = & data[ 5 + len..] ;
3959 }
4060
41- let prettified = protos
42- . into_iter ( )
43- . map ( |proto| Protobuf . prettify ( proto, metadata) )
44- . collect :: < Result < Vec < String > > > ( ) ?;
45- Ok ( prettified. join ( "\n ---\n \n " ) )
61+ Ok ( protos. join ( "\n ---\n \n " ) )
4662 }
4763
4864 fn render_priority ( & self , _data : & [ u8 ] , metadata : & dyn Metadata ) -> f64 {
@@ -61,7 +77,7 @@ impl Reencode for GRPC {
6177 for document in serde_yaml:: Deserializer :: from_str ( data) {
6278 let value = Value :: deserialize ( document) . context ( "Invalid YAML" ) ?;
6379 let proto = super :: protobuf:: reencode:: reencode_yaml ( value, metadata) ?;
64- ret. push ( 0 ) ; // compressed
80+ ret. push ( 0 ) ; // uncompressed
6581 ret. extend ( u32:: to_be_bytes ( proto. len ( ) as u32 ) ) ;
6682 ret. extend ( proto) ;
6783 }
@@ -76,13 +92,24 @@ mod tests {
7692
7793 const TEST_YAML : & str = "1: 150\n \n ---\n \n 1: 150\n " ;
7894 const TEST_GRPC : & [ u8 ] = & [
79- 0 , 0 , 0 , 0 , 3 , 8 , 150 , 1 , // first message
80- 0 , 0 , 0 , 0 , 3 , 8 , 150 , 1 , // second message
95+ 0 , 0 , 0 , 0 , 3 , 8 , 150 , 1 , // first message
96+ 0 , 0 , 0 , 0 , 3 , 8 , 150 , 1 , // second message
97+ ] ;
98+
99+ const TEST_GZIP : & [ u8 ] = & [
100+ 1 , 0 , 0 , 0 , 23 , // compressed flag and length
101+ 31 , 139 , 8 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 227 , 152 , 198 , 8 , 0 , 160 , 149 , 78 , 161 , 3 , 0 , 0 ,
102+ 0 , // gzip data
103+ ] ;
104+
105+ const TEST_DEFLATE : & [ u8 ] = & [
106+ 1 , 0 , 0 , 0 , 5 , // compressed flag and length
107+ 227 , 152 , 198 , 8 , 0 , // deflate data
81108 ] ;
82109
83110 #[ test]
84111 fn test_empty ( ) {
85- let res = GRPC . prettify ( & vec ! [ ] , & TestMetadata :: default ( ) ) . unwrap ( ) ;
112+ let res = GRPC . prettify ( & [ ] , & TestMetadata :: default ( ) ) . unwrap ( ) ;
86113 assert_eq ! ( res, "" ) ;
87114 }
88115
@@ -92,6 +119,20 @@ mod tests {
92119 assert_eq ! ( res, TEST_YAML ) ;
93120 }
94121
122+ #[ test]
123+ fn test_prettify_gzip ( ) {
124+ let metadata = TestMetadata :: default ( ) . with_header ( "grpc-encoding" , "gzip" ) ;
125+ let res = GRPC . prettify ( TEST_GZIP , & metadata) . unwrap ( ) ;
126+ assert_eq ! ( res, "1: 150\n " ) ;
127+ }
128+
129+ #[ test]
130+ fn test_prettify_deflate ( ) {
131+ let metadata = TestMetadata :: default ( ) . with_header ( "grpc-encoding" , "deflate" ) ;
132+ let res = GRPC . prettify ( TEST_DEFLATE , & metadata) . unwrap ( ) ;
133+ assert_eq ! ( res, "1: 150\n " ) ;
134+ }
135+
95136 #[ test]
96137 fn test_reencode_two_messages ( ) {
97138 let res = GRPC . reencode ( TEST_YAML , & TestMetadata :: default ( ) ) . unwrap ( ) ;
@@ -100,7 +141,19 @@ mod tests {
100141
101142 #[ test]
102143 fn test_render_priority ( ) {
103- assert_eq ! ( GRPC . render_priority( b"" , & TestMetadata :: default ( ) . with_content_type( "application/grpc" ) ) , 1.0 ) ;
104- assert_eq ! ( GRPC . render_priority( b"" , & TestMetadata :: default ( ) . with_content_type( "text/plain" ) ) , 0.0 ) ;
144+ assert_eq ! (
145+ GRPC . render_priority(
146+ b"" ,
147+ & TestMetadata :: default ( ) . with_content_type( "application/grpc" )
148+ ) ,
149+ 1.0
150+ ) ;
151+ assert_eq ! (
152+ GRPC . render_priority(
153+ b"" ,
154+ & TestMetadata :: default ( ) . with_content_type( "text/plain" )
155+ ) ,
156+ 0.0
157+ ) ;
105158 }
106159}
0 commit comments