rpc_api_server/webserver/
tokio_conversion.rs1use std::{convert::Infallible, error::Error, fs, net::SocketAddr};
2use std::collections::HashMap;
3use std::fs::{create_dir_all, read};
4use std::future::Future;
5use std::io::{BufRead, Read};
6use std::iter::Map;
7use std::ops::Add;
8use std::path::{Component, Path, PathBuf};
9
10use bytes::{Buf, Bytes};
11use http_body_util::{BodyExt, Full};
12use hyper::{body::Incoming as IncomingBody, header, Method, Request, Response, StatusCode};
13use hyper::body::{Body, Incoming};
14use hyper::server::conn::http1;
15use hyper::service::service_fn;
16use tokio::net::TcpListener;
17
18use rpc_api::rpc::http::{HttpRequest, HttpResponse};
19
20type GenericError = Box<dyn Error + Send + Sync>;
24type BoxBody = http_body_util::combinators::BoxBody<Bytes, hyper::Error>;
25type Result<T> = std::result::Result<T, GenericError>;
26
27pub async fn to_http_request(req: Request<Incoming>) -> Result<HttpRequest> {
28 let content_type = get_content_type(&req);
29 let method = req.method().to_string();
30 let url = req.uri().to_string();
31 let collected = req.collect().await?;
32 let mut rdr = collected.aggregate().reader();
33 let mut content = String::new();
35 let _ = rdr.read_to_string(&mut content)?;
36 let http_request = HttpRequest {
37 method,
38 content,
39 content_type,
40 url,
41 parameters: HashMap::new(),
42 headers: HashMap::new(),
43 };
44 Ok(http_request)
45}
46
47
48fn get_content_type(req: &Request<Incoming>) -> String {
49 let ct = req.headers();
50 let header_name = "Content-Type";
51 if ct.contains_key(header_name) {
52 ct.get(header_name).unwrap().to_str().unwrap().to_string()
53 } else {
54 "".to_string()
55 }
56}
57
58pub fn to_http_response(http_response: HttpResponse) -> Result<Response<BoxBody>> {
59 let mut builder = Response::builder()
60 .status(StatusCode::from_u16(http_response.status)?)
61 .header(header::CONTENT_TYPE, http_response.content_type);
62 for item in http_response.headers.into_iter() {
63 builder = builder.header(item.0, item.1);
64 }
65 let response = builder
66 .body(full(http_response.content))?;
67 Ok(response)
68}
69
70fn full<T: Into<Bytes>>(chunk: T) -> BoxBody {
71 Full::new(chunk.into())
72 .map_err(|never| match never {})
73 .boxed()
74}