extern crate bytes;
extern crate httparse;
#[macro_use]
extern crate mco;
use bytes::BufMut;
use httparse::Status;
use mco::net::TcpListener;
use std::io::{Read, Write};
fn main() {
println!("bind http://127.0.0.1:3000");
let listener = TcpListener::bind("0.0.0.0:3000").unwrap();
while let Ok((mut stream, _)) = listener.accept() {
co!(move || {
let mut buf = Vec::new();
let mut path = String::new();
loop {
if let Some(i) = req_done(&buf, &mut path) {
let response = match &*path {
"/" => "Hello, World!\n",
"/hello" => "Hello, World!\n",
"/quit" => std::process::exit(1),
_ => "Cannot find page\n",
};
let s = format!(
"\
HTTP/1.1 200 OK\r\n\
Server: mco\r\n\
Content-Length: {}\r\n\
date: 1-1-2000\r\n\
\r\n\
{}",
response.len(),
response
);
stream
.write_all(s.as_bytes())
.expect("Cannot write to socket");
buf = buf.split_off(i);
} else {
let mut temp_buf = vec![0; 512];
match stream.read(&mut temp_buf) {
Ok(0) => return, Ok(n) => buf.put(&temp_buf[0..n]),
Err(err) => {
println!("err = {:?}", err);
break;
}
}
}
}
});
}
}
fn req_done(buf: &[u8], path: &mut String) -> Option<usize> {
let mut headers = [httparse::EMPTY_HEADER; 16];
let mut req = httparse::Request::new(&mut headers);
if let Ok(Status::Complete(i)) = req.parse(buf) {
path.clear();
path.push_str(req.path.unwrap_or("/"));
return Some(i);
}
None
}