sfo_http/http_server/
http_server.rs1use std::fmt::Debug;
2use std::future::Future;
3use std::path::Path;
4use http::{HeaderName, HeaderValue, Method, StatusCode};
5use http::header::COOKIE;
6use serde::de::DeserializeOwned;
7use serde::{Deserialize, Serialize};
8use tokio::io::AsyncRead;
9use crate::errors::HttpResult;
10
11#[derive(Serialize, Deserialize)]
12pub struct HttpServerResult<T>
13{
14 pub err: u16,
15 pub msg: String,
16 pub result: Option<T>
17}
18
19#[async_trait::async_trait]
20pub trait Request: 'static + Send {
21 fn peer_addr(&self) -> Option<String>;
22 fn local_addr(&self) -> Option<String>;
23 fn remote(&self) -> Option<String>;
24 fn host(&self) -> Option<String>;
25 fn path(&self) -> &str;
26 fn method(&self) -> Method;
27 fn content_type(&self) -> Option<String>;
28 fn header(&self,
29 key: impl Into<HeaderName>, ) -> Option<HeaderValue>;
30 fn header_all(&self, key: impl Into<HeaderName>) -> Vec<HeaderValue>;
31 fn param(&self, key: &str) -> HttpResult<&str>;
32 fn query<T: DeserializeOwned>(&self) -> HttpResult<T>;
33 async fn body_string(&mut self) -> HttpResult<String>;
34 async fn body_bytes(&mut self) -> HttpResult<Vec<u8>>;
35 async fn body_json<T: DeserializeOwned>(&mut self) -> HttpResult<T>;
36 async fn body_form<T: DeserializeOwned>(&mut self) -> HttpResult<T>;
37 fn get_cookie(&self, cookie_name: &str) -> Option<String> {
38 let cookie = self.header_all(COOKIE);
39 if cookie.is_empty() {
40 return None;
41 }
42 let cookie_str = match cookie.last().unwrap().to_str() {
43 Ok(v) => v,
44 Err(_) => return None,
45 };
46 let cookie_list: Vec<_> = cookie_str.split(";").collect();
47 let cookie_list: Vec<(String, String)> = cookie_list.into_iter().map(|v| {
48 let cookie_list: Vec<_> = v.split("=").collect();
49 cookie_list
50 }).filter(|v| v.len() == 2).map(|v| (v[0].trim().to_string(), v[1].trim().to_string())).collect();
51
52 for (name, value) in cookie_list.into_iter() {
53 if name.as_str() == cookie_name {
54 return Some(value);
55 }
56 }
57
58 None
59 }
60}
61
62pub trait Response: 'static + Send {
63 fn from_result<T: Serialize, C: Debug + Copy + Sync + Send + 'static + Into<u16>>(ret: sfo_result::Result<T, C>) -> Self;
64 fn new(status: StatusCode) -> Self;
65 fn insert_header(&mut self, name: HeaderName, value: HeaderValue);
66 fn set_content_type(&mut self, content_type: &str) -> HttpResult<()>;
67 fn set_body(&mut self, body: Vec<u8>);
68 fn set_body_read<R: AsyncRead + Send + Unpin + 'static>(&mut self, reader: R);
69}
70
71#[async_trait::async_trait]
72pub trait Endpoint<Req: Request, Resp: Response>: Send + Sync + 'static {
73 async fn call(&self, req: Req) -> HttpResult<Resp>;
74}
75
76#[async_trait::async_trait]
77impl<Req, Resp, F, Fut> Endpoint<Req, Resp> for F
78where
79 Req: Request,
80 Resp: Response,
81 F: 'static + Send + Clone + Sync + Fn(Req) -> Fut,
82 Fut: Future<Output = HttpResult<Resp>> + Send + 'static,
83{
84 async fn call(&self, req: Req) -> HttpResult<Resp> {
85 let fut = (self)(req);
86 fut.await
87 }
88}
89
90pub type HttpMethod = http::Method;
91
92pub trait HttpServer< Req: Request, Resp: Response> {
93 fn serve(&mut self, path: &str, method: HttpMethod, ep: impl Endpoint<Req, Resp>);
94 fn serve_dir(&mut self, path: &str, dir: impl AsRef<Path>) -> HttpResult<()>;
95 fn serve_file(&mut self, path: &str, file: impl AsRef<Path>) -> HttpResult<()>;
96}
97
98#[derive(Debug, Clone)]
99pub struct HttpServerConfig {
100 pub(crate) server_addr: String,
101 pub(crate) port: u16,
102 pub(crate) allow_origins: Vec<String>,
103 pub(crate) allow_methods: Vec<String>,
104 pub(crate) allow_headers: Vec<String>,
105 pub(crate) expose_headers: Vec<String>,
106 pub(crate) max_age: usize,
107 pub(crate) support_credentials: bool,
108}
109
110impl HttpServerConfig {
111 pub fn new(server_addr: impl Into<String>, port: u16) -> Self {
112 Self {
113 server_addr: server_addr.into(),
114 port,
115 allow_origins: vec![],
116 allow_methods: vec![],
117 allow_headers: vec![],
118 expose_headers: vec![],
119 max_age: 3600,
120 support_credentials: false,
121 }
122 }
123
124 pub fn allow_origins(mut self, origin: Vec<String>) -> Self {
125 self.allow_origins = origin;
126 self
127 }
128
129 pub fn allow_any_origin(mut self) -> Self {
130 self.allow_origins = vec!["*".to_string()];
131 self
132 }
133
134 pub fn allow_methods(mut self, methods: Vec<String>) -> Self {
135 self.allow_methods = methods;
136 self
137 }
138
139 pub fn allow_any_methods(mut self) -> Self {
140 self.allow_methods = vec!["*".to_string()];
141 self
142 }
143
144 pub fn allow_headers(mut self, headers: Vec<String>) -> Self {
145 self.allow_headers = headers;
146 self
147 }
148
149 pub fn allow_any_header(mut self) -> Self {
150 self.allow_headers = vec!["*".to_string()];
151 self
152 }
153
154 pub fn expose_headers(mut self, headers: Vec<String>) -> Self {
155 self.expose_headers = headers;
156 self
157 }
158
159 pub fn expose_any_header(mut self) -> Self {
160 self.expose_headers = vec!["*".to_string()];
161 self
162 }
163
164 pub fn max_age(mut self, age: usize) -> Self {
165 self.max_age = age;
166 self
167 }
168
169 pub fn support_credentials(mut self, support: bool) -> Self {
170 self.support_credentials = support;
171 self
172 }
173}