rename BodyEncoding methods

This commit is contained in:
Rob Ede 2022-01-02 08:46:38 +00:00
parent d981dda09b
commit b540c4c9b8
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
11 changed files with 211 additions and 165 deletions

View File

@ -420,7 +420,7 @@ impl NamedFile {
}
if let Some(current_encoding) = self.encoding {
res.encoding(current_encoding);
res.encode_with(current_encoding);
}
let reader = chunked::new_chunked_read(self.md.len(), 0, self.file);
@ -494,7 +494,7 @@ impl NamedFile {
// default compressing
if let Some(current_encoding) = self.encoding {
res.encoding(current_encoding);
res.encode_with(current_encoding);
}
if let Some(lm) = last_modified {
@ -517,7 +517,7 @@ impl NamedFile {
length = ranges[0].length;
offset = ranges[0].start;
res.encoding(ContentEncoding::Identity);
res.encode_with(ContentEncoding::Identity);
res.insert_header((
header::CONTENT_RANGE,
format!("bytes {}-{}/{}", offset, offset + length - 1, self.md.len()),

View File

@ -20,7 +20,7 @@ pub struct ContentEncodingParseError;
/// See [IANA HTTP Content Coding Registry].
///
/// [IANA HTTP Content Coding Registry]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ContentEncoding {
/// Indicates the no-op identity encoding.
@ -42,12 +42,6 @@ pub enum ContentEncoding {
}
impl ContentEncoding {
// /// Is the content compressed?
// #[inline]
// pub const fn is_compression(self) -> bool {
// matches!(self, ContentEncoding::Identity)
// }
/// Convert content encoding to string.
#[inline]
pub const fn as_str(self) -> &'static str {
@ -82,16 +76,18 @@ impl Default for ContentEncoding {
impl FromStr for ContentEncoding {
type Err = ContentEncodingParseError;
fn from_str(val: &str) -> Result<Self, Self::Err> {
let val = val.trim();
fn from_str(enc: &str) -> Result<Self, Self::Err> {
let enc = enc.trim();
if val.eq_ignore_ascii_case("br") {
if enc.eq_ignore_ascii_case("br") {
Ok(ContentEncoding::Brotli)
} else if val.eq_ignore_ascii_case("gzip") {
} else if enc.eq_ignore_ascii_case("gzip") {
Ok(ContentEncoding::Gzip)
} else if val.eq_ignore_ascii_case("deflate") {
} else if enc.eq_ignore_ascii_case("deflate") {
Ok(ContentEncoding::Deflate)
} else if val.eq_ignore_ascii_case("zstd") {
} else if enc.eq_ignore_ascii_case("identity") {
Ok(ContentEncoding::Identity)
} else if enc.eq_ignore_ascii_case("zstd") {
Ok(ContentEncoding::Zstd)
} else {
Err(ContentEncodingParseError)

View File

@ -473,7 +473,7 @@ async fn test_no_decompress() {
.wrap(actix_web::middleware::Compress::default())
.service(web::resource("/").route(web::to(|| {
let mut res = HttpResponse::Ok().body(STR);
res.encoding(header::ContentEncoding::Gzip);
res.encode_with(header::ContentEncoding::Gzip);
res
})))
});
@ -645,7 +645,7 @@ async fn test_client_deflate_encoding() {
let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok()
.encoding(ContentEncoding::Brotli)
.encode_with(ContentEncoding::Brotli)
.body(body)
}))
});
@ -670,7 +670,7 @@ async fn test_client_deflate_encoding_large_random() {
let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok()
.encoding(ContentEncoding::Brotli)
.encode_with(ContentEncoding::Brotli)
.body(body)
}))
});
@ -689,7 +689,7 @@ async fn test_client_streaming_explicit() {
let srv = actix_test::start(|| {
App::new().default_service(web::to(|body: web::Payload| {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
.streaming(body)
}))
});
@ -714,7 +714,7 @@ async fn test_body_streaming_implicit() {
});
HttpResponse::Ok()
.encoding(ContentEncoding::Gzip)
.encode_with(ContentEncoding::Gzip)
.streaming(Box::pin(body))
}))
});

View File

