20260817 同步层HTTP User-Agent改为env可配置RPKI_HTTP_USER_AGENT,默认panda-rpki/0.2
This commit is contained in:
parent
e98eb6d68f
commit
49172b57d3
@ -47,6 +47,9 @@ LIVE_TA_REFRESH_MAX_TIME_SECS=120
|
|||||||
|
|
||||||
# Sync and runtime behavior.
|
# Sync and runtime behavior.
|
||||||
RSYNC_SCOPE=module-root
|
RSYNC_SCOPE=module-root
|
||||||
|
# HTTP User-Agent for all outgoing HTTP requests (RRDP / TAL / TA / dead-repo probes).
|
||||||
|
# Unset, empty, or header-illegal values fall back to panda-rpki/0.2.
|
||||||
|
#RPKI_HTTP_USER_AGENT=panda-rpki/0.2
|
||||||
DISABLE_COMPETING_RPS=0
|
DISABLE_COMPETING_RPS=0
|
||||||
RUN_ROOT=/var/lib/ours-rp
|
RUN_ROOT=/var/lib/ours-rp
|
||||||
DB_DIR=/var/lib/ours-rp/state/db
|
DB_DIR=/var/lib/ours-rp/state/db
|
||||||
|
|||||||
@ -102,6 +102,10 @@ ENABLE_CHILD_CERTIFICATE_VALIDATION_CACHE=0
|
|||||||
# 实验性 transport 预热:RPKI_EXTRA_ARGS="--enable-transport-request-prefetch --enable-roa-validation-cache"
|
# 实验性 transport 预热:RPKI_EXTRA_ARGS="--enable-transport-request-prefetch --enable-roa-validation-cache"
|
||||||
RPKI_EXTRA_ARGS=""
|
RPKI_EXTRA_ARGS=""
|
||||||
|
|
||||||
|
# 所有出站 HTTP 请求(RRDP / TAL / TA / 死 repo 探针)的 User-Agent。
|
||||||
|
# 不设置、为空或含非法 header 字符时回退默认 panda-rpki/0.2。
|
||||||
|
#RPKI_HTTP_USER_AGENT=panda-rpki/0.2
|
||||||
|
|
||||||
# 是否为每轮输出 timing profile 到 runs/run_xxxx/analyze/timing.json。
|
# 是否为每轮输出 timing profile 到 runs/run_xxxx/analyze/timing.json。
|
||||||
# 性能 profile 或打点验证时设置为 1;普通 soak 建议保持 0,避免额外开销。
|
# 性能 profile 或打点验证时设置为 1;普通 soak 建议保持 0,避免额外开销。
|
||||||
RPKI_ANALYZE=0
|
RPKI_ANALYZE=0
|
||||||
|
|||||||
@ -20,6 +20,28 @@ pub fn with_scoped_http_timeout_override<R>(timeout: Duration, f: impl FnOnce()
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Default User-Agent sent with every outgoing HTTP request (RRDP
|
||||||
|
/// notification/snapshot/delta, TAL/TA downloads, daemon probes).
|
||||||
|
pub const DEFAULT_HTTP_USER_AGENT: &str = "panda-rpki/0.2";
|
||||||
|
|
||||||
|
/// Environment variable that overrides the HTTP User-Agent. Unset, empty, or
|
||||||
|
/// values containing characters that are illegal in a header value fall back
|
||||||
|
/// to [`DEFAULT_HTTP_USER_AGENT`].
|
||||||
|
pub const HTTP_USER_AGENT_ENV: &str = "RPKI_HTTP_USER_AGENT";
|
||||||
|
|
||||||
|
fn resolve_http_user_agent(env_value: Option<String>) -> String {
|
||||||
|
let Some(value) = env_value else {
|
||||||
|
return DEFAULT_HTTP_USER_AGENT.to_string();
|
||||||
|
};
|
||||||
|
let trimmed = value.trim();
|
||||||
|
let valid = !trimmed.is_empty() && trimmed.bytes().all(|b| (0x20..=0x7e).contains(&b));
|
||||||
|
if valid {
|
||||||
|
trimmed.to_string()
|
||||||
|
} else {
|
||||||
|
DEFAULT_HTTP_USER_AGENT.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct HttpFetcherConfig {
|
pub struct HttpFetcherConfig {
|
||||||
/// Connection-establishment timeout for HTTP requests.
|
/// Connection-establishment timeout for HTTP requests.
|
||||||
@ -39,7 +61,7 @@ impl Default for HttpFetcherConfig {
|
|||||||
connect_timeout: Duration::from_secs(15),
|
connect_timeout: Duration::from_secs(15),
|
||||||
timeout: Duration::from_secs(30),
|
timeout: Duration::from_secs(30),
|
||||||
large_body_timeout: Duration::from_secs(180),
|
large_body_timeout: Duration::from_secs(180),
|
||||||
user_agent: "rpki-dev/0.1 (stage2)".to_string(),
|
user_agent: resolve_http_user_agent(std::env::var(HTTP_USER_AGENT_ENV).ok()),
|
||||||
extra_root_certificates_pem: Vec::new(),
|
extra_root_certificates_pem: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +106,7 @@ impl BlockingHttpFetcher {
|
|||||||
&config,
|
&config,
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(1),
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(1),
|
||||||
"rpki-dev/0.1 (stage2)".to_string(),
|
config.user_agent.clone(),
|
||||||
)?
|
)?
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
@ -532,4 +554,99 @@ mod tests {
|
|||||||
assert_eq!(profile_large, "large_body");
|
assert_eq!(profile_large, "large_body");
|
||||||
assert_eq!(timeout_large, Duration::from_secs(9));
|
assert_eq!(timeout_large, Duration::from_secs(9));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resolve_http_user_agent_falls_back_to_default() {
|
||||||
|
assert_eq!(resolve_http_user_agent(None), DEFAULT_HTTP_USER_AGENT);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some(String::new())),
|
||||||
|
DEFAULT_HTTP_USER_AGENT
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some(" ".to_string())),
|
||||||
|
DEFAULT_HTTP_USER_AGENT
|
||||||
|
);
|
||||||
|
// Control characters are illegal in header values; fall back instead
|
||||||
|
// of letting reqwest fail to build the client.
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some("bad\u{1}ua".to_string())),
|
||||||
|
DEFAULT_HTTP_USER_AGENT
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some("non-ascii-ua-中".to_string())),
|
||||||
|
DEFAULT_HTTP_USER_AGENT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn resolve_http_user_agent_accepts_custom_value() {
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some("panda-rpki/9.9 (test)".to_string())),
|
||||||
|
"panda-rpki/9.9 (test)"
|
||||||
|
);
|
||||||
|
// Surrounding whitespace is trimmed.
|
||||||
|
assert_eq!(
|
||||||
|
resolve_http_user_agent(Some(" custom/1.0 ".to_string())),
|
||||||
|
"custom/1.0"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_user_agent_capture_server() -> (String, std::sync::mpsc::Receiver<String>) {
|
||||||
|
let listener = TcpListener::bind(("127.0.0.1", 0)).expect("bind");
|
||||||
|
let addr = listener.local_addr().expect("addr");
|
||||||
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
thread::spawn(move || {
|
||||||
|
let (mut stream, _) = listener.accept().expect("accept");
|
||||||
|
let mut buf = [0u8; 4096];
|
||||||
|
let read = stream.read(&mut buf).expect("read request");
|
||||||
|
let request = String::from_utf8_lossy(&buf[..read]).to_string();
|
||||||
|
let body = b"ok";
|
||||||
|
let hdr = format!(
|
||||||
|
"HTTP/1.1 200 OK\r\nContent-Length: {}\r\nConnection: close\r\n\r\n",
|
||||||
|
body.len()
|
||||||
|
);
|
||||||
|
stream.write_all(hdr.as_bytes()).expect("write hdr");
|
||||||
|
stream.write_all(body).expect("write body");
|
||||||
|
let _ = tx.send(request);
|
||||||
|
});
|
||||||
|
(format!("http://{}/", addr), rx)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fetch_bytes_sends_configured_user_agent_header() {
|
||||||
|
let (url, rx) = spawn_user_agent_capture_server();
|
||||||
|
let http = BlockingHttpFetcher::new(HttpFetcherConfig {
|
||||||
|
timeout: Duration::from_secs(2),
|
||||||
|
user_agent: "panda-rpki/0.2".to_string(),
|
||||||
|
..HttpFetcherConfig::default()
|
||||||
|
})
|
||||||
|
.expect("http");
|
||||||
|
http.fetch_bytes(&url).expect("fetch");
|
||||||
|
let request = rx.recv().expect("request captured");
|
||||||
|
assert!(
|
||||||
|
request
|
||||||
|
.to_ascii_lowercase()
|
||||||
|
.contains("user-agent: panda-rpki/0.2"),
|
||||||
|
"{request}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn fetch_bytes_sends_custom_user_agent_header() {
|
||||||
|
let (url, rx) = spawn_user_agent_capture_server();
|
||||||
|
let http = BlockingHttpFetcher::new(HttpFetcherConfig {
|
||||||
|
timeout: Duration::from_secs(2),
|
||||||
|
user_agent: "custom-marker/7.7".to_string(),
|
||||||
|
..HttpFetcherConfig::default()
|
||||||
|
})
|
||||||
|
.expect("http");
|
||||||
|
http.fetch_bytes(&url).expect("fetch");
|
||||||
|
let request = rx.recv().expect("request captured");
|
||||||
|
assert!(
|
||||||
|
request
|
||||||
|
.to_ascii_lowercase()
|
||||||
|
.contains("user-agent: custom-marker/7.7"),
|
||||||
|
"{request}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ fn live_http_fetcher() -> BlockingHttpFetcher {
|
|||||||
BlockingHttpFetcher::new(HttpFetcherConfig {
|
BlockingHttpFetcher::new(HttpFetcherConfig {
|
||||||
timeout: Duration::from_secs(timeout_secs),
|
timeout: Duration::from_secs(timeout_secs),
|
||||||
large_body_timeout: Duration::from_secs(timeout_secs),
|
large_body_timeout: Duration::from_secs(timeout_secs),
|
||||||
user_agent: "rpki-dev/0.1 (stage2 live rrdp delta test)".to_string(),
|
user_agent: "panda-rpki/0.2 (live rrdp delta test)".to_string(),
|
||||||
..HttpFetcherConfig::default()
|
..HttpFetcherConfig::default()
|
||||||
})
|
})
|
||||||
.expect("http fetcher")
|
.expect("http fetcher")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user