1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3use std::collections::HashMap;
4use std::io::{self, Read, Write};
5use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener};
6use std::sync::Arc;
7
8mod thread_pool;
9
10mod http_parser;
11
12use http_parser::WsRouterValue;
13pub use http_parser::{
14 ConnectionData, MiddleWare, Request, Response, Router, RouterMap, RouterValue, ServerConfig,
15 Websocket, WebsocketEvent, WsMessage, WsRouter,
16};
17
18#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
19#[cfg(feature = "macros")]
20pub use xfinal_macro::end_point;
21
22pub use http_parser::connection::http_response_table::{
23 CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE,
24};
25
26use http_parser::connection::http_response_table::get_httpmethod_from_code;
27
28pub use tera;
29
30pub use serde_json;
31
32pub type JsonValue = serde_json::Value;
33
34pub mod cookie;
35
36pub use cookie::Period;
37
38pub use chrono;
39pub use chrono_tz;
40pub use hmac;
41pub use sha2;
42
43pub use base64;
44
45pub use sha1;
46
47use hmac::{Hmac, Mac};
48use sha2::Sha256;
49pub use uuid;
50
51pub trait SerializationMethods {
52 fn serialize(&self) -> Vec<&'static str>;
53}
54
55impl SerializationMethods for u8 {
56 fn serialize(&self) -> Vec<&'static str> {
57 let m = get_httpmethod_from_code(*self);
58 let mut r = Vec::new();
59 r.push(m);
60 r
61 }
62}
63
64impl SerializationMethods for &[u8] {
65 fn serialize(&self) -> Vec<&'static str> {
66 let mut r = Vec::new();
67 for e in *self {
68 let m = get_httpmethod_from_code(*e);
69 r.push(m);
70 }
71 r
72 }
73}
74
75impl<const I: usize> SerializationMethods for [u8; I] {
76 fn serialize(&self) -> Vec<&'static str> {
77 let mut r = Vec::new();
78 for e in *self {
79 let m = get_httpmethod_from_code(e);
80 r.push(m);
81 }
82 r
83 }
84}
85
86#[derive(Debug)]
87pub struct EndPoint {
88 pub port: u16,
89 pub ip_address: [u8; 4],
90}
91
92pub struct HttpServer {
93 end_point: EndPoint,
94 thread_number: u16,
95 router: HashMap<String, RouterValue>,
96 ws_router: HashMap<String, WsRouterValue>,
97 config_: ServerConfig,
98}
99
100pub struct RouterRegister<'a> {
101 server: &'a mut HttpServer,
102 path: &'a str,
103 methods: Vec<&'a str>,
104}
105
106impl<'a> RouterRegister<'a> {
107 pub fn reg<F>(&mut self, f: F)
108 where
109 F: Router + Send + Sync + 'static + Clone,
110 {
111 for e in &self.methods {
112 let router_path = format!("{}{}", e, self.path);
113 self.server
114 .router
115 .insert(router_path, (None, Arc::new(f.clone())));
116 }
117 }
118
119 pub fn reg_with_middlewares<F>(
120 &mut self,
121 middlewares: Vec<Arc<dyn MiddleWare + Send + Sync>>,
122 f: F,
123 ) where
124 F: Router + Send + Sync + 'static + Clone,
125 {
126 for e in &self.methods {
127 let router_path = format!("{}{}", e, self.path);
128 self.server.router.insert(
129 router_path,
130 (Some(middlewares.clone()), Arc::new(f.clone())),
131 );
132 }
133 }
134}
135
136pub struct WsRouterRegister<'a> {
137 server: &'a mut HttpServer,
138 path: &'a str,
139}
140
141impl<'a> WsRouterRegister<'a> {
142 pub fn reg<F>(&mut self, f: F)
143 where
144 F: WsRouter + Send + Sync + 'static + Clone,
145 {
146 self.server
147 .ws_router
148 .insert(self.path.to_string(), (None, Arc::new(f.clone())));
149 }
150
151 pub fn reg_with_middlewares<F>(
152 &mut self,
153 middlewares: Vec<Arc<dyn MiddleWare + Send + Sync>>,
154 f: F,
155 ) where
156 F: WsRouter + Send + Sync + 'static + Clone,
157 {
158 self.server.ws_router.insert(
159 self.path.to_string(),
160 (Some(middlewares.clone()), Arc::new(f.clone())),
161 );
162 }
163}
164
165impl HttpServer {
166 pub fn create(end: EndPoint, count: u16) -> Self {
170 let key = match std::fs::OpenOptions::new()
171 .read(true)
172 .write(true)
173 .create(true)
174 .open("./secret.key")
175 {
176 Ok(mut file) => {
177 let mut s = String::new();
178 match file.read_to_string(&mut s) {
179 Ok(size) => {
180 if size == 0 {
181 let s = uuid::Uuid::new_v4().to_string();
182 file.write(s.as_bytes())
183 .expect("write new secret key error");
184 s
185 } else {
186 s
187 }
188 }
189 Err(e) => {
190 panic!("initial secret key error:{}", e.to_string())
191 }
192 }
193 }
194 Err(e) => {
195 panic!("initial secret key error:{}", e.to_string())
196 }
197 };
198 type HmacSha256 = Hmac<Sha256>;
199 let mac = match HmacSha256::new_from_slice(key.as_bytes()) {
200 Ok(r) => r,
201 Err(e) => {
202 panic!("HmacSha256::new_from_slice error:{}", e.to_string())
203 }
204 };
205 Self {
206 end_point: end,
207 thread_number: count,
208 router: HashMap::new(),
209 ws_router: HashMap::new(),
210 config_: ServerConfig {
211 upload_directory: String::from("./upload"),
212 read_timeout: 5 * 1000,
213 chunk_size: 1024 * 5,
214 write_timeout: 5 * 1000,
215 open_log: false,
216 max_body_size: 3 * 1024 * 1024,
217 max_header_size: 3 * 1024 * 1024,
218 read_buff_increase_size: 1024,
219 secret_key: Arc::new(mac),
220 ws_read_timeout: 5 * 60 * 1000,
221 ws_write_timeout: 5 * 60 * 1000,
222 ws_frame_size: 65535,
223 },
224 }
225 }
226
227 fn create_directory(&self) -> io::Result<bool> {
228 let _ = std::fs::create_dir(self.config_.upload_directory.clone())?;
229 Ok(true)
230 }
231 pub fn set_read_timeout(&mut self, millis: u32) {
234 self.config_.read_timeout = millis;
235 }
236
237 pub fn set_write_timeout(&mut self, millis: u32) {
240 self.config_.write_timeout = millis;
241 }
242
243 pub fn set_chunksize(&mut self, size: u32) {
246 self.config_.chunk_size = size;
247 }
248
249 pub fn open_server_log(&mut self, open: bool) {
251 self.config_.open_log = open;
252 }
253
254 pub fn set_max_body_size(&mut self, size: usize) {
257 self.config_.max_header_size = size;
258 }
259
260 pub fn set_max_header_size(&mut self, size: usize) {
263 self.config_.max_body_size = size;
264 }
265
266 pub fn set_read_buff_increase_size(&mut self, size: usize) {
269 self.config_.read_buff_increase_size = size;
270 }
271
272 pub fn set_ws_readtimeout(&mut self, millis: u32) {
275 self.config_.ws_read_timeout = millis;
276 }
277
278 pub fn set_ws_writetimeout(&mut self, millis: u32) {
281 self.config_.ws_write_timeout = millis;
282 }
283
284 pub fn set_ws_frame_size(&mut self, size: usize) {
287 if size < 126 {
288 panic!("shall be larger than or equal to 126");
289 }
290 self.config_.ws_frame_size = size;
291 }
292
293 pub fn run(&mut self) {
297 let [a, b, c, d] = self.end_point.ip_address;
298 let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(a, b, c, d)), self.end_point.port);
299 let listen = TcpListener::bind(socket);
300 self.not_found_default_if_not_set();
301 match self.create_directory() {
302 Ok(_) => {}
303 Err(e) => match e.kind() {
304 io::ErrorKind::AlreadyExists => {}
305 _ => {
306 panic!("{}", e.to_string())
307 }
308 },
309 };
310 let safe_router = Arc::new(self.router.clone());
311 let safe_ws_router = Arc::new(self.ws_router.clone());
312 let conn_data = Arc::new(ConnectionData {
313 router_map: safe_router,
314 ws_router_map: safe_ws_router,
315 server_config: self.config_.clone(),
316 });
317 match listen {
318 Ok(x) => {
319 let mut pool =
320 thread_pool::ThreadPool::new(self.thread_number, http_parser::handle_incoming);
321 for conn in x.incoming() {
322 match conn {
323 Ok(stream) => {
324 let conn_data = conn_data.clone();
325 match pool.poll((conn_data, stream)) {
326 Ok(_) => {}
327 Err(e) => {
328 if self.config_.open_log {
329 let now = http_parser::get_current_date();
330 println!(
331 "[{}] >>> error in send connection: {}",
332 now,
333 e.to_string()
334 );
335 }
336 }
337 }
338 }
339 Err(e) => {
340 if self.config_.open_log {
341 let now = http_parser::get_current_date();
342 println!("[{}] >>> error on incoming:{}", now, e.to_string());
343 }
344 }
345 }
346 }
347 pool.join();
348 }
349 Err(e) => {
350 panic!("listen error, the reason is: {}", e.to_string());
351 }
352 }
353 }
354
355 pub fn route<'a, T: SerializationMethods>(
375 &'a mut self,
376 methods: T,
377 path: &'a str,
378 ) -> RouterRegister<'_> {
379 if path.trim() == "/*" {
381 panic!("/* => wildcard of root path is not permitted!")
382 }
383 RouterRegister {
384 server: self,
385 methods: methods.serialize(),
386 path,
387 }
388 }
389
390 pub fn route_ws<'a>(&'a mut self, path: &'a str) -> WsRouterRegister<'a> {
392 WsRouterRegister { server: self, path }
393 }
394
395 pub fn set_not_found<F>(&mut self, f: F)
399 where
400 F: Router + Send + Sync + 'static,
401 {
402 self.router
403 .insert(String::from("NEVER_FOUND_FOR_ALL"), (None, Arc::new(f)));
404 }
405
406 fn not_found_default_if_not_set(&mut self) {
407 let r = &self.router.get(&String::from("NEVER_FOUND_FOR_ALL"));
408 if let None = *r {
409 self.set_not_found(|_req: &Request, res: &mut Response| {
410 res.write_state(404);
411 });
412 }
413 }
414}
415
416#[macro_export]
418macro_rules! inject_middlewares {
419 ($($m:expr),*) => {
420 {
421 use std::sync::Arc;
422 type T = Arc<dyn MiddleWare + Send + Sync>;
423 let x = vec![$( Arc::new($m) as T ,)*];
424 x
425 }
426 };
427}
428
429