//! A simple echo server that listens on 127.0.0.1:8089 use std::{error::Error, io::Write, net::TcpListener}; use uhttp::Lift; fn main() -> Result<(), Box> { let listener = TcpListener::bind("127.0.0.1:8089")?; loop { let (mut stream, _) = listener.accept()?; let mut conn = uhttp::Connection::new(uhttp::Role::Server); let mut body: Vec = Vec::new(); let mut buf = vec![0; 1024].into_boxed_slice(); let mut buf = uhttp_ext::Buf::new(&mut buf); let mut method_not_allowed = false; loop { let data = buf.filled(); let (remaining, r) = conn.handle_recv(data).lift(); match r.map_err(|e| e.kind) { Err(uhttp::ErrorKind::NeedMoreData) => { buf.read_from(&mut stream)?; continue; }, Err(e) => panic!("{e:?}"), Ok(event) => { match event { uhttp::Event::RequestLine(r) => { if !r.method.eq_ignore_ascii_case("post") { method_not_allowed = true; } }, uhttp::Event::RecvDone => break, uhttp::Event::BodyChunk(b) => body.extend_from_slice(b), _ => (), }; }, }; let len = data.len() - remaining.len(); buf.pop_front(len); } let parts: &[uhttp::Event] = if method_not_allowed { &[ uhttp::Event::StatusLine(uhttp::StatusLine { version: uhttp::Version::HTTP1_1, status_code: 405, status_text: "Method not allowed", }), uhttp::Event::HeadersEnd, uhttp::Event::SendDone, ] } else { &[ uhttp::Event::StatusLine(uhttp::StatusLine { version: uhttp::Version::HTTP1_1, status_code: 200, status_text: "OK", }), uhttp::Event::Header(uhttp::Header::Special( uhttp::HeaderSpecial::ContentLength(body.len()), )), uhttp::Event::HeadersEnd, uhttp::Event::BodyChunk(body.as_slice()), uhttp::Event::SendDone, ] }; let buf = vec![0; 1024]; let mut cursor = uhttp::WriteCursor::new(buf); for p in parts { if let Err(e) = conn.handle_send(p, &mut cursor) { panic!("{e:?}") }; stream.write_all(cursor.written())?; cursor.reset(); } } }