Restaged repo, allocator and runtime implemented, ioring-backed async fs/net/channel/timer primitives
This commit is contained in:
75
lib/runtime/examples/hyper_http_client.rs
Normal file
75
lib/runtime/examples/hyper_http_client.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
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<dyn std::error::Error>> {
|
||||
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::<Bytes>::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(())
|
||||
}
|
||||
Reference in New Issue
Block a user