Compare commits

...

4 Commits

Author SHA1 Message Date
Joel Wurtz 7a092b1485
Merge bb2c6cebfd into e1da110e92 2025-11-14 07:37:40 +09:00
Ruchir e1da110e92
chore: Add public export for `EitherExtractError` (#3826)
* chore: Export EitherExtractError for public use

* refactor: export EitherExtractError
2025-11-11 15:28:40 +00:00
Rob Ede bb2c6cebfd
Merge branch 'master' into feat/encoding-as-extension 2025-05-10 00:52:46 +01:00
Joel Wurtz 0cb453e499
feat(encoding): use an extension for encoding, which allow a specific handler to disable compression if needed 2024-12-16 14:00:29 +01:00
4 changed files with 33 additions and 10 deletions

View File

@ -5,6 +5,7 @@
- `actix_web::response::builder::HttpResponseBuilder::streaming()` now sets `Content-Type` to `application/octet-stream` if `Content-Type` does not exist.
- `actix_web::response::builder::HttpResponseBuilder::streaming()` now calls `actix_web::response::builder::HttpResponseBuilder::no_chunking()` if `Content-Length` is set by user.
- Add `ws` crate feature (on-by-default) which forwards to `actix-http` and guards some of its `ResponseError` impls.
- Add public export for `EitherExtractError` in `error` module.
## 4.11.0

View File

@ -21,6 +21,7 @@ mod response_error;
pub(crate) use self::macros::{downcast_dyn, downcast_get_type_id};
pub use self::{error::Error, internal::*, response_error::ResponseError};
pub use crate::types::EitherExtractError;
/// A convenience [`Result`](std::result::Result) for Actix Web operations.
///

View File

@ -110,14 +110,22 @@ where
#[allow(clippy::borrow_interior_mutable_const)]
fn call(&self, req: ServiceRequest) -> Self::Future {
if req.extensions().get::<Encoding>().is_some() {
return Either::left(CompressResponse {
fut: self.service.call(req),
_phantom: PhantomData,
});
}
// negotiate content-encoding
let accept_encoding = req.get_header::<AcceptEncoding>();
let accept_encoding = match accept_encoding {
// missing header; fallback to identity
None => {
req.extensions_mut().insert::<Encoding>(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>(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<B>,
}
}
@ -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::<Encoding>().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");
}

View File

@ -11,7 +11,7 @@ mod query;
mod readlines;
pub use self::{
either::Either,
either::{Either, EitherExtractError},
form::{Form, FormConfig, UrlEncoded},
header::Header,
html::Html,