@ -12,16 +12,16 @@ save_exit_code() {
[ "$CMD_EXIT" = "0" ] || EXIT=$CMD_EXIT
}
save_exit_code cargo test --lib --tests -p=actix-router --all-features
save_exit_code cargo test --lib --tests -p=actix-http --all-features
save_exit_code cargo test --lib --tests -p=actix-web --features=rustls,openssl -- --skip=test_reading_deflate_encoding_large_random_rustls
save_exit_code cargo test --lib --tests -p=actix-web-codegen --all-features
save_exit_code cargo test --lib --tests -p=awc --all-features
save_exit_code cargo test --lib --tests -p=actix-http-test --all-features
save_exit_code cargo test --lib --tests -p=actix-test --all-features
save_exit_code cargo test --lib --tests -p=actix-files
save_exit_code cargo test --lib --tests -p=actix-multipart --all-features
save_exit_code cargo test --lib --tests -p=actix-web-actors --all-features
save_exit_code cargo test --lib --tests -p=actix-router --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-http --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-web --features=rustls,openssl -- --nocapture --skip=test_reading_deflate_encoding_large_random_rustls
save_exit_code cargo test --lib --tests -p=actix-web-codegen --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=awc --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-http-test --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-test --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-files -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-multipart --all-features -- --nocapture
save_exit_code cargo test --lib --tests -p=actix-web-actors --all-features -- --nocapture
save_exit_code cargo test --workspace --doc

View File

