Skip to content

Commit 2f7087c

Browse files
committed
avoid repetitively reloading system CA certificates
1 parent e8ba798 commit 2f7087c

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

src/webserver/content_security_policy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub struct ContentSecurityPolicy {
88
pub nonce: u64,
99
}
1010

11-
impl Default for ContentSecurityPolicy {
11+
impl Default for ContentSecurityPolicy {
1212
fn default() -> Self {
1313
Self { nonce: random() }
1414
}

src/webserver/database/sqlpage_functions/functions.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::webserver::{
1010
use anyhow::{anyhow, Context};
1111
use futures_util::StreamExt;
1212
use mime_guess::mime;
13-
use std::{borrow::Cow, ffi::OsStr, str::FromStr};
13+
use std::{borrow::Cow, ffi::OsStr, str::FromStr, sync::OnceLock};
1414

1515
super::function_definition_macro::sqlpage_functions! {
1616
basic_auth_password((&RequestInfo));
@@ -133,7 +133,7 @@ async fn fetch(
133133
http_request: super::http_fetch_request::HttpFetchRequest<'_>,
134134
) -> anyhow::Result<String> {
135135
use awc::http::Method;
136-
let client = make_http_client(&request.app_state.config);
136+
let client = make_http_client(&request.app_state.config)?;
137137

138138
let method = if let Some(method) = http_request.method {
139139
Method::from_str(&method)?
@@ -174,25 +174,34 @@ async fn fetch(
174174
Ok(response_str)
175175
}
176176

177-
fn make_http_client(config: &crate::app_config::AppConfig) -> awc::Client {
177+
static NATIVE_CERTS: OnceLock<std::io::Result<rustls::RootCertStore>> = OnceLock::new();
178+
179+
fn make_http_client(config: &crate::app_config::AppConfig) -> anyhow::Result<awc::Client> {
178180
let connector = if config.system_root_ca_certificates {
179-
let mut roots = rustls::RootCertStore::empty();
180-
for cert in rustls_native_certs::load_native_certs().expect("could not load platform certs")
181-
{
182-
roots.add(cert).unwrap();
183-
}
181+
let roots = NATIVE_CERTS
182+
.get_or_init(|| {
183+
let certs = rustls_native_certs::load_native_certs()?;
184+
let mut roots = rustls::RootCertStore::empty();
185+
for cert in certs {
186+
roots.add(cert.clone()).unwrap();
187+
}
188+
Ok(roots)
189+
})
190+
.as_ref()?;
191+
184192
let tls_conf = rustls::ClientConfig::builder()
185-
.with_root_certificates(roots)
193+
.with_root_certificates(roots.clone())
186194
.with_no_client_auth();
187195

188196
awc::Connector::new().rustls_0_22(std::sync::Arc::new(tls_conf))
189197
} else {
190198
awc::Connector::new()
191199
};
192-
awc::Client::builder()
200+
let client = awc::Client::builder()
193201
.connector(connector)
194202
.add_default_header((awc::http::header::USER_AGENT, env!("CARGO_PKG_NAME")))
195-
.finish()
203+
.finish();
204+
Ok(client)
196205
}
197206

198207
pub(crate) async fn hash_password(password: Option<String>) -> anyhow::Result<Option<String>> {

src/webserver/http.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,10 @@ pub async fn run_server(config: &AppConfig, state: AppState) -> anyhow::Result<(
599599
}
600600

601601
log_welcome_message(config);
602-
server.run().await.with_context(|| "Unable to start the application")
602+
server
603+
.run()
604+
.await
605+
.with_context(|| "Unable to start the application")
603606
}
604607

605608
fn log_welcome_message(config: &AppConfig) {

0 commit comments

Comments
 (0)