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};
14use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
15use std::io::{BufReader, Error, Write};
16use std::net::{IpAddr, SocketAddr, TcpListener};
17use std::sync::{Arc, Mutex};
18use std::time::{Duration};
19use std::{io, thread};
20use std::fmt::Debug;
21use std::path::PathBuf;
22use flate2::Compression;
23use flate2::write::GzEncoder;
24use json::{object, JsonValue};
25
26#[derive(Clone, Debug)]
28pub struct WebServer;
29
30impl WebServer {
31 pub fn new_service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) {
33 loop {
34 match WebServer::service(config.clone(), factory) {
35 Ok(()) => {}
36 Err(e) => error!("服务器错误: {}[{}]: {}", file!(), line!(), e),
37 }
38 warn!("服务器 1秒后重启");
39 thread::sleep(Duration::from_secs(1));
40 }
41 }
42 fn service(config: Config, factory: fn(out: Websocket) -> Box<dyn Handler>) -> io::Result<()> {
43 info!("==================== 网络服务 服务信息 ====================");
44 info!("日志记录: {}",if config.log {"开启"} else {"关闭"});
45 info!("调试模式: {}",if config.debug { "开启" } else { "关闭" });
46 info!("地 址: {}", config.host);
47 info!("端 口 号: {}", config.port);
48 info!("服务地址: {}://{}{}",if config.https { "https" } else { "http" },config.host,if config.port > 0 {format!(":{}", config.port)} else {String::new()});
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 addrs = [SocketAddr::from((
60 IpAddr::V4(config.host.parse().unwrap()),
61 config.port,
62 ))];
63 let listener = TcpListener::bind(&addrs[..])?;
64 info!("==================== 网络服务 启动成功 ====================");
65
66 let acceptor = Self::ssl(config.clone())?;
67 #[cfg(feature = "pools")] let mut pool = pools::Pool::new(config.pools_max * 4);
68 for stream in listener.incoming() {
69 match stream {
70 Ok(stream) => {
71 let config_new = config.clone();
72 let acceptor_new = acceptor.clone();
73 #[cfg(not(feature = "pools"))]
74 thread::spawn(move || -> io::Result<()> {
75
76 stream.set_read_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
78
79 stream.set_write_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
81
82
83 let scheme = if config_new.https {
84 match acceptor_new.accept(stream) {
85 Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
86 Err(_) => return Err(Error::other("加载加密请求失败")),
87 }
88 } else {
89 Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
90 };
91
92 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
93 let request_req = request.handle();
94 let mut response = Response::new(request.clone(), factory);
95 match request_req {
96 Ok(()) => {}
97 Err(e) => {
98 return match response.status(e.code).txt(e.body.as_str()).send() {
99 Ok(()) => Ok(()),
100 Err(e) => Err(Error::other(e.body.as_str())),
101 }
102 }
103 };
104 response.handle()?;
105 match request.save_log() {
106 Ok(()) => {}
107 Err(_) => error!("日志记录错误")
108 }
109 Ok(())
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
126 let scheme = if config_new.https {
127 match acceptor_new.accept(stream) {
128 Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
129 Err(_) => return Err(Error::other("加载加密请求失败")),
130 }
131 } else {
132 Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
133 };
134 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
135 let request_req = request.handle();
136 let mut response = Response::new(request.clone(), factory);
137 match request_req {
138 Ok(()) => {}
139 Err(e) => return match response.status(e.code).txt(e.body.as_str()).send() {
140 Ok(()) => Ok(()),
141 Err(e) => Err(Error::other(e.body.as_str())),
142 }
143 };
144 response.handle()?;
145 match request.save_log() {
146 Ok(()) => {}
147 Err(_) => {
148 error!("日志记录错误");
149 }
150 }
151 Ok(())
152 });
153 }
154 Err(e) => return Err(e),
155 }
156 }
157 #[cfg(feature = "pools")]
158 pool.end();
159 Ok(())
160 }
161
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, request: Request, response: &mut Response);
217
218 fn on_frame(&mut self) -> Result<(), HttpError> {
219 Ok(())
220 }
221 fn on_open(&mut self) -> Result<(), HttpError> {
223 Ok(())
224 }
225 fn on_message(&mut self, _msg: Message) -> Result<(), HttpError> {
227 Ok(())
228 }
229 fn on_close(&mut self, _code: CloseCode, _reason: &str) {}
231 fn on_error(&mut self, _err: ErrorCode) {}
233 fn on_shutdown(&mut self) {}
235}
236
237
238#[derive(Clone, Debug)]
239pub enum Connection {
240 KeepAlive,
242 Close,
244 Other(String),
245}
246impl Connection {
247 fn from(value: &str) -> Self {
248 match value.to_lowercase().as_str() {
249 "keep-alive" => Self::KeepAlive,
250 "close" => Self::Close,
251 _ => Self::Other(value.to_string()),
252 }
253 }
254 pub fn str(&self) -> &str {
255 match self {
256 Connection::KeepAlive => "keep-alive",
257 Connection::Close => "close",
258 Connection::Other(name) => name
259 }
260 }
261}
262#[derive(Clone, Debug)]
263pub enum Upgrade {
264 Websocket,
265 Http,
266 Other(String),
267}
268impl Upgrade {
269 fn from(name: &str) -> Self {
270 match name.to_lowercase().as_str() {
271 "websocket" => Self::Websocket,
272 "http" => Self::Http,
273 _ => Self::Other(name.to_lowercase().as_str().to_string()),
274 }
275 }
276 pub fn str(&self) -> &str {
277 match self {
278 Self::Websocket => "websocket",
279 Self::Http => "http",
280 Self::Other(name) => name,
281 }
282 }
283}
284
285#[derive(Clone, Debug)]
287#[derive(Default)]
288pub struct Uri {
289 pub uri: String,
291 pub url: String,
293 pub query: String,
295 pub fragment: String,
297 pub path: String,
299 pub path_segments: Vec<String>,
301}
302impl Uri {
303 pub fn from(url: &str) -> Self {
304 let mut decoded_url = br_crypto::encoding::urlencoding_decode(url);
305 let fragment = match decoded_url.rfind('#') {
306 None => String::new(),
307 Some(index) => decoded_url.drain(index..).collect::<String>(),
308 };
309
310 let query = match decoded_url.rfind('?') {
311 None => String::new(),
312 Some(index) => decoded_url.drain(index..).collect::<String>().trim_start_matches("?").to_string(),
313 };
314
315 let path_segments = decoded_url.split("/").map(|x| x.to_string()).filter(|x| !x.is_empty()).collect::<Vec<String>>();
316 Self {
317 uri: decoded_url.clone(),
318 url: url.to_string(),
319 query,
320 fragment,
321 path: decoded_url.clone(),
322 path_segments,
323 }
324 }
325 pub fn get_query_params(&self) -> JsonValue {
327 let text = self.query.split('&').collect::<Vec<&str>>();
328 let mut params = object! {};
329 for item in text {
330 if let Some(index) = item.find('=') {
331 let key = item[..index].to_string();
332 let value = item[index + 1..].to_string();
333 let _ = params.insert(key.as_str(), value);
334 }
335 }
336 params
337 }
338 #[must_use]
339 pub fn to_json(&self) -> JsonValue {
340 object! {
341 url: self.url.clone(),
342 query: self.query.clone(),
343 fragment: self.fragment.clone(),
344 path: self.path.clone(),
345 path_segments: self.path_segments.clone()
346 }
347 }
348}
349
350
351#[derive(Clone, Debug)]
353pub enum Method {
354 POST,
356 GET,
358 HEAD,
360 PUT,
362 DELETE,
364 OPTIONS,
366 PATCH,
367 TRACE,
368 VIEW,
369 CONNECT,
370 PROPFIND,
371 PRI,
373 Other(String),
375}
376
377impl Method {
378 #[must_use]
379 pub fn from(name: &str) -> Self {
380 match name.to_lowercase().as_str() {
381 "post" => Self::POST,
382 "get" => Self::GET,
383 "head" => Self::HEAD,
384 "put" => Self::PUT,
385 "delete" => Self::DELETE,
386 "options" => Self::OPTIONS,
387 "patch" => Self::PATCH,
388 "trace" => Self::TRACE,
389 "view" => Self::VIEW,
390 "propfind" => Self::PROPFIND,
391 "connect" => Self::CONNECT,
392 "pri" => Self::PRI,
393 _ => Self::Other(name.to_string()),
394 }
395 }
396 pub fn str(&mut self) -> &str {
397 match self {
398 Method::POST => "POST",
399 Method::GET => "GET",
400 Method::HEAD => "HEAD",
401 Method::PUT => "PUT",
402 Method::DELETE => "DELETE",
403 Method::OPTIONS => "OPTIONS",
404 Method::PATCH => "PATCH",
405 Method::TRACE => "TRACE",
406 Method::VIEW => "VIEW",
407 Method::PROPFIND => "PROPFIND",
408 Method::PRI => "PRI",
409 Method::CONNECT => "CONNECT",
410 Method::Other(e) => e
411 }
412 }
413}
414
415#[derive(Debug, Clone)]
416pub struct HttpError {
417 pub code: u16,
418 pub body: String,
419}
420
421impl HttpError {
422 pub fn new(code: u16, body: &str) -> Self {
424 Self {
425 code,
426 body: body.to_string(),
427 }
428 }
429}
430#[derive(Debug, Clone)]
432pub enum ContentType {
433 FormData,
434 FormUrlencoded,
435 Json,
436 Xml,
437 Javascript,
438 Text,
439 Html,
440 Stream,
441 Other(String),
442}
443impl ContentType {
444 pub fn from(name: &str) -> Self {
445 match name {
446 "multipart/form-data" => Self::FormData,
447 "application/x-www-form-urlencoded" => Self::FormUrlencoded,
448 "application/json" => Self::Json,
449 "application/xml" | "text/xml" => Self::Xml,
450 "application/javascript" => Self::Javascript,
451 "application/octet-stream" => Self::Stream,
452 "text/html" => Self::Html,
453 "text/plain" => Self::Text,
454 _ => Self::Other(name.to_string()),
455 }
456 }
457 pub fn str(&self) -> &str {
458 match self {
459 ContentType::FormData => "multipart/form-data",
460 ContentType::FormUrlencoded => "application/x-www-form-urlencoded",
461 ContentType::Json => "application/json",
462 ContentType::Xml => "application/xml",
463 ContentType::Javascript => "application/javascript",
464 ContentType::Text => "text/plain",
465 ContentType::Html => "text/html",
466 ContentType::Other(name) => name.as_str(),
467 ContentType::Stream => "application/octet-stream"
468 }
469 }
470}
471#[derive(Clone, Debug)]
473pub enum Authorization {
474 Basic(String, String),
475 Bearer(String),
476 Digest(JsonValue),
477 Other(String),
478}
479impl Authorization {
480 #[must_use]
481 pub fn from(data: &str) -> Self {
482 let authorization = data.split_whitespace().collect::<Vec<&str>>();
483 let mode = authorization[0].to_lowercase();
484 match mode.as_str() {
485 "basic" => {
486 let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
487 let text: Vec<&str> = text.split(':').collect();
488 Self::Basic(text[0].to_string(), text[1].to_string())
489 }
490 "bearer" => Self::Bearer(authorization[1].to_string()),
491 "digest" => {
492 let text = authorization[1..].concat().clone();
493 let text = text.split(',').collect::<Vec<&str>>();
494 let mut params = object! {};
495 for item in &text {
496 let Some(index) = item.find('=') else { continue };
497 let key = item[..index].to_string();
498 let value = item[index + 2..item.len() - 1].to_string();
499 let _ = params.insert(key.as_str(), value);
500 }
501 Self::Digest(params)
502 }
503 _ => Self::Other(data.to_string())
504 }
505 }
506 pub fn str(&mut self) -> JsonValue {
507 match self {
508 Authorization::Basic(key, value) => {
509 let mut data = object! {};
510 data[key.as_str()] = value.clone().into();
511 data
512 }
513 Authorization::Bearer(e) => e.clone().into(),
514 Authorization::Digest(e) => e.clone(),
515 Authorization::Other(name) => name.clone().into(),
516 }
517 }
518}
519#[derive(Clone, Debug)]
521pub enum Content {
522 FormUrlencoded(JsonValue),
523 FormData(JsonValue),
524 Json(JsonValue),
525 Text(JsonValue),
526 Xml(JsonValue),
527 None,
528}
529impl Content {}
530#[derive(Clone, Debug)]
531pub enum FormData {
532 File(String, PathBuf),
533 Field(JsonValue),
534}
535
536#[derive(Clone, Debug)]
538pub enum Language {
539 ZhCN,
540 ZhHans,
541 En,
542 Other(String),
543
544}
545impl Language {
546 #[must_use]
547 pub fn from(name: &str) -> Self {
548 let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
549 let name = binding.as_str();
550 match name {
551 "zh-cn" => Self::ZhCN,
552 "zh-hans" => Self::ZhHans,
553 "en" => Self::En,
554 _ => Self::Other(name.to_string()),
555 }
556 }
557 #[must_use]
558 pub fn str(&self) -> &str {
559 match self {
560 Language::ZhCN => "zh-CN",
561 Language::ZhHans => "zh-Hans",
562 Language::En => "en",
563 Language::Other(e) => e.as_str(),
564 }
565 }
566}
567
568
569#[derive(Clone, Debug)]
571pub enum Encoding {
572 Gzip,
573 Deflate,
574 Br,
575 Bzip2,
576 None,
577}
578impl Encoding {
579 #[must_use]
580 pub fn from(s: &str) -> Encoding {
581 match s.to_lowercase().as_str() {
582 x if x.contains("gzip") => Encoding::Gzip,
583 x if x.contains("deflate") => Encoding::Deflate,
584 x if x.contains("br") => Encoding::Br,
585 x if x.contains("bzip2") => Encoding::Bzip2,
586 _ => Encoding::None,
587 }
588 }
589 #[must_use]
590 pub fn str(&self) -> &str {
591 match self {
592 Encoding::Gzip => "gzip",
593 Encoding::Deflate => "deflate",
594 Encoding::Br => "br",
595 Encoding::None => "",
596 Encoding::Bzip2 => "bzip2",
597 }
598 }
599 pub fn compress(self, data: &[u8]) -> io::Result<Vec<u8>> {
600 match self {
601 Encoding::Gzip => {
602 let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
603 encoder.write_all(data)?;
604 encoder.finish()
605 }
606 _ => Ok(data.to_vec()),
607 }
608 }
609}