@ -22,7 +22,7 @@ pub use crate::service::{HttpServiceFactory, ServiceRequest, ServiceResponse, We
pub use crate::types::{JsonBody, Readlines, UrlEncoded};
use crate::http::header::ContentEncoding;
use crate::{http::header::ContentEncoding, HttpMessage as _};
use actix_router::Patterns;
@ -47,60 +47,105 @@ pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
/// Helper trait for managing response encoding.
///
/// Use `encoding` to flag response as already encoded. For example, when serving a Gzip compressed
/// file from disk.
/// Use `pre_encoded_with` to flag response as already encoded. For example, when serving a Gzip
/// compressed file from disk.
pub trait BodyEncoding {
/// Get content encoding
fn get_encoding(&self) -> Option<ContentEncoding>;
fn preferred_encoding(&self) -> Option<ContentEncoding>;
/// Set content encoding
/// Set content encoding to use.
///
/// Must be used with [`crate::middleware::Compress`] to take effect.
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self;
/// Must be used with [`Compress`] to take effect.
///
/// [`Compress`]: crate::middleware::Compress
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 Enc(ContentEncoding);
struct CompressWith(ContentEncoding);
impl BodyEncoding for actix_http::ResponseBuilder {
fn get_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<Enc>().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(Enc(encoding));
self
}
}
impl<B> BodyEncoding for actix_http::Response<B> {
fn get_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<Enc>().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(Enc(encoding));
self
}
}
struct PreCompressed(ContentEncoding);
impl BodyEncoding for crate::HttpResponseBuilder {
fn get_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<Enc>().map(|enc| enc.0)
fn preferred_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<CompressWith>().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(Enc(encoding));
fn encode_with(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(CompressWith(encoding));
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> {
fn get_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<Enc>().map(|enc| enc.0)
fn preferred_encoding(&self) -> Option<ContentEncoding> {
self.extensions().get::<CompressWith>().map(|enc| enc.0)
}
fn encoding(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(Enc(encoding));
fn encode_with(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(CompressWith(encoding));
self
}
fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self {
self.extensions_mut().insert(PreCompressed(encoding));
self
}
}
impl<B> BodyEncoding for ServiceResponse<B> {
fn preferred_encoding(&self) -> Option<ContentEncoding> {
self.request()
.extensions()
.get::<CompressWith>()
.map(|enc| enc.0)
}
fn encode_with(&mut self, encoding: ContentEncoding) -> &mut Self {
self.request()
.extensions_mut()
.insert(CompressWith(encoding));
self
}
fn pre_encoded_with(&mut self, encoding: ContentEncoding) -> &mut Self {
self.request()
.extensions_mut()
.insert(PreCompressed(encoding));
self
}
}
// impl BodyEncoding for actix_http::ResponseBuilder {
// fn get_encoding(&self) -> Option<ContentEncoding> {
// self.extensions().get::<Enc>().map(|enc| enc.0)
// }
// fn compress_with(&mut self, encoding: ContentEncoding) -> &mut Self {
// self.extensions_mut().insert(Enc(encoding));
// self
// }
// }
// impl<B> BodyEncoding for actix_http::Response<B> {
// fn get_encoding(&self) -> Option<ContentEncoding> {
// self.extensions().get::<Enc>().map(|enc| enc.0)
// }
// fn compress_with(&mut self, encoding: ContentEncoding) -> &mut Self {
// self.extensions_mut().insert(Enc(encoding));
// self
// }
// }

View File

@ -1,6 +1,6 @@
use std::collections::HashSet;
use super::{common_header, Encoding, Preference, Quality, QualityItem};
use super::{common_header, ContentEncoding, Encoding, Preference, Quality, QualityItem};
use crate::http::header;
common_header! {
@ -31,7 +31,7 @@ common_header! {
///
/// let mut builder = HttpResponse::Ok();
/// builder.insert_header(
/// AcceptEncoding(vec![QualityItem::max(Preference::Specific(Encoding::Gzip))])
/// AcceptEncoding(vec![QualityItem::max(Preference::Specific(Encoding::gzip()))])
/// );
/// ```
///
@ -57,8 +57,8 @@ common_header! {
order_of_appearance,
vec![b"br, gzip"],
Some(AcceptEncoding(vec![
QualityItem::max(Preference::Specific(Encoding::Brotli)),
QualityItem::max(Preference::Specific(Encoding::Gzip)),
QualityItem::max(Preference::Specific(Encoding::brotli())),
QualityItem::max(Preference::Specific(Encoding::gzip())),
]))
);
@ -76,7 +76,7 @@ common_header! {
only_gzip_no_identity,
vec![b"gzip, *; q=0"],
Some(AcceptEncoding(vec![
QualityItem::max(Preference::Specific(Encoding::Gzip)),
QualityItem::max(Preference::Specific(Encoding::gzip())),
QualityItem::zero(Preference::Any),
]))
);
@ -109,7 +109,7 @@ impl AcceptEncoding {
if self.0.is_empty() {
// though it is not recommended to encode in this case, return identity encoding
return Some(Encoding::Identity);
return Some(Encoding::identity());
}
// 2. If the representation has no content-coding, then it is acceptable by default unless
@ -119,10 +119,10 @@ impl AcceptEncoding {
let acceptable_items = self.ranked_items().collect::<Vec<_>>();
let identity_acceptable = is_identity_acceptable(&acceptable_items);
let identity_supported = supported_set.contains(&Encoding::Identity);
let identity_supported = supported_set.contains(&Encoding::identity());
if identity_acceptable && identity_supported && supported_set.len() == 1 {
return Some(Encoding::Identity);
return Some(Encoding::identity());
}
// 3. If the representation's content-coding is one of the content-codings listed in the
@ -144,7 +144,7 @@ impl AcceptEncoding {
match matched {
Some(Preference::Specific(enc)) => Some(enc),
_ if identity_acceptable => Some(Encoding::Identity),
_ if identity_acceptable => Some(Encoding::identity()),
_ => None,
}
@ -190,14 +190,15 @@ impl AcceptEncoding {
match self.0.iter().find(|pref| {
matches!(
pref.item,
Preference::Any | Preference::Specific(Encoding::Identity)
Preference::Any
| Preference::Specific(Encoding::Known(ContentEncoding::Identity))
)
}) {
// "identity" or "*" found so no representation is acceptable
Some(_) => None,
// implicit "identity" is acceptable
None => Some(Preference::Specific(Encoding::Identity)),
None => Some(Preference::Specific(Encoding::identity())),
}
})
}
@ -240,7 +241,9 @@ fn is_identity_acceptable(items: &'_ [QualityItem<Preference<Encoding>>]) -> boo
for q in items {
match (q.quality, &q.item) {
// occurrence of "identity;q=n"; return true if quality is non-zero
(q, Preference::Specific(Encoding::Identity)) => return q > Quality::ZERO,
(q, Preference::Specific(Encoding::Known(ContentEncoding::Identity))) => {
return q > Quality::ZERO
}
// occurrence of "*;q=n"; return true if quality is non-zero
(q, Preference::Any) => return q > Quality::ZERO,
@ -308,80 +311,82 @@ mod tests {
let test = accept_encoding!();
assert_eq!(
test.negotiate([Encoding::Identity].iter()),
Some(Encoding::Identity),
test.negotiate([Encoding::identity()].iter()),
Some(Encoding::identity()),
);
let test = accept_encoding!("identity;q=0");
assert_eq!(test.negotiate([Encoding::Identity].iter()), None);
assert_eq!(test.negotiate([Encoding::identity()].iter()), None);
let test = accept_encoding!("*;q=0");
assert_eq!(test.negotiate([Encoding::Identity].iter()), None);
assert_eq!(test.negotiate([Encoding::identity()].iter()), None);
let test = accept_encoding!();
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Identity),
test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::identity()),
);
let test = accept_encoding!("gzip");
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip),
test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip()),
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Identity].iter()),
Some(Encoding::Identity),
test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
Some(Encoding::identity()),
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip),
test.negotiate([Encoding::brotli(), Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip()),
);
let test = accept_encoding!("gzip", "identity;q=0");
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip),
test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip()),
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Identity].iter()),
test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
None
);
let test = accept_encoding!("gzip", "*;q=0");
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip),
test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip()),
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Identity].iter()),
test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
None
);
let test = accept_encoding!("gzip", "deflate", "br");
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip),
test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip()),
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Identity].iter()),
Some(Encoding::Brotli)
test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
Some(Encoding::brotli())
);
assert_eq!(
test.negotiate([Encoding::Deflate, Encoding::Identity].iter()),
Some(Encoding::Deflate)
test.negotiate([Encoding::deflate(), Encoding::identity()].iter()),
Some(Encoding::deflate())
);
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Deflate, Encoding::Identity].iter()),
Some(Encoding::Gzip)
test.negotiate(
[Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()
),
Some(Encoding::gzip())
);
assert_eq!(
test.negotiate([Encoding::Gzip, Encoding::Brotli, Encoding::Identity].iter()),
Some(Encoding::Gzip)
test.negotiate([Encoding::gzip(), Encoding::brotli(), Encoding::identity()].iter()),
Some(Encoding::gzip())
);
assert_eq!(
test.negotiate([Encoding::Brotli, Encoding::Gzip, Encoding::Identity].iter()),
Some(Encoding::Gzip)
test.negotiate([Encoding::brotli(), Encoding::gzip(), Encoding::identity()].iter()),
Some(Encoding::gzip())
);
}

