1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-12-18 01:43:58 +01:00
actix-web/tests/test_server.rs

949 lines
28 KiB
Rust
Raw Normal View History

2021-02-07 04:54:58 +01:00
#[cfg(feature = "openssl")]
extern crate tls_openssl as openssl;
#[cfg(feature = "rustls")]
extern crate tls_rustls as rustls;
use std::{
future::Future,
io::{Read, Write},
pin::Pin,
task::{Context, Poll},
};
use actix_web::{
2022-01-03 14:17:57 +01:00
cookie::{Cookie, CookieBuilder},
dev::BodyEncoding,
2022-01-03 14:17:57 +01:00
http::{
header::{self, ContentEncoding, ACCEPT_ENCODING, CONTENT_ENCODING, TRANSFER_ENCODING},
StatusCode,
},
middleware::{Compress, NormalizePath, TrailingSlash},
web, App, Error, HttpResponse,
2019-03-02 07:51:32 +01:00
};
use bytes::Bytes;
2021-04-01 16:26:13 +02:00
use futures_core::ready;
2022-01-03 14:17:57 +01:00
use rand::{distributions::Alphanumeric, Rng as _};
2021-02-27 21:58:44 +01:00
#[cfg(feature = "openssl")]
use openssl::{
pkey::PKey,
ssl::{SslAcceptor, SslMethod},
x509::X509,
};
2022-01-03 14:17:57 +01:00
mod test_utils;
use test_utils::{brotli, deflate, gzip, zstd};
2019-03-02 07:51:32 +01:00
2018-04-14 01:02:01 +02:00
const STR: &str = "Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World \
Hello World Hello World Hello World Hello World Hello World";
2018-01-11 06:47:30 +01:00
2021-02-27 21:58:44 +01:00
#[cfg(feature = "openssl")]
fn openssl_config() -> SslAcceptor {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
let cert = X509::from_pem(cert_file.as_bytes()).unwrap();
let key = PKey::private_key_from_pem(key_file.as_bytes()).unwrap();
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_certificate(&cert).unwrap();
builder.set_private_key(&key).unwrap();
builder.set_alpn_select_callback(|_, protos| {
const H2: &[u8] = b"\x02h2";
if protos.windows(3).any(|window| window == H2) {
Ok(b"h2")
} else {
Err(openssl::ssl::AlpnError::NOACK)
}
});
builder.set_alpn_protos(b"\x02h2").unwrap();
builder.build()
}
2019-12-20 08:50:07 +01:00
struct TestBody {
data: Bytes,
chunk_size: usize,
delay: Pin<Box<actix_rt::time::Sleep>>,
2019-12-20 08:50:07 +01:00
}
impl TestBody {
fn new(data: Bytes, chunk_size: usize) -> Self {
TestBody {
data,
chunk_size,
delay: Box::pin(actix_rt::time::sleep(std::time::Duration::from_millis(10))),
2019-12-20 08:50:07 +01:00
}
}
}
2020-05-18 04:47:20 +02:00
impl futures_core::stream::Stream for TestBody {
2019-12-20 08:50:07 +01:00
type Item = Result<Bytes, Error>;
2021-02-12 00:03:17 +01:00
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
2019-12-20 08:50:07 +01:00
ready!(Pin::new(&mut self.delay).poll(cx));
2021-02-12 00:03:17 +01:00
self.delay = Box::pin(actix_rt::time::sleep(std::time::Duration::from_millis(10)));
2019-12-20 08:50:07 +01:00
let chunk_size = std::cmp::min(self.chunk_size, self.data.len());
let chunk = self.data.split_to(chunk_size);
if chunk.is_empty() {
Poll::Ready(None)
} else {
Poll::Ready(Some(Ok(chunk)))
}
}
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body() {
let srv = actix_test::start(|| {
2021-02-12 00:03:17 +01:00
App::new().service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv.get("/").send().await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-11 07:42:26 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_encoding_override() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
2019-12-12 17:28:47 +01:00
.service(web::resource("/").route(web::to(|| {
HttpResponse::Ok()
2022-01-03 14:17:57 +01:00
.encode_with(ContentEncoding::Deflate)
2019-12-12 17:28:47 +01:00
.body(STR)
})))
.service(web::resource("/raw").route(web::to(|| {
2022-01-03 14:17:57 +01:00
let mut res = HttpResponse::with_body(actix_web::http::StatusCode::OK, STR);
res.encode_with(ContentEncoding::Deflate);
res.map_into_boxed_body()
2019-12-12 17:28:47 +01:00
})))
2019-11-26 06:25:50 +01:00
});
// Builder
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
.no_decompress()
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "deflate"))
2019-11-26 06:25:50 +01:00
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(deflate::decode(bytes), STR.as_bytes());
2019-11-26 06:25:50 +01:00
// Raw Response
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.request(actix_web::http::Method::GET, srv.url("/raw"))
.no_decompress()
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "deflate"))
2019-11-26 06:25:50 +01:00
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(deflate::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
2022-01-03 14:17:57 +01:00
async fn body_gzip_large() {
2019-11-26 06:25:50 +01:00
let data = STR.repeat(10);
let srv_data = data.clone();
let srv = actix_test::start_with(actix_test::config().h1(), move || {
2019-11-26 06:25:50 +01:00
let data = srv_data.clone();
2022-01-03 14:17:57 +01:00
App::new().wrap(Compress::default()).service(
web::resource("/").route(web::to(move || HttpResponse::Ok().body(data.clone()))),
)
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
.no_decompress()
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "gzip"))
2019-11-26 06:25:50 +01:00
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(gzip::decode(bytes), data.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_gzip_large_random() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(70_000)
2020-12-23 00:45:31 +01:00
.map(char::from)
2019-11-26 06:25:50 +01:00
.collect::<String>();
let srv_data = data.clone();
let srv = actix_test::start_with(actix_test::config().h1(), move || {
2019-11-26 06:25:50 +01:00
let data = srv_data.clone();
2022-01-03 14:17:57 +01:00
App::new().wrap(Compress::default()).service(
web::resource("/").route(web::to(move || HttpResponse::Ok().body(data.clone()))),
)
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
.no_decompress()
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "gzip"))
2019-11-26 06:25:50 +01:00
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(gzip::decode(bytes), data.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_chunked_implicit() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
2019-12-12 17:28:47 +01:00
.service(web::resource("/").route(web::get().to(move || {
HttpResponse::Ok()
2019-12-20 08:50:07 +01:00
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
2019-12-12 17:28:47 +01:00
})))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
.no_decompress()
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "gzip"))
2019-11-26 06:25:50 +01:00
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
assert_eq!(res.headers().get(TRANSFER_ENCODING).unwrap(), "chunked");
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(gzip::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-12 00:26:46 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_br_streaming() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2021-02-12 00:03:17 +01:00
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
2021-02-12 00:03:17 +01:00
.service(web::resource("/").route(web::to(move || {
2019-12-12 17:28:47 +01:00
HttpResponse::Ok()
2019-12-20 08:50:07 +01:00
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
2021-02-12 00:03:17 +01:00
})))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "br"))
2019-11-26 06:25:50 +01:00
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(brotli::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-12 01:22:27 +01:00
}
2018-01-21 01:12:38 +01:00
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_head_binary() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2020-05-21 10:56:53 +02:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::head().to(move || HttpResponse::Ok().body(STR))),
2020-05-21 10:56:53 +02:00
)
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv.head("/").send().await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let len = res.headers().get(header::CONTENT_LENGTH).unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert!(bytes.is_empty());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-21 01:12:38 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_no_chunking() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(web::resource("/").route(web::to(move || {
HttpResponse::Ok()
.no_chunking(STR.len() as u64)
2019-12-20 08:50:07 +01:00
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
2019-12-12 17:28:47 +01:00
})))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv.get("/").send().await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
assert!(!res.headers().contains_key(TRANSFER_ENCODING));
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-12 01:22:27 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_deflate() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
2021-02-12 00:03:17 +01:00
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR))))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "deflate"))
2019-11-26 06:25:50 +01:00
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(deflate::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-11 06:47:30 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_body_brotli() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2021-02-12 00:03:17 +01:00
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
2021-02-12 00:03:17 +01:00
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR))))
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-11-26 06:25:50 +01:00
.get("/")
2021-01-15 03:11:10 +01:00
.append_header((ACCEPT_ENCODING, "br"))
2019-11-26 06:25:50 +01:00
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(brotli::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2018-01-11 06:47:30 +01:00
}
#[actix_rt::test]
async fn test_body_zstd() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().body(STR))))
});
2022-01-03 14:17:57 +01:00
let mut res = srv
.get("/")
.append_header((ACCEPT_ENCODING, "zstd"))
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(zstd::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
#[actix_rt::test]
async fn test_body_zstd_streaming() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new()
2022-01-03 14:17:57 +01:00
.wrap(Compress::default())
.service(web::resource("/").route(web::to(move || {
HttpResponse::Ok()
.streaming(TestBody::new(Bytes::from_static(STR.as_ref()), 24))
})))
});
2022-01-03 14:17:57 +01:00
let mut res = srv
.get("/")
.append_header((ACCEPT_ENCODING, "zstd"))
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(zstd::decode(bytes), STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
#[actix_rt::test]
async fn test_zstd_encoding() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service(
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
)
});
let request = srv
.post("/")
.append_header((CONTENT_ENCODING, "zstd"))
2022-01-03 14:17:57 +01:00
.send_body(zstd::encode(STR));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
#[actix_rt::test]
async fn test_zstd_encoding_large() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(320_000)
.map(char::from)
.collect::<String>();
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new().service(
web::resource("/")
.app_data(web::PayloadConfig::new(320_000))
.route(web::to(move |body: Bytes| {
HttpResponse::Ok().streaming(TestBody::new(body, 10240))
})),
)
});
let request = srv
.post("/")
.append_header((CONTENT_ENCODING, "zstd"))
2022-01-03 14:17:57 +01:00
.send_body(zstd::encode(&data));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2022-01-03 14:17:57 +01:00
let bytes = res.body().limit(320_000).await.unwrap();
assert_eq!(bytes, data.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_encoding() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().wrap(Compress::default()).service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.insert_header((CONTENT_ENCODING, "gzip"))
2022-01-03 14:17:57 +01:00
.send_body(gzip::encode(STR));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_gzip_encoding() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "gzip"))
2022-01-03 14:17:57 +01:00
.send_body(gzip::encode(STR));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(bytes, STR.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_gzip_encoding_large() {
let data = STR.repeat(10);
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
2022-01-03 14:17:57 +01:00
let req = srv
2019-11-26 06:25:50 +01:00
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "gzip"))
2022-01-03 14:17:57 +01:00
.send_body(gzip::encode(&data));
let mut res = req.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(bytes, data);
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_reading_gzip_encoding_large_random() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(60_000)
2020-12-23 00:45:31 +01:00
.map(char::from)
2019-11-26 06:25:50 +01:00
.collect::<String>();
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "gzip"))
2022-01-03 14:17:57 +01:00
.send_body(gzip::encode(&data));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(bytes, data.as_bytes());
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_reading_deflate_encoding() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "deflate"))
2022-01-03 14:17:57 +01:00
.send_body(deflate::encode(STR));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_reading_deflate_encoding_large() {
let data = STR.repeat(10);
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "deflate"))
2022-01-03 14:17:57 +01:00
.send_body(deflate::encode(&data));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from(data));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_reading_deflate_encoding_large_random() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(160_000)
2020-12-23 00:45:31 +01:00
.map(char::from)
2019-11-26 06:25:50 +01:00
.collect::<String>();
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "deflate"))
2022-01-03 14:17:57 +01:00
.send_body(deflate::encode(&data));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_brotli_encoding() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
2021-02-12 00:03:17 +01:00
web::resource("/").route(web::to(move |body: Bytes| HttpResponse::Ok().body(body))),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "br"))
2022-01-03 14:17:57 +01:00
.send_body(brotli::encode(STR));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_brotli_encoding_large() {
2019-12-20 08:50:07 +01:00
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(320_000)
2020-12-23 00:45:31 +01:00
.map(char::from)
2019-12-20 08:50:07 +01:00
.collect::<String>();
let srv = actix_test::start_with(actix_test::config().h1(), || {
2019-12-12 17:28:47 +01:00
App::new().service(
web::resource("/")
.app_data(web::PayloadConfig::new(320_000))
2019-12-20 08:50:07 +01:00
.route(web::to(move |body: Bytes| {
HttpResponse::Ok().streaming(TestBody::new(body, 10240))
})),
2019-12-12 17:28:47 +01:00
)
2019-11-26 06:25:50 +01:00
});
let request = srv
.post("/")
2021-01-15 03:11:10 +01:00
.append_header((CONTENT_ENCODING, "br"))
2022-01-03 14:17:57 +01:00
.send_body(brotli::encode(&data));
let mut res = request.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2019-11-26 06:25:50 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().limit(320_000).await.unwrap();
2019-11-26 06:25:50 +01:00
assert_eq!(bytes, Bytes::from(data));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-03-26 23:14:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-12-12 17:28:47 +01:00
#[cfg(feature = "openssl")]
#[actix_rt::test]
async fn test_brotli_encoding_large_openssl() {
2022-01-03 14:17:57 +01:00
use actix_web::http::header;
2019-12-12 17:28:47 +01:00
let data = STR.repeat(10);
let srv =
actix_test::start_with(actix_test::config().openssl(openssl_config()), move || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok()
2022-01-03 14:17:57 +01:00
.encode_with(ContentEncoding::Identity)
.body(bytes)
})))
});
2019-03-02 07:51:32 +01:00
2022-01-03 14:17:57 +01:00
let mut res = srv
2019-12-12 17:28:47 +01:00
.post("/")
2022-01-03 14:17:57 +01:00
.append_header((header::CONTENT_ENCODING, "br"))
.send_body(brotli::encode(&data))
2019-12-12 17:28:47 +01:00
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::OK);
2019-03-02 07:51:32 +01:00
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
2019-12-12 17:28:47 +01:00
assert_eq!(bytes, Bytes::from(data));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-12-12 17:28:47 +01:00
}
2019-03-02 07:51:32 +01:00
2021-06-23 21:47:17 +02:00
#[cfg(feature = "rustls")]
mod plus_rustls {
2019-11-26 06:25:50 +01:00
use std::io::BufReader;
use rustls::{Certificate, PrivateKey, ServerConfig as RustlsServerConfig};
use rustls_pemfile::{certs, pkcs8_private_keys};
2019-11-26 06:25:50 +01:00
use super::*;
2019-12-12 17:28:47 +01:00
fn tls_config() -> RustlsServerConfig {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
2019-11-26 06:25:50 +01:00
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
2019-11-26 06:25:50 +01:00
let cert_chain = certs(cert_file)
.unwrap()
.into_iter()
.map(Certificate)
.collect();
let mut keys = pkcs8_private_keys(key_file).unwrap();
2019-11-26 06:25:50 +01:00
RustlsServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
.with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
.unwrap()
}
2019-11-26 06:25:50 +01:00
#[actix_rt::test]
async fn test_reading_deflate_encoding_large_random_rustls() {
let data = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(160_000)
.map(char::from)
.collect::<String>();
let srv = actix_test::start_with(actix_test::config().rustls(tls_config()), || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok()
2022-01-03 14:17:57 +01:00
.encode_with(ContentEncoding::Identity)
.body(bytes)
})))
});
let req = srv
.post("/")
.insert_header((actix_web::http::header::CONTENT_ENCODING, "deflate"))
2022-01-03 14:17:57 +01:00
.send_stream(TestBody::new(Bytes::from(deflate::encode(&data)), 1024));
2022-01-03 14:17:57 +01:00
let mut res = req.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2022-01-03 14:17:57 +01:00
let bytes = res.body().await.unwrap();
assert_eq!(bytes.len(), data.len());
assert_eq!(bytes, Bytes::from(data));
2021-11-15 05:03:33 +01:00
srv.stop().await;
}
2019-03-30 00:28:19 +01:00
}
2019-03-02 07:51:32 +01:00
2021-01-17 06:19:32 +01:00
#[actix_rt::test]
async fn test_server_cookies() {
use actix_web::http;
2021-01-17 06:19:32 +01:00
let srv = actix_test::start(|| {
2021-01-17 06:19:32 +01:00
App::new().default_service(web::to(|| {
HttpResponse::Ok()
.cookie(
CookieBuilder::new("first", "first_value")
2021-01-17 06:19:32 +01:00
.http_only(true)
.finish(),
)
.cookie(Cookie::new("second", "first_value"))
.cookie(Cookie::new("second", "second_value"))
2021-01-17 06:19:32 +01:00
.finish()
}))
});
2021-02-13 16:08:43 +01:00
let req = srv.get("/");
let res = req.send().await.unwrap();
assert!(res.status().is_success());
let first_cookie = CookieBuilder::new("first", "first_value")
2021-01-17 06:19:32 +01:00
.http_only(true)
.finish();
let second_cookie = Cookie::new("second", "second_value");
2021-01-17 06:19:32 +01:00
let cookies = res.cookies().expect("To have cookies");
assert_eq!(cookies.len(), 2);
if cookies[0] == first_cookie {
assert_eq!(cookies[1], second_cookie);
} else {
assert_eq!(cookies[0], second_cookie);
assert_eq!(cookies[1], first_cookie);
}
let first_cookie = first_cookie.to_string();
let second_cookie = second_cookie.to_string();
// Check that we have exactly two instances of raw cookie headers
let cookies = res
.headers()
.get_all(http::header::SET_COOKIE)
.map(|header| header.to_str().expect("To str").to_string())
.collect::<Vec<_>>();
assert_eq!(cookies.len(), 2);
if cookies[0] == first_cookie {
assert_eq!(cookies[1], second_cookie);
} else {
assert_eq!(cookies[0], second_cookie);
assert_eq!(cookies[1], first_cookie);
}
2021-11-15 05:03:33 +01:00
srv.stop().await;
2021-01-17 06:19:32 +01:00
}
2019-03-02 07:51:32 +01:00
2019-12-12 17:28:47 +01:00
#[actix_rt::test]
async fn test_slow_request() {
use std::net;
2019-03-02 07:51:32 +01:00
let srv = actix_test::start_with(actix_test::config().client_timeout(200), || {
App::new().service(web::resource("/").route(web::to(HttpResponse::Ok)))
2019-12-12 17:28:47 +01:00
});
2019-03-02 07:51:32 +01:00
2019-12-12 17:28:47 +01:00
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
let mut data = String::new();
let _ = stream.read_to_string(&mut data);
assert!(data.starts_with("HTTP/1.1 408 Request Timeout"));
2019-03-02 07:51:32 +01:00
2019-12-12 17:28:47 +01:00
let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
let _ = stream.write_all(b"GET /test/tests/test HTTP/1.1\r\n");
let mut data = String::new();
let _ = stream.read_to_string(&mut data);
assert!(data.starts_with("HTTP/1.1 408 Request Timeout"));
2021-11-15 05:03:33 +01:00
srv.stop().await;
2019-12-12 17:28:47 +01:00
}
2019-03-02 07:51:32 +01:00
#[actix_rt::test]
async fn test_normalize() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new()
.wrap(NormalizePath::new(TrailingSlash::Trim))
2021-05-15 02:13:33 +02:00
.service(web::resource("/one").route(web::to(HttpResponse::Ok)))
});
2022-01-03 14:17:57 +01:00
let res = srv.get("/one/").send().await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
2021-11-15 05:03:33 +01:00
srv.stop().await
}
// allow deprecated App::data
#[allow(deprecated)]
#[actix_rt::test]
async fn test_data_drop() {
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
struct TestData(Arc<AtomicUsize>);
impl TestData {
fn new(inner: Arc<AtomicUsize>) -> Self {
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Clone for TestData {
fn clone(&self) -> Self {
let inner = self.0.clone();
let _ = inner.fetch_add(1, Ordering::SeqCst);
Self(inner)
}
}
impl Drop for TestData {
fn drop(&mut self) {
self.0.fetch_sub(1, Ordering::SeqCst);
}
}
let num = Arc::new(AtomicUsize::new(0));
let data = TestData::new(num.clone());
assert_eq!(num.load(Ordering::SeqCst), 1);
let srv = actix_test::start(move || {
let data = data.clone();
App::new()
.data(data)
.service(web::resource("/").to(|_data: web::Data<TestData>| async { "ok" }))
});
assert!(srv.get("/").send().await.unwrap().status().is_success());
srv.stop().await;
assert_eq!(num.load(Ordering::SeqCst), 0);
}
#[actix_rt::test]
async fn test_accept_encoding_no_match() {
let srv = actix_test::start_with(actix_test::config().h1(), || {
App::new()
.wrap(Compress::default())
.service(web::resource("/").route(web::to(move || HttpResponse::Ok().finish())))
});
2022-01-03 14:17:57 +01:00
let mut res = srv
.get("/")
2022-01-03 14:17:57 +01:00
.insert_header((ACCEPT_ENCODING, "xz, identity;q=0"))
.no_decompress()
.send()
.await
.unwrap();
2022-01-03 14:17:57 +01:00
assert_eq!(res.status(), StatusCode::NOT_ACCEPTABLE);
assert_eq!(res.headers().get(CONTENT_ENCODING), None);
let bytes = res.body().await.unwrap();
// body should contain the supported encodings
assert!(!bytes.is_empty());
2021-11-15 05:03:33 +01:00
srv.stop().await;
}