65 lines
2.1 KiB
Rust
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");
|
|
}
|