use std::io::{Read as _, Write as _}; use std::net::TcpListener as StdTcpListener; use std::thread; use std::time::Duration; use bytes::Bytes; use http_body_util::{BodyExt, Empty}; use hyper::Request; use ruin_runtime::time::sleep; use ruin_runtime::{clear_interval, queue_future, set_interval}; fn spawn_demo_server() -> std::io::Result<(std::net::SocketAddr, thread::JoinHandle<()>)> { let listener = StdTcpListener::bind(("127.0.0.1", 0))?; let address = listener.local_addr()?; let handle = thread::Builder::new() .name("hyper-demo-server".into()) .spawn(move || { let (mut stream, peer) = listener.accept().expect("demo server should accept"); let mut request = [0; 1024]; let read = stream.read(&mut request).expect("demo server should read"); println!("[server] accepted {peer}, saw {} request bytes", read); let response = concat!( "HTTP/1.1 200 OK\r\n", "content-type: text/plain; charset=utf-8\r\n", "content-length: 24\r\n", "connection: close\r\n", "\r\n", "hello from ruin runtime!" ); stream .write_all(response.as_bytes()) .expect("demo server should reply"); }) .map_err(std::io::Error::other)?; Ok((address, handle)) } #[ruin_runtime::async_main] async fn main() -> Result<(), Box> { let (address, server) = spawn_demo_server()?; let stream = ruin_runtime::net::TcpStream::connect(address).await?; let (mut sender, connection) = hyper::client::conn::http1::handshake(stream).await?; queue_future(async move { if let Err(error) = connection.await { eprintln!("[runtime] hyper connection ended with error: {error}"); } }); println!("Sleeping a moment to let the server start..."); let interval = set_interval(Duration::from_millis(400), || println!("...")); sleep(Duration::from_secs(2)).await; clear_interval(&interval); println!("Let's go!"); let request = Request::builder() .method("GET") .uri(format!("http://{address}/demo")) .header("host", address.to_string()) .body(Empty::::new())?; let response = sender.send_request(request).await?; let status = response.status(); let body = response.into_body().collect().await?.to_bytes(); println!( "[client] status={status}, body={}", String::from_utf8_lossy(&body) ); server .join() .expect("demo server thread should exit cleanly"); Ok(()) }