@@ -10,7 +10,7 @@ use crate::webserver::{
1010use anyhow:: { anyhow, Context } ;
1111use futures_util:: StreamExt ;
1212use mime_guess:: mime;
13- use std:: { borrow:: Cow , ffi:: OsStr , str:: FromStr } ;
13+ use std:: { borrow:: Cow , ffi:: OsStr , str:: FromStr , sync :: OnceLock } ;
1414
1515super :: 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
198207pub ( crate ) async fn hash_password ( password : Option < String > ) -> anyhow:: Result < Option < String > > {
0 commit comments