-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.rs
74 lines (62 loc) · 2.36 KB
/
server.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use http::{Request, Response, StatusCode};
use http_body_util::BodyExt;
use std::error::Error;
use std::sync::Arc;
use tokio::net::TcpListener;
use micro_http::connection::HttpConnection;
use micro_http::handler::make_handler;
use micro_http::protocol::body::ReqBody;
use tracing::{error, info, warn, Level};
use tracing_subscriber::FmtSubscriber;
#[tokio::main]
async fn main() {
let subscriber = FmtSubscriber::builder().with_max_level(Level::INFO).finish();
tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
info!(port = 8080, "start listening");
let tcp_listener = match TcpListener::bind("127.0.0.1:8080").await {
Ok(tcp_listener) => tcp_listener,
Err(e) => {
error!(cause = %e, "bind server error");
return;
}
};
let handler = make_handler(simple_handler);
let handler = Arc::new(handler);
loop {
let (tcp_stream, _remote_addr) = match tcp_listener.accept().await {
Ok(stream_and_addr) => stream_and_addr,
Err(e) => {
warn!(cause = %e, "failed to accept");
continue;
}
};
let handler = handler.clone();
// one connection per task
tokio::spawn(async move {
let (reader, writer) = tcp_stream.into_split();
let connection = HttpConnection::new(reader, writer);
match connection.process(handler).await {
Ok(_) => {
info!("finished process, connection shutdown");
}
Err(e) => {
error!("service has error, cause {}, connection shutdown", e);
}
}
});
}
}
async fn simple_handler(request: Request<ReqBody>) -> Result<Response<String>, Box<dyn Error + Send + Sync>> {
let path = request.uri().path().to_string();
info!("request path {}", path);
let (_header, body) = request.into_parts();
let body_bytes = body.collect().await?.to_bytes();
info!(body = std::str::from_utf8(&body_bytes[..]).unwrap(), "receiving request body");
let response_body = "Hello World!\r\n";
let response = Response::builder()
.status(StatusCode::OK)
.header(http::header::CONTENT_LENGTH, response_body.len())
.body(response_body.to_string())
.unwrap();
Ok(response)
}