83 lines
2 KiB
Rust
83 lines
2 KiB
Rust
//! 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<dyn Error>> {
|
|
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<u8> = 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();
|
|
}
|
|
}
|
|
}
|