10583cff8SDavid Pedersen use super::*; 2a585a722SMarcus Griep use tonic::codec::CompressionEncoding; 30583cff8SDavid Pedersen 4*e8cb48fcSQuentin Perez util::parametrized_tests! { 5*e8cb48fcSQuentin Perez client_enabled_server_enabled, 6*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 7*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 8*e8cb48fcSQuentin Perez } 9*e8cb48fcSQuentin Perez 10*e8cb48fcSQuentin Perez #[allow(dead_code)] 11*e8cb48fcSQuentin Perez async fn client_enabled_server_enabled(encoding: CompressionEncoding) { 120583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 130583cff8SDavid Pedersen 140583cff8SDavid Pedersen #[derive(Clone, Copy)] 15*e8cb48fcSQuentin Perez struct AssertCorrectAcceptEncoding<S> { 16*e8cb48fcSQuentin Perez service: S, 17*e8cb48fcSQuentin Perez encoding: CompressionEncoding, 18*e8cb48fcSQuentin Perez } 190583cff8SDavid Pedersen 200583cff8SDavid Pedersen impl<S, B> Service<http::Request<B>> for AssertCorrectAcceptEncoding<S> 210583cff8SDavid Pedersen where 220583cff8SDavid Pedersen S: Service<http::Request<B>>, 230583cff8SDavid Pedersen { 240583cff8SDavid Pedersen type Response = S::Response; 250583cff8SDavid Pedersen type Error = S::Error; 260583cff8SDavid Pedersen type Future = S::Future; 270583cff8SDavid Pedersen 280583cff8SDavid Pedersen fn poll_ready( 290583cff8SDavid Pedersen &mut self, 300583cff8SDavid Pedersen cx: &mut std::task::Context<'_>, 310583cff8SDavid Pedersen ) -> std::task::Poll<Result<(), Self::Error>> { 32*e8cb48fcSQuentin Perez self.service.poll_ready(cx) 330583cff8SDavid Pedersen } 340583cff8SDavid Pedersen 350583cff8SDavid Pedersen fn call(&mut self, req: http::Request<B>) -> Self::Future { 36*e8cb48fcSQuentin Perez let expected = match self.encoding { 37*e8cb48fcSQuentin Perez CompressionEncoding::Gzip => "gzip", 38*e8cb48fcSQuentin Perez CompressionEncoding::Zstd => "zstd", 39*e8cb48fcSQuentin Perez _ => panic!("unexpected encoding {:?}", self.encoding), 40*e8cb48fcSQuentin Perez }; 410583cff8SDavid Pedersen assert_eq!( 42*e8cb48fcSQuentin Perez req.headers() 43*e8cb48fcSQuentin Perez .get("grpc-accept-encoding") 44*e8cb48fcSQuentin Perez .unwrap() 45*e8cb48fcSQuentin Perez .to_str() 46*e8cb48fcSQuentin Perez .unwrap(), 47*e8cb48fcSQuentin Perez format!("{},identity", expected) 480583cff8SDavid Pedersen ); 49*e8cb48fcSQuentin Perez self.service.call(req) 500583cff8SDavid Pedersen } 510583cff8SDavid Pedersen } 520583cff8SDavid Pedersen 53*e8cb48fcSQuentin Perez let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding); 540583cff8SDavid Pedersen 550583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 560583cff8SDavid Pedersen 570583cff8SDavid Pedersen tokio::spawn({ 580583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 590583cff8SDavid Pedersen async move { 600583cff8SDavid Pedersen Server::builder() 610583cff8SDavid Pedersen .layer( 620583cff8SDavid Pedersen ServiceBuilder::new() 63*e8cb48fcSQuentin Perez .layer(layer_fn(|service| AssertCorrectAcceptEncoding { 64*e8cb48fcSQuentin Perez service, 65*e8cb48fcSQuentin Perez encoding, 66*e8cb48fcSQuentin Perez })) 670583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 680583cff8SDavid Pedersen util::CountBytesBody { 690583cff8SDavid Pedersen inner: body, 700583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 710583cff8SDavid Pedersen } 720583cff8SDavid Pedersen })) 730583cff8SDavid Pedersen .into_inner(), 740583cff8SDavid Pedersen ) 750583cff8SDavid Pedersen .add_service(svc) 76f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 770583cff8SDavid Pedersen .await 780583cff8SDavid Pedersen .unwrap(); 790583cff8SDavid Pedersen } 800583cff8SDavid Pedersen }); 810583cff8SDavid Pedersen 82*e8cb48fcSQuentin Perez let mut client = 83*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 84*e8cb48fcSQuentin Perez 85*e8cb48fcSQuentin Perez let expected = match encoding { 86*e8cb48fcSQuentin Perez CompressionEncoding::Gzip => "gzip", 87*e8cb48fcSQuentin Perez CompressionEncoding::Zstd => "zstd", 88*e8cb48fcSQuentin Perez _ => panic!("unexpected encoding {:?}", encoding), 89*e8cb48fcSQuentin Perez }; 900583cff8SDavid Pedersen 910583cff8SDavid Pedersen for _ in 0..3 { 920583cff8SDavid Pedersen let res = client.compress_output_unary(()).await.unwrap(); 93*e8cb48fcSQuentin Perez assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected); 940583cff8SDavid Pedersen let bytes_sent = response_bytes_counter.load(SeqCst); 950583cff8SDavid Pedersen assert!(bytes_sent < UNCOMPRESSED_MIN_BODY_SIZE); 960583cff8SDavid Pedersen } 970583cff8SDavid Pedersen } 980583cff8SDavid Pedersen 99*e8cb48fcSQuentin Perez util::parametrized_tests! { 100*e8cb48fcSQuentin Perez client_enabled_server_disabled, 101*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 102*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 103*e8cb48fcSQuentin Perez } 104*e8cb48fcSQuentin Perez 105*e8cb48fcSQuentin Perez #[allow(dead_code)] 106*e8cb48fcSQuentin Perez async fn client_enabled_server_disabled(encoding: CompressionEncoding) { 107*e8cb48fcSQuentin Perez let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 108*e8cb48fcSQuentin Perez 109*e8cb48fcSQuentin Perez let svc = test_server::TestServer::new(Svc::default()); 110*e8cb48fcSQuentin Perez 111*e8cb48fcSQuentin Perez let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 112*e8cb48fcSQuentin Perez 113*e8cb48fcSQuentin Perez tokio::spawn({ 114*e8cb48fcSQuentin Perez let response_bytes_counter = response_bytes_counter.clone(); 115*e8cb48fcSQuentin Perez async move { 116*e8cb48fcSQuentin Perez Server::builder() 117*e8cb48fcSQuentin Perez // no compression enable on the server so responses should not be compressed 118*e8cb48fcSQuentin Perez .layer( 119*e8cb48fcSQuentin Perez ServiceBuilder::new() 120*e8cb48fcSQuentin Perez .layer(MapResponseBodyLayer::new(move |body| { 121*e8cb48fcSQuentin Perez util::CountBytesBody { 122*e8cb48fcSQuentin Perez inner: body, 123*e8cb48fcSQuentin Perez counter: response_bytes_counter.clone(), 124*e8cb48fcSQuentin Perez } 125*e8cb48fcSQuentin Perez })) 126*e8cb48fcSQuentin Perez .into_inner(), 127*e8cb48fcSQuentin Perez ) 128*e8cb48fcSQuentin Perez .add_service(svc) 129*e8cb48fcSQuentin Perez .serve_with_incoming(tokio_stream::iter(vec![Ok::<_, std::io::Error>(server)])) 130*e8cb48fcSQuentin Perez .await 131*e8cb48fcSQuentin Perez .unwrap(); 132*e8cb48fcSQuentin Perez } 133*e8cb48fcSQuentin Perez }); 134*e8cb48fcSQuentin Perez 135*e8cb48fcSQuentin Perez let mut client = 136*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 137*e8cb48fcSQuentin Perez 138*e8cb48fcSQuentin Perez let res = client.compress_output_unary(()).await.unwrap(); 139*e8cb48fcSQuentin Perez 140*e8cb48fcSQuentin Perez assert!(res.metadata().get("grpc-encoding").is_none()); 141*e8cb48fcSQuentin Perez 142*e8cb48fcSQuentin Perez let bytes_sent = response_bytes_counter.load(SeqCst); 143*e8cb48fcSQuentin Perez assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE); 144*e8cb48fcSQuentin Perez } 145*e8cb48fcSQuentin Perez 1460583cff8SDavid Pedersen #[tokio::test(flavor = "multi_thread")] 147*e8cb48fcSQuentin Perez async fn client_enabled_server_disabled_multi_encoding() { 1480583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 1490583cff8SDavid Pedersen 1500583cff8SDavid Pedersen let svc = test_server::TestServer::new(Svc::default()); 1510583cff8SDavid Pedersen 1520583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 1530583cff8SDavid Pedersen 1540583cff8SDavid Pedersen tokio::spawn({ 1550583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 1560583cff8SDavid Pedersen async move { 1570583cff8SDavid Pedersen Server::builder() 1580583cff8SDavid Pedersen // no compression enable on the server so responses should not be compressed 1590583cff8SDavid Pedersen .layer( 1600583cff8SDavid Pedersen ServiceBuilder::new() 1610583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 1620583cff8SDavid Pedersen util::CountBytesBody { 1630583cff8SDavid Pedersen inner: body, 1640583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 1650583cff8SDavid Pedersen } 1660583cff8SDavid Pedersen })) 1670583cff8SDavid Pedersen .into_inner(), 1680583cff8SDavid Pedersen ) 1690583cff8SDavid Pedersen .add_service(svc) 170f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 1710583cff8SDavid Pedersen .await 1720583cff8SDavid Pedersen .unwrap(); 1730583cff8SDavid Pedersen } 1740583cff8SDavid Pedersen }); 1750583cff8SDavid Pedersen 176a585a722SMarcus Griep let mut client = test_client::TestClient::new(mock_io_channel(client).await) 177*e8cb48fcSQuentin Perez .accept_compressed(CompressionEncoding::Gzip) 178*e8cb48fcSQuentin Perez .accept_compressed(CompressionEncoding::Zstd); 1790583cff8SDavid Pedersen 1800583cff8SDavid Pedersen let res = client.compress_output_unary(()).await.unwrap(); 1810583cff8SDavid Pedersen 1820583cff8SDavid Pedersen assert!(res.metadata().get("grpc-encoding").is_none()); 1830583cff8SDavid Pedersen 1840583cff8SDavid Pedersen let bytes_sent = response_bytes_counter.load(SeqCst); 1850583cff8SDavid Pedersen assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE); 1860583cff8SDavid Pedersen } 1870583cff8SDavid Pedersen 188*e8cb48fcSQuentin Perez util::parametrized_tests! { 189*e8cb48fcSQuentin Perez client_disabled, 190*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 191*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 192*e8cb48fcSQuentin Perez } 193*e8cb48fcSQuentin Perez 194*e8cb48fcSQuentin Perez #[allow(dead_code)] 195*e8cb48fcSQuentin Perez async fn client_disabled(encoding: CompressionEncoding) { 1960583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 1970583cff8SDavid Pedersen 1980583cff8SDavid Pedersen #[derive(Clone, Copy)] 1990583cff8SDavid Pedersen struct AssertCorrectAcceptEncoding<S>(S); 2000583cff8SDavid Pedersen 2010583cff8SDavid Pedersen impl<S, B> Service<http::Request<B>> for AssertCorrectAcceptEncoding<S> 2020583cff8SDavid Pedersen where 2030583cff8SDavid Pedersen S: Service<http::Request<B>>, 2040583cff8SDavid Pedersen { 2050583cff8SDavid Pedersen type Response = S::Response; 2060583cff8SDavid Pedersen type Error = S::Error; 2070583cff8SDavid Pedersen type Future = S::Future; 2080583cff8SDavid Pedersen 2090583cff8SDavid Pedersen fn poll_ready( 2100583cff8SDavid Pedersen &mut self, 2110583cff8SDavid Pedersen cx: &mut std::task::Context<'_>, 2120583cff8SDavid Pedersen ) -> std::task::Poll<Result<(), Self::Error>> { 2130583cff8SDavid Pedersen self.0.poll_ready(cx) 2140583cff8SDavid Pedersen } 2150583cff8SDavid Pedersen 2160583cff8SDavid Pedersen fn call(&mut self, req: http::Request<B>) -> Self::Future { 2170583cff8SDavid Pedersen assert!(req.headers().get("grpc-accept-encoding").is_none()); 2180583cff8SDavid Pedersen self.0.call(req) 2190583cff8SDavid Pedersen } 2200583cff8SDavid Pedersen } 2210583cff8SDavid Pedersen 222*e8cb48fcSQuentin Perez let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding); 2230583cff8SDavid Pedersen 2240583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 2250583cff8SDavid Pedersen 2260583cff8SDavid Pedersen tokio::spawn({ 2270583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 2280583cff8SDavid Pedersen async move { 2290583cff8SDavid Pedersen Server::builder() 2300583cff8SDavid Pedersen .layer( 2310583cff8SDavid Pedersen ServiceBuilder::new() 2320583cff8SDavid Pedersen .layer(layer_fn(AssertCorrectAcceptEncoding)) 2330583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 2340583cff8SDavid Pedersen util::CountBytesBody { 2350583cff8SDavid Pedersen inner: body, 2360583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 2370583cff8SDavid Pedersen } 2380583cff8SDavid Pedersen })) 2390583cff8SDavid Pedersen .into_inner(), 2400583cff8SDavid Pedersen ) 2410583cff8SDavid Pedersen .add_service(svc) 242f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 2430583cff8SDavid Pedersen .await 2440583cff8SDavid Pedersen .unwrap(); 2450583cff8SDavid Pedersen } 2460583cff8SDavid Pedersen }); 2470583cff8SDavid Pedersen 2480583cff8SDavid Pedersen let mut client = test_client::TestClient::new(mock_io_channel(client).await); 2490583cff8SDavid Pedersen 2500583cff8SDavid Pedersen let res = client.compress_output_unary(()).await.unwrap(); 2510583cff8SDavid Pedersen 2520583cff8SDavid Pedersen assert!(res.metadata().get("grpc-encoding").is_none()); 2530583cff8SDavid Pedersen 2540583cff8SDavid Pedersen let bytes_sent = response_bytes_counter.load(SeqCst); 2550583cff8SDavid Pedersen assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE); 2560583cff8SDavid Pedersen } 2570583cff8SDavid Pedersen 258*e8cb48fcSQuentin Perez util::parametrized_tests! { 259*e8cb48fcSQuentin Perez server_replying_with_unsupported_encoding, 260*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 261*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 262*e8cb48fcSQuentin Perez } 263*e8cb48fcSQuentin Perez 264*e8cb48fcSQuentin Perez #[allow(dead_code)] 265*e8cb48fcSQuentin Perez async fn server_replying_with_unsupported_encoding(encoding: CompressionEncoding) { 2660583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 2670583cff8SDavid Pedersen 268*e8cb48fcSQuentin Perez let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding); 2690583cff8SDavid Pedersen 2700583cff8SDavid Pedersen fn add_weird_content_encoding<B>(mut response: http::Response<B>) -> http::Response<B> { 2710583cff8SDavid Pedersen response 2720583cff8SDavid Pedersen .headers_mut() 2730583cff8SDavid Pedersen .insert("grpc-encoding", "br".parse().unwrap()); 2740583cff8SDavid Pedersen response 2750583cff8SDavid Pedersen } 2760583cff8SDavid Pedersen 2770583cff8SDavid Pedersen tokio::spawn(async move { 2780583cff8SDavid Pedersen Server::builder() 2790583cff8SDavid Pedersen .layer( 2800583cff8SDavid Pedersen ServiceBuilder::new() 2810583cff8SDavid Pedersen .map_response(add_weird_content_encoding) 2820583cff8SDavid Pedersen .into_inner(), 2830583cff8SDavid Pedersen ) 2840583cff8SDavid Pedersen .add_service(svc) 285f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 2860583cff8SDavid Pedersen .await 2870583cff8SDavid Pedersen .unwrap(); 2880583cff8SDavid Pedersen }); 2890583cff8SDavid Pedersen 290*e8cb48fcSQuentin Perez let mut client = 291*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 2920583cff8SDavid Pedersen let status: Status = client.compress_output_unary(()).await.unwrap_err(); 2930583cff8SDavid Pedersen 2940583cff8SDavid Pedersen assert_eq!(status.code(), tonic::Code::Unimplemented); 2950583cff8SDavid Pedersen assert_eq!( 2960583cff8SDavid Pedersen status.message(), 2970583cff8SDavid Pedersen "Content is compressed with `br` which isn't supported" 2980583cff8SDavid Pedersen ); 2990583cff8SDavid Pedersen } 3000583cff8SDavid Pedersen 301*e8cb48fcSQuentin Perez util::parametrized_tests! { 302*e8cb48fcSQuentin Perez disabling_compression_on_single_response, 303*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 304*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 305*e8cb48fcSQuentin Perez } 306*e8cb48fcSQuentin Perez 307*e8cb48fcSQuentin Perez #[allow(dead_code)] 308*e8cb48fcSQuentin Perez async fn disabling_compression_on_single_response(encoding: CompressionEncoding) { 3090583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 3100583cff8SDavid Pedersen 3110583cff8SDavid Pedersen let svc = test_server::TestServer::new(Svc { 3120583cff8SDavid Pedersen disable_compressing_on_response: true, 3130583cff8SDavid Pedersen }) 314*e8cb48fcSQuentin Perez .send_compressed(encoding); 3150583cff8SDavid Pedersen 3160583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 3170583cff8SDavid Pedersen 3180583cff8SDavid Pedersen tokio::spawn({ 3190583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 3200583cff8SDavid Pedersen async move { 3210583cff8SDavid Pedersen Server::builder() 3220583cff8SDavid Pedersen .layer( 3230583cff8SDavid Pedersen ServiceBuilder::new() 3240583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 3250583cff8SDavid Pedersen util::CountBytesBody { 3260583cff8SDavid Pedersen inner: body, 3270583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 3280583cff8SDavid Pedersen } 3290583cff8SDavid Pedersen })) 3300583cff8SDavid Pedersen .into_inner(), 3310583cff8SDavid Pedersen ) 3320583cff8SDavid Pedersen .add_service(svc) 333f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 3340583cff8SDavid Pedersen .await 3350583cff8SDavid Pedersen .unwrap(); 3360583cff8SDavid Pedersen } 3370583cff8SDavid Pedersen }); 3380583cff8SDavid Pedersen 339*e8cb48fcSQuentin Perez let mut client = 340*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 3410583cff8SDavid Pedersen 3420583cff8SDavid Pedersen let res = client.compress_output_unary(()).await.unwrap(); 343*e8cb48fcSQuentin Perez 344*e8cb48fcSQuentin Perez let expected = match encoding { 345*e8cb48fcSQuentin Perez CompressionEncoding::Gzip => "gzip", 346*e8cb48fcSQuentin Perez CompressionEncoding::Zstd => "zstd", 347*e8cb48fcSQuentin Perez _ => panic!("unexpected encoding {:?}", encoding), 348*e8cb48fcSQuentin Perez }; 349*e8cb48fcSQuentin Perez assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected); 350*e8cb48fcSQuentin Perez 3510583cff8SDavid Pedersen let bytes_sent = response_bytes_counter.load(SeqCst); 3520583cff8SDavid Pedersen assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE); 3530583cff8SDavid Pedersen } 3540583cff8SDavid Pedersen 355*e8cb48fcSQuentin Perez util::parametrized_tests! { 356*e8cb48fcSQuentin Perez disabling_compression_on_response_but_keeping_compression_on_stream, 357*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 358*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 359*e8cb48fcSQuentin Perez } 360*e8cb48fcSQuentin Perez 361*e8cb48fcSQuentin Perez #[allow(dead_code)] 362*e8cb48fcSQuentin Perez async fn disabling_compression_on_response_but_keeping_compression_on_stream( 363*e8cb48fcSQuentin Perez encoding: CompressionEncoding, 364*e8cb48fcSQuentin Perez ) { 3650583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 3660583cff8SDavid Pedersen 3670583cff8SDavid Pedersen let svc = test_server::TestServer::new(Svc { 3680583cff8SDavid Pedersen disable_compressing_on_response: true, 3690583cff8SDavid Pedersen }) 370*e8cb48fcSQuentin Perez .send_compressed(encoding); 3710583cff8SDavid Pedersen 3720583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 3730583cff8SDavid Pedersen 3740583cff8SDavid Pedersen tokio::spawn({ 3750583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 3760583cff8SDavid Pedersen async move { 3770583cff8SDavid Pedersen Server::builder() 3780583cff8SDavid Pedersen .layer( 3790583cff8SDavid Pedersen ServiceBuilder::new() 3800583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 3810583cff8SDavid Pedersen util::CountBytesBody { 3820583cff8SDavid Pedersen inner: body, 3830583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 3840583cff8SDavid Pedersen } 3850583cff8SDavid Pedersen })) 3860583cff8SDavid Pedersen .into_inner(), 3870583cff8SDavid Pedersen ) 3880583cff8SDavid Pedersen .add_service(svc) 389f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 3900583cff8SDavid Pedersen .await 3910583cff8SDavid Pedersen .unwrap(); 3920583cff8SDavid Pedersen } 3930583cff8SDavid Pedersen }); 3940583cff8SDavid Pedersen 395*e8cb48fcSQuentin Perez let mut client = 396*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 3970583cff8SDavid Pedersen 3980583cff8SDavid Pedersen let res = client.compress_output_server_stream(()).await.unwrap(); 3990583cff8SDavid Pedersen 400*e8cb48fcSQuentin Perez let expected = match encoding { 401*e8cb48fcSQuentin Perez CompressionEncoding::Gzip => "gzip", 402*e8cb48fcSQuentin Perez CompressionEncoding::Zstd => "zstd", 403*e8cb48fcSQuentin Perez _ => panic!("unexpected encoding {:?}", encoding), 404*e8cb48fcSQuentin Perez }; 405*e8cb48fcSQuentin Perez assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected); 4060583cff8SDavid Pedersen 4070583cff8SDavid Pedersen let mut stream: Streaming<SomeData> = res.into_inner(); 4080583cff8SDavid Pedersen 4090583cff8SDavid Pedersen stream 4100583cff8SDavid Pedersen .next() 4110583cff8SDavid Pedersen .await 4120583cff8SDavid Pedersen .expect("stream empty") 4130583cff8SDavid Pedersen .expect("item was error"); 4140583cff8SDavid Pedersen assert!(response_bytes_counter.load(SeqCst) < UNCOMPRESSED_MIN_BODY_SIZE); 4150583cff8SDavid Pedersen 4160583cff8SDavid Pedersen stream 4170583cff8SDavid Pedersen .next() 4180583cff8SDavid Pedersen .await 4190583cff8SDavid Pedersen .expect("stream empty") 4200583cff8SDavid Pedersen .expect("item was error"); 4210583cff8SDavid Pedersen assert!(response_bytes_counter.load(SeqCst) < UNCOMPRESSED_MIN_BODY_SIZE); 4220583cff8SDavid Pedersen } 4230583cff8SDavid Pedersen 424*e8cb48fcSQuentin Perez util::parametrized_tests! { 425*e8cb48fcSQuentin Perez disabling_compression_on_response_from_client_stream, 426*e8cb48fcSQuentin Perez zstd: CompressionEncoding::Zstd, 427*e8cb48fcSQuentin Perez gzip: CompressionEncoding::Gzip, 428*e8cb48fcSQuentin Perez } 429*e8cb48fcSQuentin Perez 430*e8cb48fcSQuentin Perez #[allow(dead_code)] 431*e8cb48fcSQuentin Perez async fn disabling_compression_on_response_from_client_stream(encoding: CompressionEncoding) { 4320583cff8SDavid Pedersen let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10); 4330583cff8SDavid Pedersen 4340583cff8SDavid Pedersen let svc = test_server::TestServer::new(Svc { 4350583cff8SDavid Pedersen disable_compressing_on_response: true, 4360583cff8SDavid Pedersen }) 437*e8cb48fcSQuentin Perez .send_compressed(encoding); 4380583cff8SDavid Pedersen 4390583cff8SDavid Pedersen let response_bytes_counter = Arc::new(AtomicUsize::new(0)); 4400583cff8SDavid Pedersen 4410583cff8SDavid Pedersen tokio::spawn({ 4420583cff8SDavid Pedersen let response_bytes_counter = response_bytes_counter.clone(); 4430583cff8SDavid Pedersen async move { 4440583cff8SDavid Pedersen Server::builder() 4450583cff8SDavid Pedersen .layer( 4460583cff8SDavid Pedersen ServiceBuilder::new() 4470583cff8SDavid Pedersen .layer(MapResponseBodyLayer::new(move |body| { 4480583cff8SDavid Pedersen util::CountBytesBody { 4490583cff8SDavid Pedersen inner: body, 4500583cff8SDavid Pedersen counter: response_bytes_counter.clone(), 4510583cff8SDavid Pedersen } 4520583cff8SDavid Pedersen })) 4530583cff8SDavid Pedersen .into_inner(), 4540583cff8SDavid Pedersen ) 4550583cff8SDavid Pedersen .add_service(svc) 456f089e7a0Stottoto .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server))) 4570583cff8SDavid Pedersen .await 4580583cff8SDavid Pedersen .unwrap(); 4590583cff8SDavid Pedersen } 4600583cff8SDavid Pedersen }); 4610583cff8SDavid Pedersen 462*e8cb48fcSQuentin Perez let mut client = 463*e8cb48fcSQuentin Perez test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding); 4640583cff8SDavid Pedersen 465f089e7a0Stottoto let req = Request::new(Box::pin(tokio_stream::empty())); 4660583cff8SDavid Pedersen 4670583cff8SDavid Pedersen let res = client.compress_output_client_stream(req).await.unwrap(); 468*e8cb48fcSQuentin Perez 469*e8cb48fcSQuentin Perez let expected = match encoding { 470*e8cb48fcSQuentin Perez CompressionEncoding::Gzip => "gzip", 471*e8cb48fcSQuentin Perez CompressionEncoding::Zstd => "zstd", 472*e8cb48fcSQuentin Perez _ => panic!("unexpected encoding {:?}", encoding), 473*e8cb48fcSQuentin Perez }; 474*e8cb48fcSQuentin Perez assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected); 4750583cff8SDavid Pedersen let bytes_sent = response_bytes_counter.load(SeqCst); 4760583cff8SDavid Pedersen assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE); 4770583cff8SDavid Pedersen } 478