1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

improve docs for Compress

This commit is contained in:
Rob Ede 2022-01-03 14:59:01 +00:00
parent 25fe1bbaa5
commit 68cd853aa2
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
4 changed files with 47 additions and 42 deletions

View File

@ -28,15 +28,15 @@ path = "src/lib.rs"
resolver = "2" resolver = "2"
members = [ members = [
".", ".",
"awc",
"actix-http",
"actix-files", "actix-files",
"actix-http-test",
"actix-http",
"actix-multipart", "actix-multipart",
"actix-router",
"actix-test",
"actix-web-actors", "actix-web-actors",
"actix-web-codegen", "actix-web-codegen",
"actix-http-test", "awc",
"actix-test",
"actix-router",
] ]
[features] [features]
@ -105,6 +105,7 @@ time = { version = "0.3", default-features = false, features = ["formatting"] }
url = "2.1" url = "2.1"
[dev-dependencies] [dev-dependencies]
actix-files = "0.6.0-beta.12"
actix-test = { version = "0.1.0-beta.10", features = ["openssl", "rustls"] } actix-test = { version = "0.1.0-beta.10", features = ["openssl", "rustls"] }
awc = { version = "3.0.0-beta.17", features = ["openssl"] } awc = { version = "3.0.0-beta.17", features = ["openssl"] }

View File

