97 lines
2.2 KiB
Rust
97 lines
2.2 KiB
Rust
pub fn main() {
|
|
}
|
|
|
|
/*
|
|
|
|
//! A simple echo server that echoes the body of a POST request, and returns a
|
|
//! 405 for any other method
|
|
//!
|
|
//! Usage:
|
|
//! cargo run --example echo -- <host> <port>
|
|
|
|
use std::{error::Error, io::Write, net::TcpListener};
|
|
|
|
use httplz::NeedsMoreData;
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let mut args = std::env::args().skip(1);
|
|
let (host, port) = args
|
|
.next()
|
|
.and_then(|h| Some((h, args.next()?)))
|
|
.ok_or_else(|| Box::<dyn Error>::from(String::from("Missing required argument")))?;
|
|
|
|
let listener = TcpListener::bind((host, port.parse()?))?;
|
|
loop {
|
|
let (mut stream, _) = listener.accept()?;
|
|
let mut conn = httplz::Connection::new(httplz::Role::Server);
|
|
|
|
let mut body: Vec<u8> = Vec::new();
|
|
let mut buf = httplz::Buf::new(vec![0; 1024].into_boxed_slice());
|
|
|
|
let mut method_not_allowed = false;
|
|
|
|
loop {
|
|
let data = buf.filled();
|
|
let r = conn.poll_recv(data);
|
|
if r.needs_more_data() {
|
|
buf.read_from(&mut stream)?;
|
|
continue;
|
|
}
|
|
|
|
let (amt, event) = r.unwrap();
|
|
match event {
|
|
httplz::Event::RequestLine(r) => {
|
|
if r.method != httplz::Method::Post {
|
|
method_not_allowed = true;
|
|
}
|
|
},
|
|
httplz::Event::RecvDone => break,
|
|
httplz::Event::BodyChunk(b) => body.extend_from_slice(b),
|
|
_ => (),
|
|
};
|
|
|
|
buf.pop_front(amt);
|
|
}
|
|
|
|
let body_len = format!("{}", body.len());
|
|
let parts: &[httplz::Event] = if method_not_allowed {
|
|
&[
|
|
httplz::Event::StatusLine(httplz::StatusLine {
|
|
version: httplz::Version::HTTP1_1,
|
|
status_code: 405,
|
|
status_text: "Method not allowed",
|
|
}),
|
|
httplz::Event::HeadersDone,
|
|
httplz::Event::SendDone,
|
|
]
|
|
} else {
|
|
&[
|
|
httplz::Event::StatusLine(httplz::StatusLine {
|
|
version: httplz::Version::HTTP1_1,
|
|
status_code: 200,
|
|
status_text: "OK",
|
|
}),
|
|
httplz::Header {
|
|
name: "Content-Length",
|
|
value: body_len.as_bytes(),
|
|
}
|
|
.into(),
|
|
httplz::Event::HeadersDone,
|
|
httplz::Event::BodyChunk(body.as_slice()),
|
|
httplz::Event::SendDone,
|
|
]
|
|
};
|
|
|
|
let buf = vec![0; 1024];
|
|
let mut cursor = httplz::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();
|
|
}
|
|
}
|
|
}
|
|
*/
|