View File

@ -1,36 +1,44 @@
use std::{fmt, str};
/// A value to represent an encoding used in the `Accept-Encoding` header.
use actix_http::ContentEncoding;
/// A value to represent an encoding used in the `Accept-Encoding` and `Content-Encoding` header.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Encoding {
/// The no-op "identity" encoding.
Identity,
/// A supported content encoding. See [`ContentEncoding`] for variants.
Known(ContentEncoding),
/// Brotli compression (`br`).
Brotli,
/// Some other encoding that is less common, can be any string.
Unknown(String),
}
/// Gzip compression.
Gzip,
impl Encoding {
pub const fn identity() -> Self {
Self::Known(ContentEncoding::Identity)
}
/// Deflate (LZ77) encoding.
Deflate,
pub const fn brotli() -> Self {
Self::Known(ContentEncoding::Brotli)
}
/// Zstd compression.
Zstd,
pub const fn deflate() -> Self {
Self::Known(ContentEncoding::Deflate)
}
/// Some other encoding that is less common, can be any String.
Other(String),
pub const fn gzip() -> Self {
Self::Known(ContentEncoding::Gzip)
}
pub const fn zstd() -> Self {
Self::Known(ContentEncoding::Zstd)
}
}
impl fmt::Display for Encoding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Encoding::Identity => "identity",
Encoding::Brotli => "br",
Encoding::Gzip => "gzip",
Encoding::Deflate => "deflate",
Encoding::Zstd => "zstd",
Encoding::Other(ref enc) => enc.as_ref(),
Encoding::Known(enc) => enc.as_str(),
Encoding::Unknown(enc) => enc.as_str(),
})
}
}
@ -38,14 +46,10 @@ impl fmt::Display for Encoding {
impl str::FromStr for Encoding {
type Err = crate::error::ParseError;
fn from_str(enc_str: &str) -> Result<Self, crate::error::ParseError> {
match enc_str {
"identity" => Ok(Self::Identity),
"br" => Ok(Self::Brotli),
"gzip" => Ok(Self::Gzip),
"deflate" => Ok(Self::Deflate),
"zstd" => Ok(Self::Zstd),
_ => Ok(Self::Other(enc_str.to_owned())),
fn from_str(enc: &str) -> Result<Self, crate::error::ParseError> {
match enc.parse::<ContentEncoding>() {
Ok(enc) => Ok(Self::Known(enc)),
Err(_) => Ok(Self::Unknown(enc.to_owned())),
}
}
}

View File

@ -16,7 +16,7 @@ use pin_project_lite::pin_project;
use crate::{
body::{EitherBody, MessageBody},
dev::BodyEncoding,
dev::BodyEncoding as _,
http::{
header::{self, AcceptEncoding, ContentEncoding, Encoding, HeaderValue},
StatusCode,
@ -111,22 +111,22 @@ static SUPPORTED_ENCODINGS_STRING: Lazy<String> = Lazy::new(|| {
});
static SUPPORTED_ENCODINGS: Lazy<Vec<Encoding>> = Lazy::new(|| {
let mut encodings = vec![Encoding::Identity];
let mut encodings = vec![Encoding::identity()];
#[cfg(feature = "compress-brotli")]
{
encodings.push(Encoding::Brotli);
encodings.push(Encoding::brotli());
}
#[cfg(feature = "compress-gzip")]
{
encodings.push(Encoding::Gzip);
encodings.push(Encoding::Deflate);
encodings.push(Encoding::gzip());
encodings.push(Encoding::deflate());
}
#[cfg(feature = "compress-zstd")]
{
encodings.push(Encoding::Zstd);
encodings.push(Encoding::zstd());
}
assert!(
@ -158,7 +158,7 @@ where
// missing header; fallback to identity
None => {
return Either::left(CompressResponse {
encoding: Encoding::Identity,
encoding: Encoding::identity(),
fut: self.service.call(req),
_phantom: PhantomData,
})
@ -217,16 +217,14 @@ where
match ready!(this.fut.poll(cx)) {
Ok(resp) => {
let enc = if let Some(enc) = resp.response().get_encoding() {
let enc = if let Some(enc) = resp.response().preferred_encoding() {
enc
} else {
match this.encoding {
Encoding::Brotli => ContentEncoding::Brotli,
Encoding::Gzip => ContentEncoding::Gzip,
Encoding::Deflate => ContentEncoding::Deflate,
Encoding::Identity => ContentEncoding::Identity,
Encoding::Zstd => ContentEncoding::Zstd,
enc => unimplemented!("encoding {} should not be here", enc),
Encoding::Known(enc) => *enc,
Encoding::Unknown(enc) => {
unimplemented!("encoding {} should not be here", enc);
}
}
};

View File

@ -27,7 +27,7 @@ macro_rules! test_server {
web::to(|| {
HttpResponse::Ok()
// signal to compressor that content should not be altered
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
// signal to client that content is encoded
.insert_header(ContentEncoding::Gzip)
.body(LOREM_GZIP)
@ -38,7 +38,7 @@ macro_rules! test_server {
web::to(|| {
HttpResponse::Ok()
// signal to compressor that content should not be altered
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
// signal to client that content is encoded
.insert_header(ContentEncoding::Brotli)
.body(LOREM_BR)
@ -49,7 +49,7 @@ macro_rules! test_server {
web::to(|| {
HttpResponse::Ok()
// signal to compressor that content should not be altered
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
// signal to client that content is encoded
.insert_header(ContentEncoding::Zstd)
.body(LOREM_ZSTD)
@ -60,7 +60,7 @@ macro_rules! test_server {
web::to(|| {
HttpResponse::Ok()
// signal to compressor that content should not be altered
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
// signal to client that content is encoded as 7zip
.insert_header((header::CONTENT_ENCODING, "xz"))
.body(LOREM_XZ)

View File

@ -136,12 +136,12 @@ async fn test_body_encoding_override() {
.wrap(Compress::new(ContentEncoding::Gzip))
.service(web::resource("/").route(web::to(|| {
HttpResponse::Ok()
.encoding(ContentEncoding::Deflate)
.encode_with(ContentEncoding::Deflate)
.body(STR)
})))
.service(web::resource("/raw").route(web::to(|| {
let mut res = HttpResponse::with_body(actix_web::http::StatusCode::OK, STR);
res.encoding(ContentEncoding::Deflate);
res.encode_with(ContentEncoding::Deflate);
res.map_into_boxed_body()
})))
});
@ -704,7 +704,7 @@ async fn test_brotli_encoding_large_openssl() {
actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
.body(bytes)
})))
});
@ -765,20 +765,15 @@ mod plus_rustls {
let srv = actix_test::start_with(actix_test::config().rustls(tls_config()), || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok()
.encoding(ContentEncoding::Identity)
.encode_with(ContentEncoding::Identity)
.body(bytes)
})))
});
// encode data
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(data.as_ref()).unwrap();
let enc = e.finish().unwrap();
let req = srv
.post("/")
.insert_header((actix_web::http::header::CONTENT_ENCODING, "deflate"))
.send_stream(TestBody::new(Bytes::from(enc), 1024));
.send_stream(TestBody::new(Bytes::from(deflate::encode(&data)), 1024));
let mut res = req.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);

View File

@ -1,3 +1,6 @@
// compiling some tests will trigger unused function warnings even though other tests use them
#![allow(dead_code)]
use std::io::{Read as _, Write as _};
pub mod gzip {