From 7eb32deb59434e06c36bf4d1fd472bdceeed2487 Mon Sep 17 00:00:00 2001 From: Andy Gayton Date: Fri, 31 May 2024 11:14:03 -0400 Subject: [PATCH] wip: cont on http interface --- src/http.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/http.rs diff --git a/src/http.rs b/src/http.rs new file mode 100644 index 0000000..91347f5 --- /dev/null +++ b/src/http.rs @@ -0,0 +1,59 @@ +use std::error::Error; + +use http_body_util::{combinators::BoxBody, BodyExt, Full}; +use hyper::body::Bytes; +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Request, Response, StatusCode}; +use hyper_util::rt::TokioIo; + +use crate::listener::Listener; +use crate::store::Store; + +type BoxError = Box; +type HTTPResult = Result>, BoxError>; + +async fn handle(_store: Store, req: Request) -> HTTPResult { + eprintln!("\n\nreq: {:?}", &req); + Ok(Response::builder() + .status(StatusCode::OK) + .header("Content-Type", "application/json") + .body(full("Hello world.\n".to_string()))?) +} + +pub async fn serve( + store: Store, + addr: &str, +) -> Result<(), Box> { + println!("starting http interface: {:?}", addr); + let mut listener = Listener::bind(addr).await?; + loop { + let (stream, _) = listener.accept().await?; + let io = TokioIo::new(stream); + let store = store.clone(); + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(move |req| handle(store.clone(), req))) + .await + { + // Match against the error kind to selectively ignore `NotConnected` errors + if let Some(std::io::ErrorKind::NotConnected) = err.source().and_then(|source| { + source + .downcast_ref::() + .map(|io_err| io_err.kind()) + }) { + // Silently ignore the NotConnected error + } else { + // Handle or log other errors + println!("Error serving connection: {:?}", err); + } + } + }); + } +} + +fn full>(chunk: T) -> BoxBody { + Full::new(chunk.into()) + .map_err(|never| match never {}) + .boxed() +}