use std::{ convert::TryFrom, io::{ self, Write, }, time::Duration, }; use reqwest::{ Client, StatusCode, }; use tokio::{ stream::StreamExt, time::interval, }; use tracing::{ debug, warn }; use tracing_subscriber::{ EnvFilter, fmt, fmt::format::FmtSpan, }; #[tokio::main] async fn main () -> Result <(), anyhow::Error> { fmt () .with_env_filter (EnvFilter::from_default_env ()) .with_span_events (FmtSpan::CLOSE) .init () ; let client = Client::default (); let server = "http://127.0.0.1:4000/files/log.txt"; let mut total_bytes_received = 0_u64; let mut timer = interval (Duration::from_secs (2)); loop { timer.tick ().await; let resp = match client .get (server) .header ("range", format! ("bytes={}-", total_bytes_received)) .send ().await { Err (e) => { warn! ("Reqwest send error: {:?}", e); continue; } Ok (x) => x, }; let status = resp.status (); match status { StatusCode::RANGE_NOT_SATISFIABLE => continue, StatusCode::PARTIAL_CONTENT => (), sc => { debug! ("status code: {}", sc); continue; }, } let mut stream = resp.bytes_stream (); while let Some (chunk) = stream.next ().await { let chunk = match chunk { Ok (x) => x, Err (_) => break, }; io::stdout ().write_all (&chunk)?; total_bytes_received += u64::try_from (chunk.len ())?; } } Ok (()) }