HTTP content coding for request and response bodies.
Currently supports:
Requests
use http::HeaderMap;
use web_faith_encoding::{Coding, request::encode};
# async fn example() {
let mut headers = HeaderMap::new();
let body = b"the quick brown fox".repeat(8);
let compressed = encode(&mut headers, &body, Coding::Gzip).await.expect("gzip compresses");
assert!(compressed.len() < body.len());
assert_eq!(headers["content-encoding"], "gzip");
# }
To drive the halves separately, compress_buffer and compress_stream do the body, and
[ContentEncoding::layer] with to_header_value does the
header.
Responses
- Use
AcceptEncoding to parse the advertised supported coding set from the request.
- Use
decode to take one layer off a response: it decodes the body and updates the headers
together.
- A body encoded more than once takes one call per layer.
use std::pin::Pin;
use bytes::Bytes;
use futures::TryStreamExt as _;
use http::{HeaderMap, HeaderValue};
use web_faith_encoding::{
Coding,
request::encode,
response::{AcceptEncoding, ByteStream, decode},
};
# async fn example() {
let mut request = HeaderMap::new();
request.insert("accept-encoding", HeaderValue::from_static("gzip, br;q=0.5"));
let accept = AcceptEncoding::from(&request);
let mut response = HeaderMap::new();
response.insert("content-encoding", HeaderValue::from_static("custom-thing"));
let gzipped = encode(&mut response, b"pretend this is custom-thing", Coding::Gzip)
.await
.expect("gzip compresses");
assert_eq!(response["content-encoding"], "custom-thing, gzip");
let body: Pin<Box<ByteStream>> =
Box::pin(futures::stream::once(async move { Ok(Bytes::from(gzipped)) }));
let decoded: Vec<u8> = decode(&mut response, body, &accept)
.try_fold(Vec::new(), |mut acc, chunk| async move {
acc.extend_from_slice(&chunk);
Ok(acc)
})
.await
.expect("the gzip decodes");
assert_eq!(decoded, b"pretend this is custom-thing");
assert_eq!(response["content-encoding"], "custom-thing");
# }