Repository: servo/servo
File: components/net/resource_thread.rs (Rust)

Code before:
};
use crate::cookie::ServoCookie;
use crate::cookie_storage::CookieStorage;
use crate::fetch::cors_cache::CorsCache;
use crate::fetch::fetch_params::FetchParams;
use crate::fetch::methods::{CancellationListener, FetchContext, WebSocketChannel, fetch};
use crate::filemanager_thread::FileManager;
use crate::hsts::{self, HstsList};
use crate::http_cache::HttpCache;
use crate::http_loader::{HttpState, http_redirect_fetch};
use crate::protocols::ProtocolRegistry;
use crate::request_interceptor::RequestInterceptor;
use crate::websocket_loader::create_handshake_request;

/// Load a file with CA certificate and produce a RootCertStore with the results.
fn load_root_cert_store_from_file(file_path: String) -> io::Result<Vec<CertificateDer<'static>>> {
    let mut pem = BufReader::new(File::open(file_path)?);

    let certs = rustls_pemfile::certs(&mut pem)
        .filter_map(|cert| {
            if let Err(e) = cert {
                log::error!("Could not load certificate ({e}). Ignoring it.");
                None
            } else {
                Some(cert.unwrap())
            }
        })
        .collect();
    Ok(certs)
}

/// Returns a tuple of (public, private) senders to the new threads.
#[allow(clippy::too_many_arguments)]
pub fn new_resource_threads(
    devtools_sender: Option<Sender<DevtoolsControlMsg>>,
    time_profiler_chan: ProfilerChan,
    mem_profiler_chan: MemProfilerChan,
    embedder_proxy: EmbedderProxy,
    config_dir: Option<PathBuf>,
    certificate_path: Option<String>,
    ignore_certificate_errors: bool,
    protocols: Arc<ProtocolRegistry>,
) -> (ResourceThreads, ResourceThreads, Box<dyn AsyncRuntime>) {
    // Initialize the async runtime, and get a handle to it for use in clean shutdown.
    let async_runtime = init_async_runtime();

    let ca_certificates = match certificate_path {
        Some(path) => match load_root_cert_store_from_file(path) {
            Ok(root_cert_store) => CACertificates::Override(root_cert_store),
            Err(error) => {
                warn!("Could not load CA file. Falling back to defaults. {error:?}");

Review comment (suggestion):
```suggestion
            cert.inspect_err(|e| log::error!("Could not load certificate ({e}). Ignoring it.")).ok()
```

Code after:
    CACertificates, CertificateErrorOverrideManager, create_http_client, create_tls_config,
};
use crate::cookie::ServoCookie;
use crate::cookie_storage::CookieStorage;
use crate::fetch::cors_cache::CorsCache;
use crate::fetch::fetch_params::FetchParams;
use crate::fetch::methods::{CancellationListener, FetchContext, WebSocketChannel, fetch};
use crate::filemanager_thread::FileManager;
use crate::hsts::{self, HstsList};
use crate::http_cache::HttpCache;
use crate::http_loader::{HttpState, http_redirect_fetch};
use crate::protocols::ProtocolRegistry;
use crate::request_interceptor::RequestInterceptor;
use crate::websocket_loader::create_handshake_request;

/// Load a file with CA certificate and produce a RootCertStore with the results.
fn load_root_cert_store_from_file(file_path: String) -> io::Result<Vec<CertificateDer<'static>>> {
    let mut pem = BufReader::new(File::open(file_path)?);

    let certs = rustls_pemfile::certs(&mut pem)
        .filter_map(|cert| {
            cert.inspect_err(|e| log::error!("Could not load certificate ({e}). Ignoring it."))
                .ok()
        })
        .collect();
    Ok(certs)
}

/// Returns a tuple of (public, private) senders to the new threads.
#[allow(clippy::too_many_arguments)]
pub fn new_resource_threads(
    devtools_sender: Option<Sender<DevtoolsControlMsg>>,
    time_profiler_chan: ProfilerChan,
    mem_profiler_chan: MemProfilerChan,
    embedder_proxy: EmbedderProxy,
    config_dir: Option<PathBuf>,
    certificate_path: Option<String>,
    ignore_certificate_errors: bool,
    protocols: Arc<ProtocolRegistry>,
) -> (ResourceThreads, ResourceThreads, Box<dyn AsyncRuntime>) {
    // Initialize the async runtime, and get a handle to it for use in clean shutdown.
    let async_runtime = init_async_runtime();

    #[cfg(target_os = "android")]
    let default_verifier = CACertificates::WebPKI;
    #[cfg(not(target_os = "android"))]
    let default_verifier = CACertificates::PlatformVerifier;

    let ca_certificates = match certificate_path {
        Some(path) => match load_root_cert_store_from_file(path) {
            Ok(root_cert_store) => CACertificates::Override(root_cert_store),