20260707 支持本地HTTP root证书

This commit is contained in:
2026-07-07 23:04:44 +08:00
parent b0f76738e5
commit 63ac3ee254
3 changed files with 89 additions and 20 deletions

View File

@@ -29,6 +29,8 @@ pub struct HttpFetcherConfig {
/// Larger timeout used for RRDP snapshot / delta bodies.
pub large_body_timeout: Duration,
pub user_agent: String,
/// Extra PEM trust anchors for HTTPS transport tests or private RRDP endpoints.
pub extra_root_certificates_pem: Vec<Vec<u8>>,
}
impl Default for HttpFetcherConfig {
@@ -38,6 +40,7 @@ impl Default for HttpFetcherConfig {
timeout: Duration::from_secs(30),
large_body_timeout: Duration::from_secs(180),
user_agent: "rpki-dev/0.1 (stage2)".to_string(),
extra_root_certificates_pem: Vec::new(),
}
}
}
@@ -61,24 +64,30 @@ impl BlockingHttpFetcher {
let short_timeout = config.timeout;
let large_body_timeout = std::cmp::max(config.large_body_timeout, config.timeout);
let connect_timeout = std::cmp::min(config.connect_timeout, config.timeout);
let short_client = Client::builder()
.connect_timeout(connect_timeout)
.timeout(config.timeout)
.user_agent(config.user_agent.clone())
.build()
.map_err(|e| e.to_string())?;
let large_body_client = Client::builder()
.connect_timeout(connect_timeout)
.timeout(large_body_timeout)
.user_agent(config.user_agent)
.build()
.map_err(|e| e.to_string())?;
let retry_short_client = Client::builder()
.connect_timeout(Duration::from_secs(1))
.timeout(Duration::from_secs(1))
.user_agent("rpki-dev/0.1 (stage2)")
.build()
.map_err(|e| e.to_string())?;
let short_client = Self::client_builder(
&config,
connect_timeout,
config.timeout,
config.user_agent.clone(),
)?
.build()
.map_err(|e| e.to_string())?;
let large_body_client = Self::client_builder(
&config,
connect_timeout,
large_body_timeout,
config.user_agent.clone(),
)?
.build()
.map_err(|e| e.to_string())?;
let retry_short_client = Self::client_builder(
&config,
Duration::from_secs(1),
Duration::from_secs(1),
"rpki-dev/0.1 (stage2)".to_string(),
)?
.build()
.map_err(|e| e.to_string())?;
Ok(Self {
short_client,
large_body_client,
@@ -88,11 +97,29 @@ impl BlockingHttpFetcher {
})
}
fn client_builder(
config: &HttpFetcherConfig,
connect_timeout: Duration,
timeout: Duration,
user_agent: String,
) -> Result<reqwest::blocking::ClientBuilder, String> {
let mut builder = Client::builder()
.connect_timeout(connect_timeout)
.timeout(timeout)
.user_agent(user_agent);
for (idx, pem) in config.extra_root_certificates_pem.iter().enumerate() {
let certificate = reqwest::Certificate::from_pem(pem)
.map_err(|e| format!("parse HTTP root certificate #{idx} failed: {e}"))?;
builder = builder.add_root_certificate(certificate);
}
Ok(builder)
}
pub fn fetch_bytes(&self, uri: &str) -> Result<Vec<u8>, String> {
let started = std::time::Instant::now();
let (client, timeout_profile, timeout_value) = self.client_for_uri(uri);
let resp = client.get(uri).send().map_err(|e| {
let msg = format!("http request failed: {e}");
let msg = format!("http request failed: {e:?}");
crate::progress_log::emit(
"http_fetch_failed",
serde_json::json!({
@@ -222,7 +249,7 @@ impl Fetcher for BlockingHttpFetcher {
let started = std::time::Instant::now();
let (client, timeout_profile, timeout_value) = self.client_for_uri(uri);
let resp = client.get(uri).send().map_err(|e| {
let msg = format!("http request failed: {e}");
let msg = format!("http request failed: {e:?}");
crate::progress_log::emit(
"http_fetch_failed",
serde_json::json!({