This commit is contained in:
Marat Safin 2019-07-28 11:55:29 +03:00
parent 607defac68
commit f387a8ceb8
6 changed files with 91 additions and 93 deletions

View File

@ -79,7 +79,9 @@ impl Connector<(), ()> {
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
config.set_protocols(&protos); config.set_protocols(&protos);
config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS); config
.root_store
.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
Arc::new(config) Arc::new(config)
} }
#[cfg(not(any(feature = "ssl", feature = "rust-tls")))] #[cfg(not(any(feature = "ssl", feature = "rust-tls")))]

View File

@ -1,24 +1,22 @@
#![cfg(feature = "rust-tls")] #![cfg(feature = "rust-tls")]
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::error::PayloadError;
use actix_http::http::header::{self, HeaderName, HeaderValue};
use actix_http::http::{Method, StatusCode, Version};
use actix_http::{body, error, Error, HttpService, Request, Response};
use actix_http_test::TestServer; use actix_http_test::TestServer;
use actix_server::ssl::RustlsAcceptor;
use actix_server_config::ServerConfig; use actix_server_config::ServerConfig;
use actix_service::{new_service_cfg, NewService}; use actix_service::{new_service_cfg, NewService};
use bytes::{Bytes, BytesMut}; use bytes::{Bytes, BytesMut};
use futures::future::{self, ok, Future}; use futures::future::{self, ok, Future};
use futures::stream::{once, Stream}; use futures::stream::{once, Stream};
use rustls::{internal::pemfile, NoClientAuth};
use actix_http::error::PayloadError;
use actix_http::{
body, error, http, http::header, Error, HttpService, Request, Response,
};
use std::fs::File; use std::fs::File;
use rustls::{internal::pemfile, NoClientAuth}; use std::io::{BufReader, Result};
use std::io::BufReader;
use std::sync::Arc; use std::sync::Arc;
use std::io::Result;
use actix_server::ssl::RustlsAcceptor
fn load_body<S>(stream: S) -> impl Future<Item = BytesMut, Error = PayloadError> fn load_body<S>(stream: S) -> impl Future<Item = BytesMut, Error = PayloadError>
where where
@ -35,10 +33,15 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> Result<RustlsAcceptor<T, ()>> {
// load ssl keys // load ssl keys
let mut key_file = BufReader::new(File::open("tests/key.pem").expect("key file")); let mut key_file = BufReader::new(File::open("tests/key.pem").expect("key file"));
let mut cert_file = BufReader::new(File::open("tests/cert.pem").expect("cert file")); let mut cert_file = BufReader::new(File::open("tests/cert.pem").expect("cert file"));
let key_der = pemfile::pkcs8_private_keys(&mut key_file).expect("key der").pop().expect("key not found"); let key_der = pemfile::pkcs8_private_keys(&mut key_file)
.expect("key der")
.pop()
.expect("key not found");
let cert_chain = pemfile::certs(&mut cert_file).expect("cert chain"); let cert_chain = pemfile::certs(&mut cert_file).expect("cert chain");
let mut builder = ServerConfig::new(Arc::new(NoClientAuth)); let mut builder = ServerConfig::new(Arc::new(NoClientAuth));
builder.set_single_cert(cert_chain, key_der).expect("set single cert"); builder
.set_single_cert(cert_chain, key_der)
.expect("set single cert");
let protos = vec![b"h2".to_vec()]; let protos = vec![b"h2".to_vec()];
builder.set_protocols(&protos); builder.set_protocols(&protos);
Ok(RustlsAcceptor::new(builder)) Ok(RustlsAcceptor::new(builder))
@ -74,7 +77,7 @@ fn test_h2_1() -> Result<()> {
HttpService::build() HttpService::build()
.finish(|req: Request| { .finish(|req: Request| {
assert!(req.peer_addr().is_some()); assert!(req.peer_addr().is_some());
assert_eq!(req.version(), http::Version::HTTP_2); assert_eq!(req.version(), Version::HTTP_2);
future::ok::<_, Error>(Response::Ok().finish()) future::ok::<_, Error>(Response::Ok().finish())
}) })
.map_err(|_| ()), .map_err(|_| ()),
@ -114,10 +117,6 @@ fn test_h2_body() -> Result<()> {
#[test] #[test]
fn test_h2_content_length() { fn test_h2_content_length() {
use actix_http::http::{
header::{HeaderName, HeaderValue},
StatusCode,
};
let rustls = ssl_acceptor().unwrap(); let rustls = ssl_acceptor().unwrap();
let mut srv = TestServer::new(move || { let mut srv = TestServer::new(move || {
@ -148,13 +147,13 @@ fn test_h2_content_length() {
{ {
for i in 0..4 { for i in 0..4 {
let req = srv let req = srv
.request(http::Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
let req = srv let req = srv
.request(http::Method::HEAD, srv.surl(&format!("/{}", i))) .request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
@ -162,7 +161,7 @@ fn test_h2_content_length() {
for i in 4..6 { for i in 4..6 {
let req = srv let req = srv
.request(http::Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), Some(&value)); assert_eq!(response.headers().get(&header), Some(&value));
@ -274,7 +273,7 @@ fn test_h2_head_empty() {
let response = srv.block_on(srv.shead("/").send()).unwrap(); let response = srv.block_on(srv.shead("/").send()).unwrap();
assert!(response.status().is_success()); assert!(response.status().is_success());
assert_eq!(response.version(), http::Version::HTTP_2); assert_eq!(response.version(), Version::HTTP_2);
{ {
let len = response let len = response

View File

@ -1,24 +1,19 @@
#![cfg(feature = "ssl")] #![cfg(feature = "ssl")]
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::error::{ErrorBadRequest, PayloadError};
use actix_http::http::header::{self, HeaderName, HeaderValue};
use actix_http::http::{Method, StatusCode, Version};
use actix_http::{body, Error, HttpService, Request, Response};
use actix_http_test::TestServer; use actix_http_test::TestServer;
use actix_server::ssl::OpensslAcceptor;
use actix_server_config::ServerConfig; use actix_server_config::ServerConfig;
use actix_service::{new_service_cfg, NewService}; use actix_service::{new_service_cfg, NewService};
use bytes::{Bytes, BytesMut};
use futures::future::{self, ok, Future};
use futures::stream::{once, Stream};
use actix_http::http::{
header::{HeaderName, HeaderValue},
StatusCode,
};
use actix_http::error::PayloadError; use bytes::{Bytes, BytesMut};
use actix_http::{ use futures::future::{ok, Future};
body, error, http, http::header, Error, HttpService, Request, Response, use futures::stream::{once, Stream};
}; use openssl::ssl::{AlpnError, SslAcceptor, SslFiletype, SslMethod};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, AlpnError};
use std::io::Result; use std::io::Result;
use actix_server::ssl::OpensslAcceptor;
fn load_body<S>(stream: S) -> impl Future<Item = BytesMut, Error = PayloadError> fn load_body<S>(stream: S) -> impl Future<Item = BytesMut, Error = PayloadError>
where where
@ -60,7 +55,7 @@ fn test_h2() -> Result<()> {
.map_err(|e| println!("Openssl error: {}", e)) .map_err(|e| println!("Openssl error: {}", e))
.and_then( .and_then(
HttpService::build() HttpService::build()
.h2(|_| future::ok::<_, Error>(Response::Ok().finish())) .h2(|_| ok::<_, Error>(Response::Ok().finish()))
.map_err(|_| ()), .map_err(|_| ()),
) )
}); });
@ -81,8 +76,8 @@ fn test_h2_1() -> Result<()> {
HttpService::build() HttpService::build()
.finish(|req: Request| { .finish(|req: Request| {
assert!(req.peer_addr().is_some()); assert!(req.peer_addr().is_some());
assert_eq!(req.version(), http::Version::HTTP_2); assert_eq!(req.version(), Version::HTTP_2);
future::ok::<_, Error>(Response::Ok().finish()) ok::<_, Error>(Response::Ok().finish())
}) })
.map_err(|_| ()), .map_err(|_| ()),
) )
@ -139,7 +134,7 @@ fn test_h2_content_length() {
StatusCode::OK, StatusCode::OK,
StatusCode::NOT_FOUND, StatusCode::NOT_FOUND,
]; ];
future::ok::<_, ()>(Response::new(statuses[indx])) ok::<_, ()>(Response::new(statuses[indx]))
}) })
.map_err(|_| ()), .map_err(|_| ()),
) )
@ -151,13 +146,13 @@ fn test_h2_content_length() {
{ {
for i in 0..4 { for i in 0..4 {
let req = srv let req = srv
.request(http::Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
let req = srv let req = srv
.request(http::Method::HEAD, srv.surl(&format!("/{}", i))) .request(Method::HEAD, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), None); assert_eq!(response.headers().get(&header), None);
@ -165,7 +160,7 @@ fn test_h2_content_length() {
for i in 4..6 { for i in 4..6 {
let req = srv let req = srv
.request(http::Method::GET, srv.surl(&format!("/{}", i))) .request(Method::GET, srv.surl(&format!("/{}", i)))
.send(); .send();
let response = srv.block_on(req).unwrap(); let response = srv.block_on(req).unwrap();
assert_eq!(response.headers().get(&header), Some(&value)); assert_eq!(response.headers().get(&header), Some(&value));
@ -205,7 +200,7 @@ fn test_h2_headers() {
TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ", TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST TEST ",
); );
} }
future::ok::<_, ()>(builder.body(data.clone())) ok::<_, ()>(builder.body(data.clone()))
}).map_err(|_| ())) }).map_err(|_| ()))
}); });
@ -248,7 +243,7 @@ fn test_h2_body2() {
.map_err(|e| println!("Openssl error: {}", e)) .map_err(|e| println!("Openssl error: {}", e))
.and_then( .and_then(
HttpService::build() HttpService::build()
.h2(|_| future::ok::<_, ()>(Response::Ok().body(STR))) .h2(|_| ok::<_, ()>(Response::Ok().body(STR)))
.map_err(|_| ()), .map_err(|_| ()),
) )
}); });
@ -277,13 +272,10 @@ fn test_h2_head_empty() {
let response = srv.block_on(srv.shead("/").send()).unwrap(); let response = srv.block_on(srv.shead("/").send()).unwrap();
assert!(response.status().is_success()); assert!(response.status().is_success());
assert_eq!(response.version(), http::Version::HTTP_2); assert_eq!(response.version(), Version::HTTP_2);
{ {
let len = response let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
} }
@ -314,10 +306,7 @@ fn test_h2_head_binary() {
assert!(response.status().is_success()); assert!(response.status().is_success());
{ {
let len = response let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
} }
@ -344,10 +333,7 @@ fn test_h2_head_binary2() {
assert!(response.status().is_success()); assert!(response.status().is_success());
{ {
let len = response let len = response.headers().get(header::CONTENT_LENGTH).unwrap();
.headers()
.get(http::header::CONTENT_LENGTH)
.unwrap();
assert_eq!(format!("{}", STR.len()), len.to_str().unwrap()); assert_eq!(format!("{}", STR.len()), len.to_str().unwrap());
} }
} }
@ -428,7 +414,7 @@ fn test_h2_response_http_error_handling() {
let broken_header = Bytes::from_static(b"\0\0\0"); let broken_header = Bytes::from_static(b"\0\0\0");
ok::<_, ()>( ok::<_, ()>(
Response::Ok() Response::Ok()
.header(http::header::CONTENT_TYPE, broken_header) .header(header::CONTENT_TYPE, broken_header)
.body(STR), .body(STR),
) )
}) })
@ -438,7 +424,7 @@ fn test_h2_response_http_error_handling() {
}); });
let response = srv.block_on(srv.sget("/").send()).unwrap(); let response = srv.block_on(srv.sget("/").send()).unwrap();
assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
// read response // read response
let bytes = srv.load_body(response).unwrap(); let bytes = srv.load_body(response).unwrap();
@ -455,13 +441,13 @@ fn test_h2_service_error() {
.map_err(|e| println!("Openssl error: {}", e)) .map_err(|e| println!("Openssl error: {}", e))
.and_then( .and_then(
HttpService::build() HttpService::build()
.h2(|_| Err::<Response, Error>(error::ErrorBadRequest("error"))) .h2(|_| Err::<Response, Error>(ErrorBadRequest("error")))
.map_err(|_| ()), .map_err(|_| ()),
) )
}); });
let response = srv.block_on(srv.sget("/").send()).unwrap(); let response = srv.block_on(srv.sget("/").send()).unwrap();
assert_eq!(response.status(), http::StatusCode::INTERNAL_SERVER_ERROR); assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
// read response // read response
let bytes = srv.load_body(response).unwrap(); let bytes = srv.load_body(response).unwrap();

