From 0cb453e49936da4e6622f5c3caab88a581cc9f19 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Mon, 16 Dec 2024 13:53:09 +0100 Subject: [PATCH] feat(encoding): use an extension for encoding, which allow a specific handler to disable compression if needed --- actix-web/src/middleware/compress.rs | 39 +++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/actix-web/src/middleware/compress.rs b/actix-web/src/middleware/compress.rs index 943868d21..8265b0cf7 100644 --- a/actix-web/src/middleware/compress.rs +++ b/actix-web/src/middleware/compress.rs @@ -110,14 +110,22 @@ where #[allow(clippy::borrow_interior_mutable_const)] fn call(&self, req: ServiceRequest) -> Self::Future { + if req.extensions().get::().is_some() { + return Either::left(CompressResponse { + fut: self.service.call(req), + _phantom: PhantomData, + }); + } + // negotiate content-encoding let accept_encoding = req.get_header::(); let accept_encoding = match accept_encoding { // missing header; fallback to identity None => { + req.extensions_mut().insert::(Encoding::identity()); + return Either::left(CompressResponse { - encoding: Encoding::identity(), fut: self.service.call(req), _phantom: PhantomData, }) @@ -143,11 +151,14 @@ where .map_into_right_body())) } - Some(encoding) => Either::left(CompressResponse { - fut: self.service.call(req), - encoding, - _phantom: PhantomData, - }), + Some(encoding) => { + req.extensions_mut().insert::(encoding); + + Either::left(CompressResponse { + fut: self.service.call(req), + _phantom: PhantomData, + }) + }, } } } @@ -159,7 +170,6 @@ pin_project! { { #[pin] fut: S::Future, - encoding: Encoding, _phantom: PhantomData, } } @@ -176,8 +186,19 @@ where match ready!(this.fut.poll(cx)) { Ok(resp) => { - let enc = match this.encoding { - Encoding::Known(enc) => *enc, + let request_encoding = resp.request().extensions().get::().cloned(); + + let encoding = match request_encoding { + Some(enc) => enc.clone(), + None => { + return Poll::Ready(Ok(resp.map_body(move |head, body| { + EitherBody::left(Encoder::response(ContentEncoding::Identity, head, body)) + }))); + } + }; + + let enc = match encoding { + Encoding::Known(enc) => enc, Encoding::Unknown(enc) => { unimplemented!("encoding '{enc}' should not be here"); }