rpc_api_server/webserver/
tokio_server.rs

1extern 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
27// use crate::read::{self, Fused, Reference};
28
29
30type 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