串行验证通过

This commit is contained in:
2026-02-09 19:35:54 +08:00
parent 7be865d7f1
commit afc31c02ab
66 changed files with 12049 additions and 4 deletions

65
src/fetch/http.rs Normal file
View File

@@ -0,0 +1,65 @@
use std::time::Duration;
use reqwest::blocking::Client;
use crate::sync::rrdp::Fetcher;
#[derive(Clone, Debug)]
pub struct HttpFetcherConfig {
pub timeout: Duration,
pub user_agent: String,
}
impl Default for HttpFetcherConfig {
fn default() -> Self {
Self {
timeout: Duration::from_secs(20),
user_agent: "rpki-dev/0.1 (stage2)".to_string(),
}
}
}
/// Minimal blocking HTTP(S) fetcher for stage2.
///
/// This is used for:
/// - downloading TAL / TA certificates (RFC 8630 §2)
/// - fetching RRDP notification/snapshot files (RFC 8182 §3.4)
#[derive(Clone, Debug)]
pub struct BlockingHttpFetcher {
client: Client,
}
impl BlockingHttpFetcher {
pub fn new(config: HttpFetcherConfig) -> Result<Self, String> {
let client = Client::builder()
.timeout(config.timeout)
.user_agent(config.user_agent)
.build()
.map_err(|e| e.to_string())?;
Ok(Self { client })
}
pub fn fetch_bytes(&self, uri: &str) -> Result<Vec<u8>, String> {
let resp = self
.client
.get(uri)
.send()
.map_err(|e| format!("http request failed: {e}"))?;
let status = resp.status();
if !status.is_success() {
return Err(format!("http status {status}"));
}
resp.bytes()
.map(|b| b.to_vec())
.map_err(|e| format!("http read body failed: {e}"))
}
}
impl Fetcher for BlockingHttpFetcher {
fn fetch(&self, uri: &str) -> Result<Vec<u8>, String> {
self.fetch_bytes(uri)
}
}