1
0
mirror of https://github.com/actix/examples synced 2025-06-26 17:17:42 +02:00

feat: use rustls best practice for clients

This commit is contained in:
Rob Ede
2025-05-12 03:36:54 +01:00
parent c39ea70fa8
commit dfce64475b
7 changed files with 201 additions and 47 deletions

View File

@ -4,11 +4,10 @@ edition.workspace = true
rust-version.workspace = true
[dependencies]
actix-web.workspace = true
actix-web = { workspace = true }
awc = { workspace = true, features = ["rustls-0_23"] }
env_logger.workspace = true
log.workspace = true
mime = "0.3"
rustls.workspace = true
webpki-roots = "0.26"
env_logger = { workspace = true }
log = { workspace = true }
mime = { workspace = true }
rustls = { workspace = true }
rustls-platform-verifier = "0.5"

View File

@ -1,14 +1,13 @@
use std::{sync::Arc, time::Instant};
use actix_web::{App, HttpResponse, HttpServer, get, middleware, web::Data};
use actix_web::{App, HttpResponse, HttpServer, get, middleware, web::ThinData};
use awc::{Client, Connector, http::header};
use rustls::{ClientConfig, RootCertStore};
const MAP_URL: &str =
"https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg";
#[get("/")]
async fn fetch_image(client: Data<Client>) -> HttpResponse {
async fn fetch_image(client: ThinData<Client>) -> HttpResponse {
let start = Instant::now();
let mut res = client.get(MAP_URL).send().await.unwrap();
@ -20,13 +19,14 @@ async fn fetch_image(client: Data<Client>) -> HttpResponse {
let payload = res
.body()
// expected image is larger than default body limit
.limit(20_000_000) // 20MB
// expected image is larger than default body limit, set up a higher
// limit of 20 MB
.limit(20_000_000)
.await
.unwrap();
log::info!(
"it took {}ms to download image to memory",
"It took {}ms to download image to memory",
start.elapsed().as_millis()
);
@ -41,7 +41,7 @@ async fn main() -> std::io::Result<()> {
let client_tls_config = Arc::new(rustls_config());
log::info!("starting HTTP server at http://localhost:8080");
log::info!("Starting HTTP server at http://localhost:8080");
HttpServer::new(move || {
// create client _inside_ `HttpServer::new` closure to have one per worker thread
@ -53,9 +53,9 @@ async fn main() -> std::io::Result<()> {
.finish();
App::new()
.wrap(middleware::Logger::default())
.app_data(Data::new(client))
.app_data(ThinData(client))
.service(fetch_image)
.wrap(middleware::Logger::default())
})
.bind(("127.0.0.1", 8080))?
.workers(2)
@ -63,15 +63,15 @@ async fn main() -> std::io::Result<()> {
.await
}
/// Create simple rustls client config from root certificates.
fn rustls_config() -> ClientConfig {
/// Create simple `rustls` client config.
fn rustls_config() -> rustls::ClientConfig {
use rustls_platform_verifier::ConfigVerifierExt as _;
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.unwrap();
let root_store = RootCertStore::from_iter(webpki_roots::TLS_SERVER_ROOTS.to_owned());
rustls::ClientConfig::builder()
.with_root_certificates(root_store)
.with_no_client_auth()
// The benefits of the platform verifier are clear; see:
// https://github.com/rustls/rustls-platform-verifier#readme
rustls::ClientConfig::with_platform_verifier()
}

View File

@ -6,6 +6,6 @@ rust-version.workspace = true
[dependencies]
actix-tls = { workspace = true, features = ["rustls-0_23"] }
actix-web = { workspace = true, features = ["rustls-0_23"] }
env_logger.workspace = true
log.workspace = true
rustls.workspace = true
env_logger = { workspace = true }
log = { workspace = true }
rustls = { workspace = true }

View File

@ -5,7 +5,8 @@ use std::{any::Any, net::SocketAddr, sync::Arc};
use actix_tls::accept::rustls_0_23::TlsStream;
use actix_web::{
App, HttpRequest, HttpResponse, HttpServer, Responder, dev::Extensions, rt::net::TcpStream, web,
App, HttpRequest, HttpResponse, HttpServer, Responder, dev::Extensions, middleware::Logger,
rt::net::TcpStream, web,
};
use log::info;
use rustls::{
@ -101,13 +102,17 @@ async fn main() -> std::io::Result<()> {
.with_single_cert(cert_chain, key_der)
.unwrap();
log::info!("starting HTTP server at http://localhost:8080 and https://localhost:8443");
log::info!("Starting HTTP server at http://localhost:8080 and https://localhost:8443");
HttpServer::new(|| App::new().default_service(web::to(route_whoami)))
.on_connect(get_client_cert)
.bind(("localhost", 8080))?
.bind_rustls_0_23(("localhost", 8443), config)?
.workers(1)
.run()
.await
HttpServer::new(|| {
App::new()
.default_service(web::to(route_whoami))
.wrap(Logger::default())
})
.on_connect(get_client_cert)
.bind(("localhost", 8080))?
.bind_rustls_0_23(("localhost", 8443), config)?
.workers(2)
.run()
.await
}