rpc_api_server/webserver/
tokio_server.rs1extern crate core;
2
3use std::{convert::Infallible, error::Error, fs, net::SocketAddr};
4use std::collections::HashMap;
5use std::fs::{create_dir_all, read};
6use std::future::Future;
7use std::io::{BufRead, Read};
8use std::iter::Map;
9use std::ops::{Add, Deref};
10use std::path::{Component, Path, PathBuf};
11use std::sync::Arc;
12
13use bytes::{Buf, Bytes};
14use http_body_util::{BodyExt, Full};
15use hyper::{body::Incoming as IncomingBody, header, Method, Request, Response, StatusCode};
16use hyper::body::{Body, Incoming};
17use hyper::server::conn::http1;
18use hyper::service::service_fn;
19use tokio::net::TcpListener;
20use tokio::sync::Mutex;
21
22use rpc_api::rpc::http::{HttpHandler, HttpRequest, HttpResponse};
23
24use crate::webserver;
25use crate::webserver::tokio_conversion::to_http_request;
26
27type GenericError = Box<dyn std::error::Error + Send + Sync>;
31type BoxBody = http_body_util::combinators::BoxBody<Bytes, hyper::Error>;
32type Result<T> = std::result::Result<T, GenericError>;
33
34pub async fn webserver_start(host_port: &str, http_handler: fn(HttpRequest) -> HttpResponse) -> Result<()> {
35 webserver_start_arc(host_port, Arc::new(http_handler)).await
36}
37
38pub async fn webserver_start_arc(host_port: &str, http_handler: HttpHandler) -> Result<()> {
39 println!("webserver_start");
40
41 let ignore = pretty_env_logger::try_init();
42
43 let addr: SocketAddr = host_port.parse().unwrap();
44 println!("serving on http://{}", addr);
45 let listener = TcpListener::bind(&addr).await?;
46
47 loop {
48 let (stream, _) = listener.accept().await?;
49 let callback_clone = Arc::clone(&http_handler);
50
51 tokio::task::spawn(async move {
52 let callback_ref = &callback_clone;
53 let service = service_fn(move |req| web_handler(callback_ref, req));
54
55 if let Err(err) = http1::Builder::new()
56 .serve_connection(stream, service)
57 .await
58 {
59 println!("Failed to serve connection: {:?}", err);
60 }
61 });
62 }
63}
64
65async fn web_handler(http_handler: &HttpHandler, req: Request<IncomingBody>) -> Result<Response<BoxBody>> {
66 let http_request = to_http_request(req).await?;
67 let http_response = http_handler(http_request);
68 webserver::tokio_conversion::to_http_response(http_response)
69}
70
71
72