Module compression

Expand description

Middleware that compresses response bodies.

§Example

Example showing how to respond with the compressed contents of a file.

use bytes::Bytes;
use futures_lite::stream::StreamExt;
use rama_core::error::BoxError;
use rama_http::dep::http_body::Frame;
use rama_http::dep::http_body_util::{BodyExt , StreamBody};
use rama_http::dep::http_body_util::combinators::BoxBody as InnerBoxBody;
use rama_http::layer::compression::CompressionLayer;
use rama_http::{Body, Request, Response, header::ACCEPT_ENCODING};
use rama_core::service::service_fn;
use rama_core::{Context, Service, Layer};
use std::convert::Infallible;
use tokio::fs::{self, File};
use tokio_util::io::ReaderStream;

type BoxBody = InnerBoxBody<Bytes, std::io::Error>;

async fn handle(req: Request) -> Result<Response<BoxBody>, Infallible> {
    // Open the file.
    let file = File::open("Cargo.toml").await.expect("file missing");
    // Convert the file into a `Stream` of `Bytes`.
    let stream = ReaderStream::new(file);
    // Convert the stream into a stream of data `Frame`s.
    let stream = stream.map(|res| match res {
        Ok(v) => Ok(Frame::data(v)),
        Err(e) => Err(e),
    });
    // Convert the `Stream` into a `Body`.
    let body = StreamBody::new(stream);
    // Erase the type because its very hard to name in the function signature.
    let body = BodyExt::boxed(body);
    // Create response.
    Ok(Response::new(body))
}

let mut service = (
    // Compress responses based on the `Accept-Encoding` header.
    CompressionLayer::new(),
).into_layer(service_fn(handle));

// Call the service.
let request = Request::builder()
    .header(ACCEPT_ENCODING, "gzip")
    .body(Body::default())?;

let response = service
    .serve(Context::default(), request)
    .await?;

assert_eq!(response.headers()["content-encoding"], "gzip");

// Read the body
let bytes = response
    .into_body()
    .collect()
    .await?
    .to_bytes();

// The compressed body should be smaller 🤞
let uncompressed_len = fs::read_to_string("Cargo.toml").await?.len();
assert!(bytes.len() < uncompressed_len);

Modules§

predicate
Predicates for disabling compression of responses.

Structs§

Compression
Compress response bodies of the underlying service.
CompressionBody
Response body of Compression.
CompressionLayer
Compress response bodies of the underlying service.
DefaultPredicate
The default predicate used by Compression and CompressionLayer.

Enums§

CompressionLevel
Level of compression data should be compressed with.

Traits§

Predicate
Predicate used to determine if a response should be compressed or not.