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 || {
75 stream.set_nonblocking(true).unwrap();
76 stream.set_read_timeout(Some(Duration::from_secs(5))).unwrap_or_default();
78 stream.set_write_timeout(Some(Duration::from_secs(5))).unwrap_or_default();
80
81
82 let scheme = if config_new.https {
83 match acceptor_new.accept(stream) {
84 Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
85 Err(_) => return Err(Error::other("加载加密请求失败")),
86 }
87 } else {
88 Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
89 };
90
91 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
92 let response = match request.handle() {
93 Ok(()) => Response::new(request.clone(), factory),
94 Err(e) => {
95 error!("处理请求: {:?} {} {}",thread::current().id() ,e.code, e.body);
96 return Err(Error::other(e.body.as_str()));
97 }
98 };
99 match response.handle() {
100 Ok(()) => {}
101 Err(e) => {
102 error!("发送错误失败2: {}",e.to_string());
103 return Err(Error::other(e));
104 }
105 };
106 match request.save_log() {
107 Ok(()) => {}
108 Err(_) => error!("日志记录错误")
109 }
110 Ok(())
111 });
112
113 #[cfg(feature = "pools")]
114 pool.execute(move || -> io::Result<()> {
115
116 stream.set_read_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
118 stream.set_write_timeout(Some(Duration::from_secs(15))).unwrap_or_default();
120
121
122 let scheme = if config_new.https {
123 match acceptor_new.accept(stream) {
124 Ok(e) => Scheme::Https(Arc::new(Mutex::new(BufReader::new(e)))),
125 Err(_) => return Err(Error::other("加载加密请求失败")),
126 }
127 } else {
128 Scheme::Http(Arc::new(Mutex::new(BufReader::new(stream))))
129 };
130 let mut request = Request::new(config_new.clone(), Arc::new(Mutex::new(scheme.clone())));
131 let request_req = request.handle();
132 let mut response = Response::new(request.clone(), factory);
133 match request_req {
134 Ok(()) => {}
135 Err(e) => return match response.status(e.code).txt(e.body.as_str()).send() {
136 Ok(()) => Ok(()),
137 Err(e) => Err(Error::other(e.body.as_str())),
138 }
139 };
140 response.handle()?;
141 match request.save_log() {
142 Ok(()) => {}
143 Err(_) => {
144 error!("日志记录错误");
145 }
146 }
147 Ok(())
148 });
149 }
150 Err(e) => return Err(e),
151 }
152 }
153 #[cfg(feature = "pools")]
154 pool.end();
155 Ok(())
156 }
157
158 fn ssl(config: Config) -> io::Result<Arc<SslAcceptor>> {
159 if config.https {
160 let mut acceptor = SslAcceptor::mozilla_intermediate(SslMethod::tls())?;
161 if !config.tls.key.is_file() {
162 return Err(Error::other(
163 format!("private.key 不存在: {:?}", config.tls.key).as_str(),
164 ));
165 }
166 if !config.tls.certs.is_file() {
167 return Err(Error::other(
168 format!("certificate.pem 不存在: {:?}", config.tls.certs).as_str(),
169 ));
170 }
171 acceptor.set_private_key_file(config.tls.key.clone(), SslFiletype::PEM)?;
172 acceptor.set_certificate_file(config.tls.certs.clone(), SslFiletype::PEM)?;
173 Ok(Arc::new(acceptor.build()))
174 } else {
175 Ok(Arc::new(SslAcceptor::mozilla_intermediate(SslMethod::tls())?.build()))
176 }
177 }
178}
179
180pub trait HandlerClone {
181 fn clone_box(&self) -> Box<dyn Handler>;
182}
183
184impl<T> HandlerClone for T
186where
187 T: 'static + Handler + Clone,
188{
189 fn clone_box(&self) -> Box<dyn Handler> {
190 Box::new(self.clone())
191 }
192}
193
194impl Clone for Box<dyn Handler> {
196 fn clone(&self) -> Box<dyn Handler> {
197 self.clone_box()
198 }
199}
200pub trait Handler: Send + Sync + HandlerClone + Debug {
201 fn on_request(&mut self, _request: Request, _response: &mut Response);
203 fn on_options(&mut self, response: &mut Response) {
205 response.allow_origins = vec![];
206 response.allow_methods = vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"];
207 response.allow_headers = vec!["Authorization", "X-Forwarded-For", "X-Real-IP"];
208 response.header("Access-Control-Expose-Headers", "Content-Disposition");
209 response.header("Access-Control-Max-Age", 86400.to_string().as_str());
210 }
211 fn on_response(&mut self, _request: Request, response: &mut Response) {
213 if !response.headers.has_key("Access-Control-Allow-Origin") {
214 response.header("Access-Control-Allow-Origin", "*");
215 }
216 if !response.headers.has_key("Access-Control-Allow-Credentials") {
218 response.header("Access-Control-Allow-Credentials", "true");
219 }
220 if !response.headers.has_key("Access-Control-Expose-Headers") {
222 response.header("Access-Control-Expose-Headers", "Content-Disposition");
223 }
224 }
225
226 fn on_frame(&mut self) -> Result<(), HttpError> {
227 Ok(())
228 }
229 fn on_open(&mut self) -> Result<(), HttpError> {
231 Ok(())
232 }
233 fn on_message(&mut self, _msg: Message) -> Result<(), HttpError> {
235 Ok(())
236 }
237 fn on_close(&mut self, _code: CloseCode, _reason: &str) {}
239 fn on_error(&mut self, _err: ErrorCode) {}
241 fn on_shutdown(&mut self) {}
243}
244
245
246#[derive(Clone, Debug)]
247pub enum Connection {
248 KeepAlive,
250 Close,
252 Other(String),
253}
254impl Connection {
255 fn from(value: &str) -> Self {
256 match value.to_lowercase().as_str() {
257 "keep-alive" => Self::KeepAlive,
258 "close" => Self::Close,
259 _ => Self::Other(value.to_string()),
260 }
261 }
262 pub fn str(&self) -> &str {
263 match self {
264 Connection::KeepAlive => "keep-alive",
265 Connection::Close => "close",
266 Connection::Other(name) => name
267 }
268 }
269}
270#[derive(Clone, Debug)]
271pub enum Upgrade {
272 Websocket,
273 Http,
274 Other(String),
275}
276impl Upgrade {
277 fn from(name: &str) -> Self {
278 match name.to_lowercase().as_str() {
279 "websocket" => Self::Websocket,
280 "http" => Self::Http,
281 _ => Self::Other(name.to_lowercase().as_str().to_string()),
282 }
283 }
284 pub fn str(&self) -> &str {
285 match self {
286 Self::Websocket => "websocket",
287 Self::Http => "http",
288 Self::Other(name) => name,
289 }
290 }
291}
292
293#[derive(Clone, Debug)]
295#[derive(Default)]
296pub struct Uri {
297 pub uri: String,
299 pub url: String,
301 pub query: String,
303 pub fragment: String,
305 pub path: String,
307 pub path_segments: Vec<String>,
309}
310impl Uri {
311 pub fn from(url: &str) -> Self {
312 let mut decoded_url = br_crypto::encoding::urlencoding_decode(url);
313 let fragment = match decoded_url.rfind('#') {
314 None => String::new(),
315 Some(index) => decoded_url.drain(index..).collect::<String>(),
316 };
317
318 let query = match decoded_url.rfind('?') {
319 None => String::new(),
320 Some(index) => decoded_url.drain(index..).collect::<String>().trim_start_matches("?").to_string(),
321 };
322
323 let path_segments = decoded_url.split("/").map(|x| x.to_string()).filter(|x| !x.is_empty()).collect::<Vec<String>>();
324 Self {
325 uri: decoded_url.clone(),
326 url: url.to_string(),
327 query,
328 fragment,
329 path: decoded_url.clone(),
330 path_segments,
331 }
332 }
333 pub fn get_query_params(&self) -> JsonValue {
335 let text = self.query.split('&').collect::<Vec<&str>>();
336 let mut params = object! {};
337 for item in text {
338 if let Some(index) = item.find('=') {
339 let key = item[..index].to_string();
340 let value = item[index + 1..].to_string();
341 let _ = params.insert(key.as_str(), value);
342 }
343 }
344 params
345 }
346 #[must_use]
347 pub fn to_json(&self) -> JsonValue {
348 object! {
349 url: self.url.clone(),
350 query: self.query.clone(),
351 fragment: self.fragment.clone(),
352 path: self.path.clone(),
353 path_segments: self.path_segments.clone()
354 }
355 }
356}
357
358
359#[derive(Clone, Debug)]
361pub enum Method {
362 POST,
364 GET,
366 HEAD,
368 PUT,
370 DELETE,
372 OPTIONS,
374 PATCH,
375 TRACE,
376 VIEW,
377 CONNECT,
378 PROPFIND,
379 PRI,
381 Other(String),
383}
384
385impl Method {
386 #[must_use]
387 pub fn from(name: &str) -> Self {
388 match name.to_lowercase().as_str() {
389 "post" => Self::POST,
390 "get" => Self::GET,
391 "head" => Self::HEAD,
392 "put" => Self::PUT,
393 "delete" => Self::DELETE,
394 "options" => Self::OPTIONS,
395 "patch" => Self::PATCH,
396 "trace" => Self::TRACE,
397 "view" => Self::VIEW,
398 "propfind" => Self::PROPFIND,
399 "connect" => Self::CONNECT,
400 "pri" => Self::PRI,
401 _ => Self::Other(name.to_string()),
402 }
403 }
404 pub fn str(&mut self) -> &str {
405 match self {
406 Method::POST => "POST",
407 Method::GET => "GET",
408 Method::HEAD => "HEAD",
409 Method::PUT => "PUT",
410 Method::DELETE => "DELETE",
411 Method::OPTIONS => "OPTIONS",
412 Method::PATCH => "PATCH",
413 Method::TRACE => "TRACE",
414 Method::VIEW => "VIEW",
415 Method::PROPFIND => "PROPFIND",
416 Method::PRI => "PRI",
417 Method::CONNECT => "CONNECT",
418 Method::Other(e) => e
419 }
420 }
421}
422
423#[derive(Debug, Clone)]
424pub struct HttpError {
425 pub code: u16,
426 pub body: String,
427}
428
429impl HttpError {
430 pub fn new(code: u16, body: &str) -> Self {
432 Self {
433 code,
434 body: body.to_string(),
435 }
436 }
437}
438#[derive(Debug, Clone)]
440pub enum ContentType {
441 FormData,
442 FormUrlencoded,
443 Json,
444 Xml,
445 Javascript,
446 Text,
447 Html,
448 Stream,
449 Other(String),
450}
451impl ContentType {
452 pub fn from(name: &str) -> Self {
453 match name {
454 "multipart/form-data" => Self::FormData,
455 "application/x-www-form-urlencoded" => Self::FormUrlencoded,
456 "application/json" => Self::Json,
457 "application/xml" | "text/xml" => Self::Xml,
458 "application/javascript" => Self::Javascript,
459 "application/octet-stream" => Self::Stream,
460 "text/html" => Self::Html,
461 "text/plain" => Self::Text,
462 _ => Self::Other(name.to_string()),
463 }
464 }
465 pub fn str(&self) -> &str {
466 match self {
467 ContentType::FormData => "multipart/form-data",
468 ContentType::FormUrlencoded => "application/x-www-form-urlencoded",
469 ContentType::Json => "application/json",
470 ContentType::Xml => "application/xml",
471 ContentType::Javascript => "application/javascript",
472 ContentType::Text => "text/plain",
473 ContentType::Html => "text/html",
474 ContentType::Other(name) => name.as_str(),
475 ContentType::Stream => "application/octet-stream"
476 }
477 }
478}
479#[derive(Clone, Debug)]
481pub enum Authorization {
482 Basic(String, String),
483 Bearer(String),
484 Digest(JsonValue),
485 Other(String),
486}
487impl Authorization {
488 #[must_use]
489 pub fn from(data: &str) -> Self {
490 let authorization = data.split_whitespace().collect::<Vec<&str>>();
491 let mode = authorization[0].to_lowercase();
492 match mode.as_str() {
493 "basic" => {
494 let text = br_crypto::base64::decode(&authorization[1].to_string().clone());
495 let text: Vec<&str> = text.split(':').collect();
496 Self::Basic(text[0].to_string(), text[1].to_string())
497 }
498 "bearer" => Self::Bearer(authorization[1].to_string()),
499 "digest" => {
500 let text = authorization[1..].concat().clone();
501 let text = text.split(',').collect::<Vec<&str>>();
502 let mut params = object! {};
503 for item in &text {
504 let Some(index) = item.find('=') else { continue };
505 let key = item[..index].to_string();
506 let value = item[index + 2..item.len() - 1].to_string();
507 let _ = params.insert(key.as_str(), value);
508 }
509 Self::Digest(params)
510 }
511 _ => Self::Other(data.to_string())
512 }
513 }
514 pub fn str(&mut self) -> JsonValue {
515 match self {
516 Authorization::Basic(key, value) => {
517 let mut data = object! {};
518 data[key.as_str()] = value.clone().into();
519 data
520 }
521 Authorization::Bearer(e) => e.clone().into(),
522 Authorization::Digest(e) => e.clone(),
523 Authorization::Other(name) => name.clone().into(),
524 }
525 }
526}
527#[derive(Clone, Debug)]
529pub enum Content {
530 FormUrlencoded(JsonValue),
531 FormData(JsonValue),
532 Json(JsonValue),
533 Text(JsonValue),
534 Xml(JsonValue),
535 None,
536}
537impl Content {}
538#[derive(Clone, Debug)]
539pub enum FormData {
540 File(String, PathBuf),
541 Field(JsonValue),
542}
543
544#[derive(Clone, Debug)]
546pub enum Language {
547 ZhCN,
548 ZhHans,
549 En,
550 Other(String),
551
552}
553impl Language {
554 #[must_use]
555 pub fn from(name: &str) -> Self {
556 let binding = name.split(',').collect::<Vec<&str>>()[0].trim().to_lowercase();
557 let name = binding.as_str();
558 match name {
559 "zh-cn" => Self::ZhCN,
560 "zh-hans" => Self::ZhHans,
561 "en" => Self::En,
562 _ => Self::Other(name.to_string()),
563 }
564 }
565 #[must_use]
566 pub fn str(&self) -> &str {
567 match self {
568 Language::ZhCN => "zh-CN",
569 Language::ZhHans => "zh-Hans",
570 Language::En => "en",
571 Language::Other(e) => e.as_str(),
572 }
573 }
574}
575
576
577#[derive(Clone, Debug)]
579pub enum Encoding {
580 Gzip,
581 Deflate,
582 Br,
583 Bzip2,
584 None,
585}
586impl Encoding {
587 #[must_use]
588 pub fn from(s: &str) -> Encoding {
589 match s.to_lowercase().as_str() {
590 x if x.contains("gzip") => Encoding::Gzip,
591 x if x.contains("deflate") => Encoding::Deflate,
592 x if x.contains("br") => Encoding::Br,
593 x if x.contains("bzip2") => Encoding::Bzip2,
594 _ => Encoding::None,
595 }
596 }
597 #[must_use]
598 pub fn str(&self) -> &str {
599 match self {
600 Encoding::Gzip => "gzip",
601 Encoding::Deflate => "deflate",
602 Encoding::Br => "br",
603 Encoding::None => "",
604 Encoding::Bzip2 => "bzip2",
605 }
606 }
607 pub fn compress(self, data: &[u8]) -> io::Result<Vec<u8>> {
608 match self {
609 Encoding::Gzip => {
610 let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
611 encoder.write_all(data)?;
612 encoder.finish()
613 }
614 _ => Ok(data.to_vec()),
615 }
616 }
617}