1
0
mirror of https://github.com/actix/examples synced 2025-05-14 00:43:53 +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
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
7 changed files with 201 additions and 47 deletions

View File

@ -6,14 +6,24 @@ column_width = 100
[[rule]]
include = ["**/Cargo.toml"]
keys = ["dependencies", "*-dependencies"]
[rule.formatting]
reorder_keys = true
keys = [
"dependencies",
"*-dependencies",
"workspace.dependencies",
"workspace.*-dependencies",
"target.*.dependencies",
"target.*.*-dependencies",
]
formatting.reorder_keys = true
[[rule]]
include = ["**/Cargo.toml"]
keys = ["dependencies.*", "*-dependencies.*"]
[rule.formatting]
reorder_keys = false
keys = [
"dependencies.*",
"*-dependencies.*",
"workspace.dependencies.*",
"workspace.*-dependencies.*",
"target.*.dependencies",
"target.*.*-dependencies",
]
formatting.reorder_keys = false

141
Cargo.lock generated
View File

@ -1120,7 +1120,7 @@ dependencies = [
"log",
"mime",
"rustls 0.23.27",
"webpki-roots 0.26.11",
"rustls-platform-verifier",
]
[[package]]
@ -2037,6 +2037,12 @@ dependencies = [
"shlex",
]
[[package]]
name = "cesu8"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
[[package]]
name = "cexpr"
version = "0.6.0"
@ -4519,6 +4525,28 @@ dependencies = [
"syn 2.0.101",
]
[[package]]
name = "jni"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
dependencies = [
"cesu8",
"cfg-if",
"combine",
"jni-sys",
"log",
"thiserror 1.0.69",
"walkdir",
"windows-sys 0.45.0",
]
[[package]]
name = "jni-sys"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.33"
@ -7026,6 +7054,33 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-platform-verifier"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1"
dependencies = [
"core-foundation 0.10.0",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls 0.23.27",
"rustls-native-certs 0.8.1",
"rustls-platform-verifier-android",
"rustls-webpki 0.103.3",
"security-framework 3.2.0",
"security-framework-sys",
"webpki-root-certs 0.26.11",
"windows-sys 0.59.0",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
@ -9458,6 +9513,24 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-root-certs"
version = "0.26.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e"
dependencies = [
"webpki-root-certs 1.0.0",
]
[[package]]
name = "webpki-root-certs"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01a83f7e1a9f8712695c03eabe9ed3fbca0feff0152f33f12593e5a6303cb1a4"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "webpki-roots"
version = "0.25.4"
@ -9725,6 +9798,15 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
@ -9752,6 +9834,21 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
@ -9799,6 +9896,12 @@ dependencies = [
"windows_x86_64_msvc 0.53.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@ -9817,6 +9920,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@ -9835,6 +9944,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@ -9865,6 +9980,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@ -9883,6 +10004,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@ -9901,6 +10028,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@ -9919,6 +10052,12 @@ version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"

View File

@ -97,13 +97,14 @@ actix-ws = "0.3"
awc = "3.7"
chrono = { version = "0.4.30", features = ["serde"] }
color-eyre = "0.6"
derive_more = "2"
dotenvy = "0.15"
env_logger = "0.11"
eyre = { version = "0.6", default-features = false, features = ["auto-install", "track-caller"] }
color-eyre = "0.6"
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
log = "0.4"
mime = "0.3"
notify = "8"
openssl = { version = "0.10.60", features = ["v110"] }
parking_lot = "0.12"
@ -114,11 +115,11 @@ reqwest = { version = "0.12", features = ["json", "stream"] }
rustls = "0.23"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
time = "0.3"
temp-env = "0.3"
time = "0.3"
tokio = { version = "1.24.2", features = ["sync", "io-util"] }
tokio-util = "0.7.4"
tokio-stream = "0.1.1"
tokio-util = "0.7.4"
tracing = "0.1.30"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
uuid = { version = "1.6", features = ["v4", "v7", "serde"] }

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
}