Skip to content

Instantly share code, notes, and snippets.

@kig
Created May 9, 2020 17:59
Show Gist options
  • Save kig/e422ceda6cab124b3fb6bcc3d1e6ff1c to your computer and use it in GitHub Desktop.
Save kig/e422ceda6cab124b3fb6bcc3d1e6ff1c to your computer and use it in GitHub Desktop.
Rust Hyper stdin lines web server
use {
hyper::{
service::{make_service_fn, service_fn},
Body,
Request,
Response,
Server,
},
std::net::SocketAddr,
tokio::io::{BufReader, AsyncBufReadExt},
std::sync::Arc,
tokio::sync::RwLock,
};
struct Line {
line: RwLock<String>,
}
async fn serve_req(_req: Request<Body>, buffer: Arc<Line>) -> Result<Response<Body>, hyper::Error> {
Ok(Response::new(Body::from(format!("hello, {}!", buffer.line.read().await.to_string()))))
}
async fn run_server(addr: SocketAddr, buffer: Arc<Line>) {
println!("Listening on http://{}", addr);
let serve_future = Server::bind(&addr)
.serve(make_service_fn(|_| {
let buf = Arc::clone(&buffer);
async {
{
Ok::<_, hyper::Error>(service_fn(move |_req| {
serve_req(_req, Arc::clone(&buf))
}))
}
}
}));
if let Err(e) = serve_future.await {
eprintln!("server error: {}", e);
}
}
#[tokio::main]
async fn main() {
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let mut reader = BufReader::new(tokio::io::stdin());
let line = Arc::new(Line{line: RwLock::new(String::new()) });
let server = run_server(addr, Arc::clone(&line));
tokio::spawn(async move {
server.await;
});
loop {
{
let mut s = String::new();
match reader.read_line(&mut s).await {
Ok(0) => {
println!("EOF");
break;
}
Ok(n) => {
println!("{} > {}", n, &s);
let mut tx_guard = line.line.write().await;
tx_guard.clear();
tx_guard.push_str(&s);
}
Err(error) => {
println!("error: {}", error);
break;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment