use hirun::net::*;
use hirun::runtime;
mod http;
use http::*;
async fn server_conn(conn: Fd, size: usize) {
conn.set_linger(Some(Duration::default()));
let mut aio = AioFd::new(&conn);
loop {
let mut req = HttpReq::new();
if let Err(_) = req.read(&mut aio).await {
break;
}
let rsp = HttpRsp::new(size);
if let Err(_) = rsp.write(&mut aio).await {
break;
}
}
let _ = conn.shutdown(SHUT_RDWR);
}
async fn server(addr: &SocketAddr, size: usize) {
let server = match Fd::tcp_server(addr) {
Ok(server) => server,
Err(_e) => {
println!("tcp_server fail: {_e}");
return;
}
};
let mut aio = AioFd::new(&server);
loop {
match aio.accept().await {
Ok((conn, _)) => {
let _ = runtime::task::spawn(server_conn(conn, size)).await;
}
Err(_e) => {}
};
}
}
use std::time::*;
fn help() {
println!("{} options", hictor::program_invocation_name());
println!("options:");
println!("--addr | -a: listening addr, format is port | ip:port");
println!("--size | -s: body_length, default is 1024");
println!("--cache: max task-cache size, default is 0");
println!("--threads | -t: default is 0");
println!("--help | -h: print help message");
}
fn main() {
let opts = hiopt::options!["addr:", "a:", "size:", "s:", "cache:", "threads:", "t:", "help", "h"];
let args = unsafe { hiopt::raw_args_from_i8(hictor::args()) };
let mut addr = SocketAddr::inet_from("2000").unwrap();
let mut size = 1024_usize;
let mut cache = 0_usize;
let mut nth = 0_usize;
for opt in opts.opt_iter(&args[1..]) {
let (optidx, optval) = opt.unwrap();
match optidx {
0..=1 => addr = SocketAddr::inet_from(optval.unwrap()).unwrap(),
2..=3 => size = optval.unwrap().parse().unwrap(),
4 => cache = optval.unwrap().parse().unwrap(),
5..=6 => nth = optval.unwrap().parse().unwrap(),
7..=8 => return help(),
_ => unreachable!(),
}
}
let _ = runtime::Builder::new()
.name("http")
.max_cache(cache)
.nth(nth)
.build();
let _ = runtime::block_on_with(server(&addr, size), runtime::Attr::new().priority(1));
}