View File

@ -1,15 +1,15 @@
#![cfg(feature = "rustls")] #![cfg(feature = "rustls")]
use rustls::{internal::pemfile, NoClientAuth, ClientConfig}; use rustls::{internal::pemfile, ClientConfig, NoClientAuth};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::fs::File; use std::fs::File;
use std::io::{BufReader, Result}; use std::io::{BufReader, Result};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use actix_server::ssl::RustlsAcceptor;
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::HttpService; use actix_http::HttpService;
use actix_http_test::TestServer; use actix_http_test::TestServer;
use actix_server::ssl::RustlsAcceptor;
use actix_service::{service_fn, NewService}; use actix_service::{service_fn, NewService};
use actix_web::http::Version; use actix_web::http::Version;
use actix_web::{web, App, HttpResponse}; use actix_web::{web, App, HttpResponse};
@ -18,11 +18,17 @@ fn ssl_acceptor<T: AsyncRead + AsyncWrite>() -> Result<RustlsAcceptor<T, ()>> {
use rustls::ServerConfig; use rustls::ServerConfig;
// load ssl keys // load ssl keys
let mut key_file = BufReader::new(File::open("../tests/key.pem").expect("key file")); let mut key_file = BufReader::new(File::open("../tests/key.pem").expect("key file"));
let mut cert_file = BufReader::new(File::open("../tests/cert.pem").expect("cert file")); let mut cert_file =
let key_der = pemfile::pkcs8_private_keys(&mut key_file).expect("key der").pop().expect("key not found"); BufReader::new(File::open("../tests/cert.pem").expect("cert file"));
let key_der = pemfile::pkcs8_private_keys(&mut key_file)
.expect("key der")
.pop()
.expect("key not found");
let cert_chain = pemfile::certs(&mut cert_file).expect("cert chain"); let cert_chain = pemfile::certs(&mut cert_file).expect("cert chain");
let mut builder = ServerConfig::new(Arc::new(NoClientAuth)); let mut builder = ServerConfig::new(Arc::new(NoClientAuth));
builder.set_single_cert(cert_chain, key_der).expect("set single cert"); builder
.set_single_cert(cert_chain, key_der)
.expect("set single cert");
let protos = vec![b"h2".to_vec()]; let protos = vec![b"h2".to_vec()];
builder.set_protocols(&protos); builder.set_protocols(&protos);
Ok(RustlsAcceptor::new(builder)) Ok(RustlsAcceptor::new(builder))
@ -32,11 +38,13 @@ mod danger {
pub struct NoCertificateVerification {} pub struct NoCertificateVerification {}
impl rustls::ServerCertVerifier for NoCertificateVerification { impl rustls::ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(&self, fn verify_server_cert(
&self,
_roots: &rustls::RootCertStore, _roots: &rustls::RootCertStore,
_presented_certs: &[rustls::Certificate], _presented_certs: &[rustls::Certificate],
_dns_name: webpki::DNSNameRef<'_>, _dns_name: webpki::DNSNameRef<'_>,
_ocsp: &[u8]) -> Result<rustls::ServerCertVerified, rustls::TLSError> { _ocsp: &[u8],
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
Ok(rustls::ServerCertVerified::assertion()) Ok(rustls::ServerCertVerified::assertion())
} }
} }
@ -54,11 +62,7 @@ fn test_connection_reuse_h2() {
num2.fetch_add(1, Ordering::Relaxed); num2.fetch_add(1, Ordering::Relaxed);
Ok(io) Ok(io)
}) })
.and_then( .and_then(rustls.clone().map_err(|e| println!("Rustls error: {}", e)))
rustls
.clone()
.map_err(|e| println!("Rustls error: {}", e)),
)
.and_then( .and_then(
HttpService::build() HttpService::build()
.h2(App::new() .h2(App::new()
@ -73,7 +77,9 @@ fn test_connection_reuse_h2() {
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
config.set_protocols(&protos); config.set_protocols(&protos);
config.dangerous().set_certificate_verifier(Arc::new(danger::NoCertificateVerification{})); config
.dangerous()
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification {}));
let client = awc::Client::build() let client = awc::Client::build()
.connector(awc::Connector::new().ssl(Arc::new(config)).finish()) .connector(awc::Connector::new().ssl(Arc::new(config)).finish())

View File

@ -1,14 +1,14 @@
#![cfg(feature = "ssl")] #![cfg(feature = "ssl")]
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod, SslConnector, SslVerifyMode}; use openssl::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod, SslVerifyMode};
use actix_server::ssl::OpensslAcceptor;
use std::io::Result;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::io::Result;
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::HttpService; use actix_http::HttpService;
use actix_http_test::TestServer; use actix_http_test::TestServer;
use actix_server::ssl::OpensslAcceptor;
use actix_service::{service_fn, NewService}; use actix_service::{service_fn, NewService};
use actix_web::http::Version; use actix_web::http::Version;
use actix_web::{web, App, HttpResponse}; use actix_web::{web, App, HttpResponse};

View File

@ -67,18 +67,20 @@ where
R: IntoFuture, R: IntoFuture,
{ {
RT.with(move |rt| rt.borrow_mut().get_mut().block_on(lazy(f))) RT.with(move |rt| rt.borrow_mut().get_mut().block_on(lazy(f)))
} pub struct NoCertificateVerification {} }
#[cfg(feature = "rust-tls")] #[cfg(feature = "rust-tls")]
mod danger { mod danger {
pub struct NoCertificateVerification {} pub struct NoCertificateVerification {}
impl rustls::ServerCertVerifier for NoCertificateVerification { impl rustls::ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(&self, fn verify_server_cert(
&self,
_roots: &rustls::RootCertStore, _roots: &rustls::RootCertStore,
_presented_certs: &[rustls::Certificate], _presented_certs: &[rustls::Certificate],
_dns_name: webpki::DNSNameRef<'_>, _dns_name: webpki::DNSNameRef<'_>,
_ocsp: &[u8]) -> Result<rustls::ServerCertVerified, rustls::TLSError> { _ocsp: &[u8],
) -> Result<rustls::ServerCertVerified, rustls::TLSError> {
Ok(rustls::ServerCertVerified::assertion()) Ok(rustls::ServerCertVerified::assertion())
} }
} }
@ -174,7 +176,9 @@ impl TestServer {
let mut config = ClientConfig::new(); let mut config = ClientConfig::new();
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()]; let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
config.set_protocols(&protos); config.set_protocols(&protos);
config.dangerous().set_certificate_verifier(Arc::new(danger::NoCertificateVerification{})); config.dangerous().set_certificate_verifier(Arc::new(
danger::NoCertificateVerification {},
));
Connector::new() Connector::new()
.conn_lifetime(time::Duration::from_secs(0)) .conn_lifetime(time::Duration::from_secs(0))
@ -194,9 +198,10 @@ impl TestServer {
Ok::<Client, ()>(Client::build().connector(connector).finish()) Ok::<Client, ()>(Client::build().connector(connector).finish())
})) }))
.unwrap(); .unwrap();
rt.block_on(lazy(|| rt.block_on(lazy(
Ok::<_, ()>(actix_connect::start_default_resolver()) || Ok::<_, ()>(actix_connect::start_default_resolver()),
)).unwrap(); ))
.unwrap();
System::set_current(system); System::set_current(system);
TestServerRuntime { addr, rt, client } TestServerRuntime { addr, rt, client }
} }