1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-11 01:39:33 +00:00

revive commented out tests (#1912)

This commit is contained in:
Rob Ede 2021-01-17 05:19:32 +00:00 committed by GitHub
parent 1c95fc2654
commit ee10148444
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 243 additions and 222 deletions

View file

@ -6,6 +6,7 @@
* `ResponseBuilder::insert_header` method which allows using typed headers. [#1869]
* `ResponseBuilder::append_header` method which allows using typed headers. [#1869]
* `TestRequest::insert_header` method which allows using typed headers. [#1869]
* `ContentEncoding` implements all necessary header traits. [#1912]
### Changed
* `ResponseBuilder::content_type` now takes an `impl IntoHeaderValue` to support using typed
@ -24,6 +25,7 @@
[#1869]: https://github.com/actix/actix-web/pull/1869
[#1894]: https://github.com/actix/actix-web/pull/1894
[#1904]: https://github.com/actix/actix-web/pull/1904
[#1912]: https://github.com/actix/actix-web/pull/1912
## 3.0.0-beta.1 - 2021-01-07

View file

@ -1,3 +1,13 @@
use std::{convert::Infallible, str::FromStr};
use http::header::InvalidHeaderValue;
use crate::{
error::ParseError,
header::{self, from_one_raw_str, Header, HeaderName, HeaderValue, IntoHeaderValue},
HttpMessage,
};
/// Represents a supported content encoding.
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum ContentEncoding {
@ -47,6 +57,20 @@ impl ContentEncoding {
}
}
impl Default for ContentEncoding {
fn default() -> Self {
Self::Identity
}
}
impl FromStr for ContentEncoding {
type Err = Infallible;
fn from_str(val: &str) -> Result<Self, Self::Err> {
Ok(Self::from(val))
}
}
impl From<&str> for ContentEncoding {
fn from(val: &str) -> ContentEncoding {
let val = val.trim();
@ -58,7 +82,25 @@ impl From<&str> for ContentEncoding {
} else if val.eq_ignore_ascii_case("deflate") {
ContentEncoding::Deflate
} else {
ContentEncoding::Identity
ContentEncoding::default()
}
}
}
impl IntoHeaderValue for ContentEncoding {
type Error = InvalidHeaderValue;
fn try_into_value(self) -> Result<http::HeaderValue, Self::Error> {
Ok(HeaderValue::from_static(self.as_str()))
}
}
impl Header for ContentEncoding {
fn name() -> HeaderName {
header::CONTENT_ENCODING
}
fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
from_one_raw_str(msg.headers().get(Self::name()))
}
}

View file

@ -67,8 +67,10 @@ actix-http-test = { version = "3.0.0-beta.1", features = ["openssl"] }
actix-utils = "3.0.0-beta.1"
actix-server = "2.0.0-beta.2"
actix-tls = { version = "3.0.0-beta.2", features = ["openssl", "rustls"] }
brotli2 = "0.3.2"
flate2 = "1.0.13"
futures-util = { version = "0.3.7", default-features = false }
env_logger = "0.7"
rcgen = "0.8"
webpki = "0.21"

View file

@ -9,17 +9,20 @@ use bytes::Bytes;
use flate2::read::GzDecoder;
use flate2::write::GzEncoder;
use flate2::Compression;
use futures_util::future::ok;
use futures_util::{future::ok, stream};
use rand::Rng;
use actix_http::HttpService;
use actix_http::{
http::{self, StatusCode},
HttpService,
};
use actix_http_test::test_server;
use actix_service::{map_config, pipeline_factory};
use actix_web::dev::{AppConfig, BodyEncoding};
use actix_web::http::Cookie;
use actix_web::middleware::Compress;
use actix_web::{
http::header, test, web, App, Error, HttpMessage, HttpRequest, HttpResponse,
dev::{AppConfig, BodyEncoding},
http::{header, Cookie},
middleware::Compress,
test, web, App, Error, HttpMessage, HttpRequest, HttpResponse,
};
use awc::error::SendRequestError;
@ -557,117 +560,94 @@ async fn test_client_brotli_encoding_large_random() {
assert_eq!(bytes, Bytes::from(data));
}
// TODO: why is test ignored
// #[actix_rt::test]
// async fn test_client_deflate_encoding() {
// let srv = test::TestServer::start(|app| {
// app.handler(|req: &HttpRequest| {
// req.body()
// .and_then(|bytes: Bytes| {
// Ok(HttpResponse::Ok()
// .content_encoding(http::ContentEncoding::Br)
// .body(bytes))
// })
// .responder()
// })
// });
#[actix_rt::test]
async fn test_client_deflate_encoding() {
let srv = test::start(|| {
App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok()
.encoding(http::ContentEncoding::Br)
.body(body)
}))
});
// // client request
// let request = srv
// .post()
// .content_encoding(http::ContentEncoding::Deflate)
// .body(STR)
// .unwrap();
// let response = srv.execute(request.send()).unwrap();
// assert!(response.status().is_success());
let req = srv.post("/").send_body(STR);
// // read response
// let bytes = srv.execute(response.body()).unwrap();
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
// }
let mut res = req.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
// TODO: why is test ignored
// #[actix_rt::test]
// async fn test_client_deflate_encoding_large_random() {
// let data = rand::thread_rng()
// .sample_iter(&rand::distributions::Alphanumeric)
// .take(70_000)
// .collect::<String>();
let bytes = res.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
// let srv = test::TestServer::start(|app| {
// app.handler(|req: &HttpRequest| {
// req.body()
// .and_then(|bytes: Bytes| {
// Ok(HttpResponse::Ok()
// .content_encoding(http::ContentEncoding::Br)
// .body(bytes))
// })
// .responder()
// })
// });
#[actix_rt::test]
async fn test_client_deflate_encoding_large_random() {
let data = rand::thread_rng()
.sample_iter(rand::distributions::Alphanumeric)
.map(char::from)
.take(70_000)
.collect::<String>();
// // client request
// let request = srv
// .post()
// .content_encoding(http::ContentEncoding::Deflate)
// .body(data.clone())
// .unwrap();
// let response = srv.execute(request.send()).unwrap();
// assert!(response.status().is_success());
let srv = test::start(|| {
App::new().default_service(web::to(|body: Bytes| {
HttpResponse::Ok()
.encoding(http::ContentEncoding::Br)
.body(body)
}))
});
// // read response
// let bytes = srv.execute(response.body()).unwrap();
// assert_eq!(bytes, Bytes::from(data));
// }
let req = srv.post("/").send_body(data.clone());
// TODO: why is test ignored
// #[actix_rt::test]
// async fn test_client_streaming_explicit() {
// let srv = test::TestServer::start(|app| {
// app.handler(|req: &HttpRequest| {
// req.body()
// .map_err(Error::from)
// .and_then(|body| {
// Ok(HttpResponse::Ok()
// .chunked()
// .content_encoding(http::ContentEncoding::Identity)
// .body(body))
// })
// .responder()
// })
// });
let mut res = req.await.unwrap();
let bytes = res.body().await.unwrap();
// let body = once(Ok(Bytes::from_static(STR.as_ref())));
assert_eq!(res.status(), StatusCode::OK);
assert_eq!(bytes, Bytes::from(data));
}
// let request = srv.get("/").body(Body::Streaming(Box::new(body))).unwrap();
// let response = srv.execute(request.send()).unwrap();
// assert!(response.status().is_success());
#[actix_rt::test]
async fn test_client_streaming_explicit() {
let srv = test::start(|| {
App::new().default_service(web::to(|body: web::Payload| {
HttpResponse::Ok()
.encoding(http::ContentEncoding::Identity)
.streaming(body)
}))
});
// // read response
// let bytes = srv.execute(response.body()).unwrap();
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
// }
let body = stream::once(async {
Ok::<_, actix_http::Error>(Bytes::from_static(STR.as_bytes()))
});
let req = srv.post("/").send_stream(Box::pin(body));
// TODO: why is test ignored
// #[actix_rt::test]
// async fn test_body_streaming_implicit() {
// let srv = test::TestServer::start(|app| {
// app.handler(|_| {
// let body = once(Ok(Bytes::from_static(STR.as_ref())));
// HttpResponse::Ok()
// .content_encoding(http::ContentEncoding::Gzip)
// .body(Body::Streaming(Box::new(body)))
// })
// });
let mut res = req.await.unwrap();
assert!(res.status().is_success());
// let request = srv.get("/").finish().unwrap();
// let response = srv.execute(request.send()).unwrap();
// assert!(response.status().is_success());
let bytes = res.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
// // read response
// let bytes = srv.execute(response.body()).unwrap();
// assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
// }
#[actix_rt::test]
async fn test_body_streaming_implicit() {
let srv = test::start(|| {
App::new().default_service(web::to(|| {
let body = stream::once(async {
Ok::<_, actix_http::Error>(Bytes::from_static(STR.as_bytes()))
});
HttpResponse::Ok()
.encoding(http::ContentEncoding::Gzip)
.streaming(Box::pin(body))
}))
});
let req = srv.get("/").send();
let mut res = req.await.unwrap();
assert!(res.status().is_success());
let bytes = res.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(STR.as_ref()));
}
#[actix_rt::test]
async fn test_client_cookie_handling() {
@ -738,36 +718,35 @@ async fn test_client_cookie_handling() {
assert_eq!(c2, cookie2);
}
// TODO: why is test ignored
// #[actix_rt::test]
// fn client_read_until_eof() {
// let addr = test::TestServer::unused_addr();
#[actix_rt::test]
async fn client_unread_response() {
let addr = test::unused_addr();
// thread::spawn(move || {
// let lst = net::TcpListener::bind(addr).unwrap();
std::thread::spawn(move || {
let lst = std::net::TcpListener::bind(addr).unwrap();
// for stream in lst.incoming() {
// let mut stream = stream.unwrap();
// let mut b = [0; 1000];
// let _ = stream.read(&mut b).unwrap();
// let _ = stream
// .write_all(b"HTTP/1.1 200 OK\r\nconnection: close\r\n\r\nwelcome!");
// }
// });
for stream in lst.incoming() {
let mut stream = stream.unwrap();
let mut b = [0; 1000];
let _ = stream.read(&mut b).unwrap();
let _ = stream.write_all(
b"HTTP/1.1 200 OK\r\n\
connection: close\r\n\
\r\n\
welcome!",
);
}
});
// let mut sys = actix::System::new("test");
// client request
let req = awc::Client::new().get(format!("http://{}/", addr).as_str());
let mut res = req.send().await.unwrap();
assert!(res.status().is_success());
// // client request
// let req = client::ClientRequest::get(format!("http://{}/", addr).as_str())
// .finish()
// .unwrap();
// let response = req.send().await.unwrap();
// assert!(response.status().is_success());
// // read response
// let bytes = response.body().await.unwrap();
// assert_eq!(bytes, Bytes::from_static(b"welcome!"));
// }
// awc does not read all bytes unless content-length is specified
let bytes = res.body().await.unwrap();
assert_eq!(bytes, Bytes::from_static(b""));
}
#[actix_rt::test]
async fn client_basic_auth() {

View file

@ -1,58 +1,57 @@
#![cfg(feature = "rustls")]
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
extern crate rust_tls as rustls;
use std::{
io::BufReader,
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
};
use actix_http::HttpService;
use actix_http_test::test_server;
use actix_service::{map_config, pipeline_factory, ServiceFactoryExt};
use actix_web::http::Version;
use actix_web::{dev::AppConfig, web, App, HttpResponse};
use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
use futures_util::future::ok;
use open_ssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslVerifyMode};
use rust_tls::ClientConfig;
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use rustls::{ClientConfig, NoClientAuth, ServerConfig};
#[allow(unused)]
fn ssl_acceptor() -> SslAcceptor {
// load ssl keys
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
builder.set_verify_callback(SslVerifyMode::NONE, |_, _| true);
builder
.set_private_key_file("../tests/key.pem", SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file("../tests/cert.pem")
.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(open_ssl::ssl::AlpnError::NOACK)
}
});
builder.set_alpn_protos(b"\x02h2").unwrap();
builder.build()
fn tls_config() -> ServerConfig {
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 mut config = ServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
let cert_chain = certs(cert_file).unwrap();
let mut keys = pkcs8_private_keys(key_file).unwrap();
config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
config
}
mod danger {
pub struct NoCertificateVerification {}
pub struct NoCertificateVerification;
impl rust_tls::ServerCertVerifier for NoCertificateVerification {
impl rustls::ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(
&self,
_roots: &rust_tls::RootCertStore,
_presented_certs: &[rust_tls::Certificate],
_roots: &rustls::RootCertStore,
_presented_certs: &[rustls::Certificate],
_dns_name: webpki::DNSNameRef<'_>,
_ocsp: &[u8],
) -> Result<rust_tls::ServerCertVerified, rust_tls::TLSError> {
Ok(rust_tls::ServerCertVerified::assertion())
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
Ok(rustls::ServerCertVerified::assertion())
}
}
}
// TODO: why is test ignored
// #[actix_rt::test]
async fn _test_connection_reuse_h2() {
#[actix_rt::test]
async fn test_connection_reuse_h2() {
let num = Arc::new(AtomicUsize::new(0));
let num2 = num.clone();
@ -69,19 +68,19 @@ async fn _test_connection_reuse_h2() {
.service(web::resource("/").route(web::to(HttpResponse::Ok))),
|_| AppConfig::default(),
))
.openssl(ssl_acceptor())
.rustls(tls_config())
.map_err(|_| ()),
)
})
.await;
// disable ssl verification
// disable TLS verification
let mut config = ClientConfig::new();
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
config.set_protocols(&protos);
config
.dangerous()
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification {}));
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification));
let client = awc::Client::builder()
.connector(awc::Connector::new().rustls(Arc::new(config)).finish())