@ -73,7 +73,7 @@ impl<B: MessageBody> Encoder<B> {
if should_encode { if should_encode {
// wrap body only if encoder is feature-enabled // wrap body only if encoder is feature-enabled
if let Some(enc) = ContentEncoder::encoder(encoding) { if let Some(enc) = ContentEncoder::select(encoding) {
update_head(encoding, head); update_head(encoding, head);
return Encoder { return Encoder {
@ -168,6 +168,7 @@ where
cx: &mut Context<'_>, cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Self::Error>>> { ) -> Poll<Option<Result<Bytes, Self::Error>>> {
let mut this = self.project(); let mut this = self.project();
loop { loop {
if *this.eof { if *this.eof {
return Poll::Ready(None); return Poll::Ready(None);
@ -276,7 +277,7 @@ enum ContentEncoder {
} }
impl ContentEncoder { impl ContentEncoder {
fn encoder(encoding: ContentEncoding) -> Option<Self> { fn select(encoding: ContentEncoding) -> Option<Self> {
match encoding { match encoding {
#[cfg(feature = "compress-gzip")] #[cfg(feature = "compress-gzip")]
ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new( ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new(

View File

@ -46,9 +46,6 @@ pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
} }
/// Helper trait for managing response encoding. /// Helper trait for managing response encoding.
///
/// Use `pre_encoded_with` to flag response as already encoded. For example, when serving a Gzip
/// compressed file from disk.
pub trait BodyEncoding { pub trait BodyEncoding {
/// Get content encoding /// Get content encoding
fn preferred_encoding(&self) -> Option<ContentEncoding>; fn preferred_encoding(&self) -> Option<ContentEncoding>;
@ -59,21 +56,10 @@ pub trait BodyEncoding {
/// ///
/// [`Compress`]: crate::middleware::Compress /// [`Compress`]: crate::middleware::Compress
fn encode_with(&mut self, encoding: ContentEncoding) -> &mut Self; fn encode_with(&mut self, encoding: ContentEncoding) -> &mut Self;
// /// Flags that a file already is encoded so that [`Compress`] does not modify it.
// ///
// /// Effectively a shortcut for `compress_with("identity")`
// /// plus `insert_header(ContentEncoding, encoding)`.
// ///
// /// [`Compress`]: crate::middleware::Compress
// fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self;
} }
struct CompressWith(ContentEncoding); struct CompressWith(ContentEncoding);
// TODO: add or delete this
// struct PreCompressed(ContentEncoding);
impl BodyEncoding for crate::HttpResponseBuilder { impl BodyEncoding for crate::HttpResponseBuilder {
fn preferred_encoding(&self) -> Option<ContentEncoding> { fn preferred_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<CompressWith>().map(|enc| enc.0) self.extensions().get::<CompressWith>().map(|enc| enc.0)
@ -83,11 +69,6 @@ impl BodyEncoding for crate::HttpResponseBuilder {
self.extensions_mut().insert(CompressWith(encoding)); self.extensions_mut().insert(CompressWith(encoding));
self self
} }
// fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self {
// self.extensions_mut().insert(PreCompressed(encoding));
// self
// }
} }
impl<B> BodyEncoding for crate::HttpResponse<B> { impl<B> BodyEncoding for crate::HttpResponse<B> {
@ -99,11 +80,6 @@ impl<B> BodyEncoding for crate::HttpResponse<B> {
self.extensions_mut().insert(CompressWith(encoding)); self.extensions_mut().insert(CompressWith(encoding));
self self
} }
// fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self {
// self.extensions_mut().insert(PreCompressed(encoding));
// self
// }
} }
impl<B> BodyEncoding for ServiceResponse<B> { impl<B> BodyEncoding for ServiceResponse<B> {
@ -120,13 +96,6 @@ impl<B> BodyEncoding for ServiceResponse<B> {
.insert(CompressWith(encoding)); .insert(CompressWith(encoding));
self self
} }
// fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self {
// self.request()
// .extensions_mut()
// .insert(PreCompressed(encoding));
// self
// }
} }
// TODO: remove these impls ? // TODO: remove these impls ?

View File

@ -27,17 +27,51 @@ use crate::{
/// Middleware for compressing response payloads. /// Middleware for compressing response payloads.
/// ///
/// Use `BodyEncoding` trait for overriding response compression. To disable compression set /// # Encoding Negotiation
/// encoding to `ContentEncoding::Identity`. /// `Compress` will read the `Accept-Encoding` header to negotiate which compression codec to use.
/// Payloads are not compressed if the header is not sent. The `compress-*` [feature flags] are also
/// considered in this selection process.
///
/// # Pre-compressed Payload
/// If you are serving some data is already using a compressed representation (e.g., a gzip
/// compressed HTML file from disk) you can signal this to `Compress` by setting an appropriate
/// `Content-Encoding` header. In addition to preventing double compressing the payload, this header
/// is required by the spec when using compressed representations and will inform the client that
/// the content should be uncompressed.
///
/// However, it is not advised to unconditionally serve encoded representations of content because
/// the client may not support it. The [`AcceptEncoding`] typed header has some utilities to help
/// perform manual encoding negotiation, if required. When negotiating content encoding, it is also
/// required by the spec to send a `Vary: Accept-Encoding` header.
///
/// A (naïve) example serving an pre-compressed Gzip file is included below.
/// ///
/// # Examples /// # Examples
/// To enable automatic payload compression just include `Compress` as a top-level middleware:
/// ``` /// ```
/// use actix_web::{web, middleware, App, HttpResponse}; /// use actix_web::{middleware, web, App, HttpResponse};
/// ///
/// let app = App::new() /// let app = App::new()
/// .wrap(middleware::Compress::default()) /// .wrap(middleware::Compress::default())
/// .default_service(web::to(|| HttpResponse::NotFound())); /// .default_service(web::to(|| HttpResponse::Ok().body("hello world")));
/// ``` /// ```
///
/// Pre-compressed Gzip file being served from disk with correct headers added to bypass middleware:
/// ```no_run
/// use actix_web::{middleware, http::header, web, App, HttpResponse, Responder};
///
/// async fn index_handler() -> actix_web::Result<impl Responder> {
/// Ok(actix_files::NamedFile::open("./assets/index.html.gz")?
/// .customize()
/// .insert_header(header::ContentEncoding::Gzip))
/// }
///
/// let app = App::new()
/// .wrap(middleware::Compress::default())
/// .default_service(web::to(index_handler));
/// ```
///
/// [feature flags]: ../index.html#crate-features
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
#[non_exhaustive] #[non_exhaustive]
pub struct Compress; pub struct Compress;