//! Serve the HDF5 files of a directory over HTTP with range support — the //! server the tests use — to try `clawhdf5_remote` and `h5rs` on URLs. //! //! ```text //! cargo run -p clawhdf5-remote --example range_server -- DIR [127.0.0.1:8000] //! ``` //! //! Every file under `DIR` is served at its path relative to `DIR`. The //! files are read into memory at start. Requests are logged to stderr. #[path = "../tests/common/server.rs"] mod server; fn main() { let mut args = std::env::args().skip(1); let Some(dir) = args.next() else { eprintln!("usage: range_server DIR [ADDR]"); std::process::exit(2); }; let addr = args.next().unwrap_or_else(|| "127.0.0.1:8000".into()); let root = std::path::PathBuf::from(&dir); let mut files = Vec::new(); let mut stack = vec![root.clone()]; while let Some(d) = stack.pop() { let Ok(entries) = std::fs::read_dir(&d) else { continue; }; for e in entries.flatten() { let p = e.path(); if p.is_dir() { stack.push(p); } else if let (Ok(rel), Ok(bytes)) = (p.strip_prefix(&root), std::fs::read(&p)) { let url = format!("/{}", rel.to_string_lossy().replace('\\', "/")); files.push((url, bytes)); } } } files.sort(); let server = server::Server::bind(&addr, files.clone()); for (path, bytes) in &files { eprintln!("{} ({} bytes)", server.url(path), bytes.len()); } eprintln!("serving {} files on http://{}", files.len(), server.addr); let mut logged = 0; loop { std::thread::sleep(std::time::Duration::from_millis(200)); let log = server.log(); for (path, range) in &log[logged.min(log.len())..] { match range { Some((a, b)) => eprintln!("GET {path} bytes={a}-{b}"), None => eprintln!("GET {path} (whole file)"), } } logged = log.len(); } }