View file

@ -16,6 +16,7 @@ use actix_http::{
Error,
};
use actix_service::{Service, Transform};
use futures_core::ready;
use futures_util::future::{ok, Ready};
use pin_project::pin_project;
@ -131,7 +132,7 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
match futures_util::ready!(this.fut.poll(cx)) {
match ready!(this.fut.poll(cx)) {
Ok(resp) => {
let enc = if let Some(enc) = resp.response().get_encoding() {
enc

View file

@ -800,62 +800,58 @@ async fn test_reading_deflate_encoding_large_random_rustls() {
assert_eq!(bytes, Bytes::from(data));
}
// TODO: why is test ignored
// #[test]
// fn test_server_cookies() {
// use actix_web::http;
#[actix_rt::test]
async fn test_server_cookies() {
use actix_web::{http, HttpMessage};
// let srv = test::TestServer::with_factory(|| {
// App::new().resource("/", |r| {
// r.f(|_| {
// HttpResponse::Ok()
// .cookie(
// http::CookieBuilder::new("first", "first_value")
// .http_only(true)
// .finish(),
// )
// .cookie(http::Cookie::new("second", "first_value"))
// .cookie(http::Cookie::new("second", "second_value"))
// .finish()
// })
// })
// });
let srv = test::start(|| {
App::new().default_service(web::to(|| {
HttpResponse::Ok()
.cookie(
http::CookieBuilder::new("first", "first_value")
.http_only(true)
.finish(),
)
.cookie(http::Cookie::new("second", "first_value"))
.cookie(http::Cookie::new("second", "second_value"))
.finish()
}))
});
// let first_cookie = http::CookieBuilder::new("first", "first_value")
// .http_only(true)
// .finish();
// let second_cookie = http::Cookie::new("second", "second_value");
let first_cookie = http::CookieBuilder::new("first", "first_value")
.http_only(true)
.finish();
let second_cookie = http::Cookie::new("second", "second_value");
// let request = srv.get("/").finish().unwrap();
// let response = srv.execute(request.send()).unwrap();
// assert!(response.status().is_success());
let req = srv.get("/");
let res = req.send().await.unwrap();
assert!(res.status().is_success());
// let cookies = response.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 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 = response
// .headers()
// .get_all(http::header::SET_COOKIE)
// .iter()
// .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);
// }
// }
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);
}
}
#[actix_rt::test]
async fn test_slow_request() {