1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-11-25 19:11:10 +00:00

add double compress layer test

This commit is contained in:
Rob Ede 2022-01-03 14:05:08 +00:00
parent e890307091
commit 25fe1bbaa5
No known key found for this signature in database
GPG key ID: 97C636207D3EF933
3 changed files with 67 additions and 6 deletions

View file

@ -109,6 +109,7 @@ 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"] }
brotli2 = "0.3.2" brotli2 = "0.3.2"
const-str = "0.3"
criterion = { version = "0.3", features = ["html_reports"] } criterion = { version = "0.3", features = ["html_reports"] }
env_logger = "0.9" env_logger = "0.9"
flate2 = "1.0.13" flate2 = "1.0.13"

View file

@ -56,16 +56,16 @@ impl<B: MessageBody> Encoder<B> {
} }
pub fn response(encoding: ContentEncoding, head: &mut ResponseHead, body: B) -> Self { pub fn response(encoding: ContentEncoding, head: &mut ResponseHead, body: B) -> Self {
let should_encode = !(head.headers().contains_key(&CONTENT_ENCODING)
|| head.status == StatusCode::SWITCHING_PROTOCOLS
|| head.status == StatusCode::NO_CONTENT
|| encoding == ContentEncoding::Identity);
// no need to compress an empty body // no need to compress an empty body
if matches!(body.size(), BodySize::None) { if matches!(body.size(), BodySize::None) {
return Self::none(); return Self::none();
} }
let should_encode = !(head.headers().contains_key(&CONTENT_ENCODING)
|| head.status == StatusCode::SWITCHING_PROTOCOLS
|| head.status == StatusCode::NO_CONTENT
|| encoding == ContentEncoding::Identity);
let body = match body.try_into_bytes() { let body = match body.try_into_bytes() {
Ok(body) => EncoderBody::Full { body }, Ok(body) => EncoderBody::Full { body },
Err(body) => EncoderBody::Stream { body }, Err(body) => EncoderBody::Stream { body },
@ -301,7 +301,7 @@ impl ContentEncoder {
Some(ContentEncoder::Zstd(encoder)) Some(ContentEncoder::Zstd(encoder))
} }
ContentEncoding::Identity => None, _ => None,
} }
} }

View file

@ -217,3 +217,63 @@ static SUPPORTED_ENCODINGS: Lazy<Vec<Encoding>> = Lazy::new(|| {
encodings encodings
}); });
// move cfg(feature) to prevents_double_compressing if more tests are added
#[cfg(feature = "compress-gzip")]
#[cfg(test)]
mod tests {
use super::*;
use crate::{middleware::DefaultHeaders, test, web, App};
pub fn gzip_decode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
use std::io::Read as _;
let mut decoder = flate2::read::GzDecoder::new(bytes.as_ref());
let mut buf = Vec::new();
decoder.read_to_end(&mut buf).unwrap();
buf
}
#[actix_rt::test]
async fn prevents_double_compressing() {
const D: &str = "hello world ";
const DATA: &str = const_str::repeat!(D, 100);
let app = test::init_service({
App::new()
.wrap(Compress::default())
.route(
"/single",
web::get().to(move || HttpResponse::Ok().body(DATA)),
)
.service(
web::resource("/double")
.wrap(Compress::default())
.wrap(DefaultHeaders::new().add(("x-double", "true")))
.route(web::get().to(move || HttpResponse::Ok().body(DATA))),
)
})
.await;
let req = test::TestRequest::default()
.uri("/single")
.insert_header((header::ACCEPT_ENCODING, "gzip"))
.to_request();
let res = test::call_service(&app, req).await;
assert_eq!(res.status(), StatusCode::OK);
assert_eq!(res.headers().get("x-double"), None);
assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip");
let bytes = test::read_body(res).await;
assert_eq!(gzip_decode(bytes), DATA.as_bytes());
let req = test::TestRequest::default()
.uri("/double")
.insert_header((header::ACCEPT_ENCODING, "gzip"))
.to_request();
let res = test::call_service(&app, req).await;
assert_eq!(res.status(), StatusCode::OK);
assert_eq!(res.headers().get("x-double").unwrap(), "true");
assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip");
let bytes = test::read_body(res).await;
assert_eq!(gzip_decode(bytes), DATA.as_bytes());
}
}