1mod stream;
2pub mod config;
3pub mod request;
4pub mod response;
5pub mod websocket;
6#[cfg(feature = "pools")]
7mod pools;
8use crate::stream::{Scheme};
9use crate::config::{Config};
10use crate::request::{Request};
11use crate::response::Response;
12use crate::websocket::{CloseCode, ErrorCode, Message, Websocket};
13use log::{error, info, warn};
14#[cfg(feature = "https")]
15use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
16use std::io::{Error, Write};
17use std::net::{TcpListener};
18use std::sync::{Arc, Mutex};
19use std::time::{Duration};
20use std::{io, thread};
21use std::fmt::Debug;
22use std::path::PathBuf;
23use flate2::Compression;
24use flate2::write::GzEncoder;
25use json::{object, JsonValue};
26
27#[derive(Clone, Debug)]
29pub struct WebServer;
30
31impl WebServer {
32 pub fn new_service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) {
34 loop {
35 match WebServer::service(config.clone(), factory) {
36 Ok(()) => {}
37 Err(e) => error!("服务器错误: {}[{}]: {}", file!(), line!(), e),
38 }
39 warn!("服务器 1秒后重启");
40 thread::sleep(Duration::from_secs(1));
41 }
42 }
43 fn service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
44 info!("==================== 网络服务 服务信息 ====================");
45 info!("日志记录: {}",if config.log {"开启"} else {"关闭"});
46 info!("调试模式: {}",if config.debug { "开启" } else { "关闭" });
47 info!("监听地址: {}", config.host);
48 info!("服务地址: {}://{}",if config.https { "https" } else { "http" },config.host);
49 info!("根 目 录: {}", config.root_path.to_str().unwrap());
50 info!("访问目录: {}", config.public);
51 info!("运行目录: {}", config.runtime);
52 info!("SSL/TLS: {}",if config.https { "开启" } else { "关闭" });
53
54 if config.https {
55 info!("证书目录KEY: {:?}", config.tls.key);
56 info!("证书目录PEM: {:?}", config.tls.certs);
57 }
58
59 let listener = TcpListener::bind(config.host.clone())?;
60 info!("==================== 网络服务 启动成功 ====================");
61
62 #[cfg(feature = "https")] let acceptor = Self::ssl(config.clone())?;
63 #[cfg(feature = "pools")] let mut pool = pools::Pool::new(config.pools_max * 4);
64 for stream in listener.incoming() {
65 match stream {
66 Ok(stream) => {
67 let config_new = config.clone();
68 #[cfg(feature = "https")] let acceptor_new = acceptor.clone();
69 #[cfg(not(feature = "pools"))]
70 thread::spawn(move || {
71 stream.set_nonblocking(false)?;
72 stream.set_read_timeout(Some(Duration::from_secs(30))).unwrap_or_default();
74 stream.set_write_timeout(Some(Duration::from_secs(30))).unwrap_or_default();
76 #[cfg(feature = "https")]
77 {
78 let scheme = if config_new.https {
79 match acceptor_new.accept(stream) {
80 Ok(e) => Scheme::Https(Arc::new(Mutex::new(e))),
81 Err(_) => return Err(Error::other("加载加密请求失败")),
82 }
83 } else {
84 Scheme::Http(Arc::new(Mutex::new(stream)))
85 };
86 }
87 #[cfg(not(feature = "https"))] let scheme = Scheme::Http(Arc::new(Mutex::new(stream)));
88
89 loop {
90 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
91 let response = match request.handle() {
92 Ok(()) => Response::new(request.clone(), factory),
93 Err(e) => {
94 return Err(Error::other(e.body.as_str()));
96 }
97 };
98 match response.handle() {
99 Ok(()) => {}
100 Err(e) => {
101 error!("发送错误失败2: {}",e.to_string());
102 return Err(Error::other(e));
103 }
104 };
105 match request.upgrade {
106 Upgrade::H2c => continue,
107 _ => {}
108 }
109 match request.save_log() {
110 Ok(()) => {}
111 Err(_) => error!("日志记录错误")
112 }
113 break Ok(());
114 }
115 });
116
117 #[cfg(feature = "pools")]
118 pool.execute(move || -> io::Result<()> {
119
120 stream.set_read_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
122 stream.set_write_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
124
125 let scheme = if config_new.https {
126 match acceptor_new.accept(stream) {
127 Ok(e) => Scheme::Https(Arc::new(Mutex::new(e))),
128 Err(_) => return Err(Error::other("加载加密请求失败")),
129 }
130 } else {
131 Scheme::Http(Arc::new(Mutex::new(stream)))
132 };
133 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
134 let request_req = request.handle();
135 let mut response = Response::new(request.clone(), factory);
136 match request_req {
137 Ok(()) => {}
138 Err(e) => return match response.status(e.code).txt(e.body.as_str()).send() {
139 Ok(()) => Ok(()),
140 Err(e) => Err(Error::other(e.body.as_str())),
141 }
142 };
143 response.handle()?;
144 match request.save_log() {
145 Ok(()) => {}
146 Err(_) => {
147 error!("日志记录错误");
148 }
149 }
150 Ok(())
151 });
152 }
153 Err(e) => return Err(e),
154 }
155 }
156 #[cfg(feature = "pools")]
157 pool.end();
158 Ok(())
159 }
160
161 #[cfg(feature = "https")]
162 fn ssl(config: Config) -> io::Result<Arc<SslAcceptor>> {
163 if config.https {
164 let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
165 if !config.tls.key.is_file() {
166 return Err(Error::other(
167 format!("private.key 不存在: {:?}", config.tls.key).as_str(),
168 ));
169 }
170 if !config.tls.certs.is_file() {
171 return Err(Error::other(
172 format!("certificate.pem 不存在: {:?}", config.tls.certs).as_str(),
173 ));
174 }
175 acceptor.set_private_key_file(config.tls.key.clone(), SslFiletype::PEM)?;
176 acceptor.set_certificate_file(config.tls.certs.clone(), SslFiletype::PEM)?;
177 Ok(Arc::new(acceptor.build()))
178 } else {
179 Ok(Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls())?.build()))
180 }
181 }
182}
183
184pub trait HandlerClone {
185 fn clone_box(&self) -> Box<dyn Handler>;
186}
187
188impl<T> HandlerClone for T
190where
191 T: 'static + Handler + Clone,
192{
193 fn clone_box(&self) -> Box<dyn Handler> {
194 Box::new(self.clone())
195 }
196}
197
198impl Clone for Box<dyn Handler> {
200 fn clone(&self) -> Box<dyn Handler> {
201 self.clone_box()
202 }
203}
204pub trait Handler: Send + Sync + HandlerClone + Debug {
205 fn on_request(&mut self, _request: Request, _response: &mut Response);
207 fn on_options(&mut self, response: &mut Response) {
209 response.allow_origins = vec![];
210 response.allow_methods = vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"];
211 response.allow_headers = vec!["Authorization", "X-Forwarded-For", "X-Real-IP"];
212 response.header("Access-Control-Expose-Headers", "Content-Disposition");
213 response.header("Access-Control-Max-Age", 86400.to_string().as_str());
214 }
215 fn on_response(&mut self, response: &mut Response) {
217 if !response.headers.has_key("Access-Control-Allow-Origin") {
218 response.header("Access-Control-Allow-Origin", "*");
219 }
220 if !response.headers.has_key("Access-Control-Allow-Credentials") {
222 response.header("Access-Control-Allow-Credentials", "true");
223 }
224 }
229
230 fn on_frame(&mut self) -> Result<(), HttpError> {
231 Ok(())
232 }
233 fn on_open(&mut self) -> Result<(), HttpError> {
235 Ok(())
236 }
237 fn on_message(&mut self, _msg: Message) -> Result<(), HttpError> {
239 Ok(())
240 }
241 fn on_close(&mut self, _code: CloseCode, _reason: &str) {}
243 fn on_error(&mut self, _err: ErrorCode) {}
245 fn on_shutdown(&mut self) {}
247}
248
249
250#[derive(Clone, Debug)]
251pub enum Connection {
252 KeepAlive,
254 Close,
256 Other(String),
257}
258impl Connection {
259 fn from(value: &str) -> Self {
260 match value.to_lowercase().as_str() {
261 "keep-alive" => Self::KeepAlive,
262 "close" => Self::Close,
263 _ => Self::Other(value.to_string()),
264 }
265 }
266 pub fn str(&self) -> &str {
267 match self {
268 Connection::KeepAlive => "keep-alive",
269 Connection::Close => "close",
270 Connection::Other(name) => name
271 }
272 }
273}
274#[derive(Clone, Debug)]
275pub enum Upgrade {
276 Websocket,
277 Http,
278 H2c,
279 Other(String),
280}
281impl Upgrade {
282 fn from(name: &str) -> Self {
283 match name.to_lowercase().as_str() {
284 "websocket" => Upgrade::Websocket,
285 "http" => Upgrade::Http,
286 "h2c" => Upgrade::H2c,
287 _ => Upgrade::Other(name.to_lowercase().as_str().to_string()),
288 }
289 }
290 pub fn str(&self) -> &str {
291 match self {
292 Upgrade::Websocket => "websocket",
293 Upgrade::Http => "http",
294 Upgrade::H2c => "h2c",
295 Upgrade::Other(name) => name,
296 }
297 }
298}
299
300#[derive(Clone, Debug)]
302#[derive(Default)]
303pub struct Uri {
304 pub uri: String,
306 pub url: String,
308 pub query: String,
310 pub fragment: String,
312 pub path: String,
314 pub path_segments: Vec<String>,
316}
317impl Uri {
318 pub fn from(url: &str) -> Self {
319 let mut decoded_url = br_crypto::encoding::urlencoding_decode(url);
320 let fragment = match decoded_url.rfind('#') {
321 None => String::new(),
322 Some(index) => decoded_url.drain(index..).collect::<String>(),
323 };
324
325 let query = match decoded_url.rfind('?') {
326 None => String::new(),
327 Some(index) => decoded_url.drain(index..).collect::<String>().trim_start_matches("?").to_string(),
328 };
329
330 let path_segments = decoded_url.split("/").map(|x| x.to_string()).filter(|x| !x.is_empty()).collect::<Vec<String>>();
331 Self {
332 uri: decoded_url.clone(),
333 url: url.to_string(),
334 query,
335 fragment,
336 path: decoded_url.clone(),
337 path_segments,
338 }
339 }
340 pub fn get_query_params(&self) -> JsonValue {
342 let text = self.query.split('&').collect::<Vec<&str>>();
343 let mut params = object! {};
344 for item in text {
345 if let Some(index) = item.find('=') {
346 let key = item[..index].to_string();
347 let value = item[index + 1..].to_string();
348 let _ = params.insert(key.as_str(), value);
349 }
350 }
351 params
352 }
353 #[must_use]
354 pub fn to_json(&self) -> JsonValue {
355 object! {
356 url: self.url.clone(),
357 query: self.query.clone(),
358 fragment: self.fragment.clone(),
359 path: self.path.clone(),
360 path_segments: self.path_segments.clone()
361 }
362 }
363}
364
365
366#[derive(Clone, Debug)]
368pub enum Method {
369 POST,
371 GET,
373 HEAD,
375 PUT,
377 DELETE,
379 OPTIONS,
381 PATCH,
382 TRACE,
383 VIEW,
384 CONNECT,
385 PROPFIND,
386 PRI,
388 Other(String),
390}
391
392impl Method {
393 #[must_use]
394 pub fn from(name: &str) -> Self {
395 match name.to_lowercase().as_str() {
396 "post" => Self::POST,
397 "get" => Self::GET,
398 "head" => Self::HEAD,
399 "put" => Self::PUT,
400 "delete" => Self::DELETE,
401 "options" => Self::OPTIONS,
402 "patch" => Self::PATCH,
403 "trace" => Self::TRACE,
404 "view" => Self::VIEW,
405 "propfind" => Self::PROPFIND,
406 "connect" => Self::CONNECT,
407 "pri" => Self::PRI,
408 _ => Self::Other(name.to_string()),
409 }
410 }
411 pub fn str(&mut self) -> &str {
412 match self {
413 Method::POST => "POST",
414 Method::GET => "GET",
415 Method::HEAD => "HEAD",
416 Method::PUT => "PUT",
417 Method::DELETE => "DELETE",
418 Method::OPTIONS => "OPTIONS",
419 Method::PATCH => "PATCH",
420 Method::TRACE => "TRACE",
421 Method::VIEW => "VIEW",
422 Method::PROPFIND => "PROPFIND",
423 Method::PRI => "PRI",
424 Method::CONNECT => "CONNECT",
425 Method::Other(e) => e
426 }
427 }
428}
429
430#[derive(Debug, Clone)]
431pub struct HttpError {
432 pub code: u16,
433 pub body: String,
434}
435
436impl HttpError {
437 pub fn new(code: u16, body: &str) -> Self {
439 Self {
440 code,
441 body: body.to_string(),
442 }
443 }
444}
445#[derive(Debug, Clone)]
447pub enum ContentType {
448 FormData,
449 FormUrlencoded,
450 Json,
451 Xml,
452 Javascript,
453 Text,
454 Html,
455 Stream,
456 Other(String),
457}
458impl ContentType {
459 pub fn from(name: &str) -> Self {
460 match name {
461 "multipart/form-data" => Self::FormData,
462 "application/x-www-form-urlencoded" => Self::FormUrlencoded,
463 "application/json" => Self::Json,
464 "application/xml" | "text/xml" => Self::Xml,
465 "application/javascript" => Self::Javascript,
466 "application/octet-stream" => Self::Stream,
467 "text/html" => Self::Html,
468 "text/plain" => Self::Text,
469 _ => Self::Other(name.to_string()),
470 }
471 }
472 pub fn str(&self) -> &str {
473 match self {
474 ContentType::FormData => "multipart/form-data",
475 ContentType::FormUrlencoded => "application/x-www-form-urlencoded",
476 ContentType::Json => "application/json",
477 ContentType::Xml => "application/xml",
478 ContentType::Javascript => "application/javascript",
479 ContentType::Text => "text/plain",
480 ContentType::Html => "text/html",
481 ContentType::Other(name) => name.as_str(),
482 ContentType::Stream => "application/octet-stream"
483 }
484 }
485}
486#[derive(Clone, Debug)]
488pub enum Authorization {
489 Basic(String, String),
490 Bearer(String),
491 Digest(JsonValue),
492 Other(String),
493}
494impl Authorization {
495 #[must_use]
496 pub fn from(data: &str) -> Self {
497 let authorization = data.split_whitespace().collect::<Vec<&str>>();
498 let mode = authorization[0].to_lowercase();
499 match mode.as_str() {
500 "basic" => {
501 let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
502 let text: Vec<&str> = text.split(':').collect();
503 Self::Basic(text[0].to_string(), text[1].to_string())
504 }
505 "bearer" => Self::Bearer(authorization[1].to_string()),
506 "digest" => {
507 let text = authorization[1..].concat().clone();
508 let text = text.split(',').collect::<Vec<&str>>();
509 let mut params = object! {};
510 for item in &text {
511 let Some(index) = item.find('=') else { continue };
512 let key = item[..index].to_string();
513 let value = item[index + 2..item.len() - 1].to_string();
514 let _ = params.insert(key.as_str(), value);
515 }
516 Self::Digest(params)
517 }
518 _ => Self::Other(data.to_string())
519 }
520 }
521 pub fn str(&mut self) -> JsonValue {
522 match self {
523 Authorization::Basic(key, value) => {
524 let mut data = object! {};
525 data[key.as_str()] = value.clone().into();
526 data
527 }
528 Authorization::Bearer(e) => e.clone().into(),
529 Authorization::Digest(e) => e.clone(),
530 Authorization::Other(name) => name.clone().into(),
531 }
532 }
533}
534#[derive(Clone, Debug)]
536pub enum Content {
537 FormUrlencoded(JsonValue),
538 FormData(JsonValue),
539 Json(JsonValue),
540 Text(JsonValue),
541 Xml(JsonValue),
542 None,
543}
544impl Content {}
545#[derive(Clone, Debug)]
546pub enum FormData {
547 File(String, PathBuf),
548 Field(JsonValue),
549}
550
551#[derive(Clone, Debug)]
553pub enum Language {
554 ZhCN,
555 ZhHans,
556 En,
557 Other(String),
558
559}
560impl Language {
561 #[must_use]
562 pub fn from(name: &str) -> Self {
563 let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
564 let name = binding.as_str();
565 match name {
566 "zh-cn" => Self::ZhCN,
567 "zh-hans" => Self::ZhHans,
568 "en" => Self::En,
569 _ => Self::Other(name.to_string()),
570 }
571 }
572 #[must_use]
573 pub fn str(&self) -> &str {
574 match self {
575 Language::ZhCN => "zh-CN",
576 Language::ZhHans => "zh-Hans",
577 Language::En => "en",
578 Language::Other(e) => e.as_str(),
579 }
580 }
581}
582
583
584#[derive(Clone, Debug)]
586pub enum Encoding {
587 Gzip,
588 Deflate,
589 Br,
590 Bzip2,
591 None,
592}
593impl Encoding {
594 #[must_use]
595 pub fn from(s: &str) -> Encoding {
596 match s.to_lowercase().as_str() {
597 x if x.contains("gzip") => Encoding::Gzip,
598 x if x.contains("deflate") => Encoding::Deflate,
599 x if x.contains("br") => Encoding::Br,
600 x if x.contains("bzip2") => Encoding::Bzip2,
601 _ => Encoding::None,
602 }
603 }
604 #[must_use]
605 pub fn str(&self) -> &str {
606 match self {
607 Encoding::Gzip => "gzip",
608 Encoding::Deflate => "deflate",
609 Encoding::Br => "br",
610 Encoding::None => "",
611 Encoding::Bzip2 => "bzip2",
612 }
613 }
614 pub fn compress(self, data: &[u8]) -> io::Result<Vec<u8>> {
615 match self {
616 Encoding::Gzip => {
617 let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
618 encoder.write_all(data)?;
619 encoder.finish()
620 }
621 _ => Ok(data.to_vec()),
622 }
623 }
624}