rpki/tests/test_fetch_http.rs
2026-02-09 19:35:54 +08:00

65 lines
2.1 KiB
Rust

use std::io::{Read, Write};
use std::net::TcpListener;
use std::thread;
use rpki::fetch::http::{BlockingHttpFetcher, HttpFetcherConfig};
use rpki::sync::rrdp::Fetcher;
fn start_one_shot_http_server() -> (String, thread::JoinHandle<()>) {
let listener = TcpListener::bind("127.0.0.1:0").expect("bind");
let addr = listener.local_addr().expect("local addr");
let addr_s = addr.to_string();
let h = thread::spawn(move || {
for _ in 0..3 {
let (mut sock, _peer) = listener.accept().expect("accept");
let mut buf = [0u8; 4096];
let n = sock.read(&mut buf).expect("read request");
let req = String::from_utf8_lossy(&buf[..n]);
let path = req
.lines()
.next()
.and_then(|l| l.split_whitespace().nth(1))
.unwrap_or("/");
let (status, body) = if path == "/ok" {
("200 OK", b"ok".as_slice())
} else {
("404 Not Found", b"nope".as_slice())
};
let resp = format!(
"HTTP/1.1 {status}\r\nContent-Length: {}\r\nConnection: close\r\n\r\n",
body.len()
);
sock.write_all(resp.as_bytes()).expect("write headers");
sock.write_all(body).expect("write body");
}
});
(addr_s, h)
}
#[test]
fn http_fetcher_handles_success_and_status_errors() {
let (addr, h) = start_one_shot_http_server();
let fetcher = BlockingHttpFetcher::new(HttpFetcherConfig::default()).expect("build fetcher");
let ok = fetcher
.fetch_bytes(&format!("http://{addr}/ok"))
.expect("fetch ok");
assert_eq!(ok, b"ok");
// Also exercise the trait method wrapper.
let ok2 = Fetcher::fetch(&fetcher, &format!("http://{addr}/ok")).expect("fetch via trait");
assert_eq!(ok2, b"ok");
let err = fetcher
.fetch_bytes(&format!("http://{addr}/missing"))
.unwrap_err();
assert!(err.contains("404"), "error should mention 404, got: {err}");
h.join().expect("server thread join");
}