http_server_api.rs 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /*************************************************************************
  2. *
  3. * Copyright (C) 2018-2024 Ruilin Peng (Nick) <[email protected]>.
  4. *
  5. * smartdns is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * smartdns is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. use crate::db::*;
  19. use crate::dns_log;
  20. use crate::http_api_msg::*;
  21. use crate::http_error::*;
  22. use crate::http_jwt::*;
  23. use crate::http_server::*;
  24. use crate::http_server_stream;
  25. use crate::smartdns;
  26. use crate::smartdns::*;
  27. use crate::utils;
  28. use crate::Plugin;
  29. use bytes::Bytes;
  30. use http_body_util::BodyExt;
  31. use http_body_util::Full;
  32. use hyper::{body, Method, Request, Response, StatusCode};
  33. use matchit::Router;
  34. use std::collections::HashMap;
  35. use std::future::Future;
  36. use std::pin::Pin;
  37. use std::sync::Arc;
  38. use url::form_urlencoded;
  39. const PASSWORD_CONFIG_KEY: &str = "smartdns-ui.password";
  40. const REST_API_PATH: &str = "/api";
  41. type APIRouteFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
  42. type APIRouterFun = fn(
  43. this: Arc<HttpServer>,
  44. param: APIRouteParam,
  45. req: Request<body::Incoming>,
  46. ) -> APIRouteFuture<'static, Result<Response<Full<Bytes>>, HttpError>>;
  47. type APIRouteParam = HashMap<String, String>;
  48. pub struct APIRouter {
  49. pub method: Method,
  50. pub auth: bool,
  51. pub handler: APIRouterFun,
  52. }
  53. pub struct API {
  54. router: Router<std::collections::HashMap<Method, APIRouter>>,
  55. }
  56. macro_rules! APIRoute {
  57. ( $fn:path) => {
  58. |r, p, h| Box::pin($fn(r, p, h))
  59. };
  60. }
  61. #[allow(dead_code)]
  62. impl API {
  63. #[rustfmt::skip]
  64. pub fn new() -> Self {
  65. let mut api = API {
  66. router: Router::new(),
  67. };
  68. api.register(Method::PUT, "/api/service/restart", true, APIRoute!(API::api_service_restart));
  69. api.register(Method::PUT, "/api/cache/flush", true, APIRoute!(API::api_cache_flush));
  70. api.register(Method::GET, "/api/cache/count", true, APIRoute!(API::api_cache_count));
  71. api.register(Method::POST, "/api/auth/login", false, APIRoute!(API::api_auth_login));
  72. api.register(Method::POST, "/api/auth/logout", false, APIRoute!(API::api_auth_logout));
  73. api.register(Method::GET, "/api/auth/check", true, APIRoute!(API::api_auth_check));
  74. api.register(Method::PUT, "/api/auth/password", false, APIRoute!(API::api_auth_change_password));
  75. api.register(Method::POST, "/api/auth/refresh", true, APIRoute!(API::api_auth_refresh));
  76. api.register(Method::GET, "/api/domain", true, APIRoute!(API::api_domain_get_list));
  77. api.register(Method::DELETE, "/api/domain", true, APIRoute!(API::api_domain_delete_list));
  78. api.register(Method::GET, "/api/domain/count", true, APIRoute!(API::api_domain_get_list_count));
  79. api.register(Method::GET, "/api/domain/{id}", true, APIRoute!(API::api_domain_get_by_id));
  80. api.register(Method::DELETE, "/api/domain/{id}", true, APIRoute!(API::api_domain_delete_by_id));
  81. api.register(Method::GET, "/api/client", true, APIRoute!(API::api_client_get_list));
  82. api.register(Method::DELETE, "/api/client/{id}", true, APIRoute!(API::api_client_delete_by_id));
  83. api.register(Method::GET, "/api/log/stream", true, APIRoute!(API::api_log_stream));
  84. api.register(Method::PUT, "/api/log/level", true, APIRoute!(API::api_log_set_level));
  85. api.register(Method::GET, "/api/log/level", true, APIRoute!(API::api_log_get_level));
  86. api.register(Method::GET, "/api/server/version", false, APIRoute!(API::api_server_version));
  87. api.register(Method::GET, "/api/upstream-server", true, APIRoute!(API::api_upstream_server_get_list));
  88. api.register(Method::GET, "/api/config/settings", true, APIRoute!(API::api_config_get_settings));
  89. api.register(Method::PUT, "/api/config/settings", true, APIRoute!(API::api_config_set_settings));
  90. api.register(Method::GET, "/api/stats/top/client", true, APIRoute!(API::api_stats_get_top_client));
  91. api.register(Method::GET, "/api/stats/top/domain", true, APIRoute!(API::api_stats_get_top_domain));
  92. api.register(Method::GET, "/api/stats/metrics", true, APIRoute!(API::api_stats_get_metrics));
  93. api.register(Method::GET, "/api/stats/overview", true, APIRoute!(API::api_stats_get_overview));
  94. api.register(Method::GET, "/api/stats/hourly-query-count", true, APIRoute!(API::api_stats_get_hourly_query_count));
  95. api.register(Method::GET, "/api/stats/daily-query-count", true, APIRoute!(API::api_stats_get_daily_query_count));
  96. api.register(Method::PUT, "/api/stats/refresh", true, APIRoute!(API::api_stats_refresh));
  97. api.register(Method::GET, "/api/whois", true, APIRoute!(API::api_whois));
  98. api.register(Method::GET, "/api/tool/term", true, APIRoute!(API::api_tool_term));
  99. api
  100. }
  101. pub fn register(&mut self, method: Method, path: &str, auth: bool, handler: APIRouterFun) {
  102. let route_data = APIRouter {
  103. method: method.clone(),
  104. auth: auth,
  105. handler: handler,
  106. };
  107. let mut m = self.router.at_mut(path);
  108. if m.is_err() {
  109. let map_new = std::collections::HashMap::new();
  110. _ = self.router.insert(path, map_new);
  111. m = self.router.at_mut(path);
  112. if m.is_err() {
  113. return;
  114. }
  115. }
  116. let m = m.unwrap();
  117. let mutmethod_map = m.value;
  118. mutmethod_map.insert(method, route_data);
  119. }
  120. pub fn get_router(&self, method: &Method, path: &str) -> Option<(&APIRouter, APIRouteParam)> {
  121. let m = self.router.at(path);
  122. if m.is_err() {
  123. return None;
  124. }
  125. let m = m.unwrap();
  126. let method_map = m.value;
  127. let route_data = method_map.get(method);
  128. if route_data.is_none() {
  129. return None;
  130. }
  131. let route_data = route_data.unwrap();
  132. let mut param = APIRouteParam::new();
  133. m.params.iter().for_each(|(k, v)| {
  134. let v = v.to_string();
  135. param.insert(k.to_string(), v);
  136. });
  137. Some((route_data, param))
  138. }
  139. fn get_params(req: &Request<body::Incoming>) -> HashMap<String, String> {
  140. let b = req.uri().query().unwrap_or("").to_string();
  141. form_urlencoded::parse(b.as_ref())
  142. .into_owned()
  143. .collect::<HashMap<String, String>>()
  144. }
  145. fn params_parser_value<T: std::str::FromStr>(v: Option<&String>) -> Option<T> {
  146. if v.is_none() {
  147. return None;
  148. }
  149. let v = v.unwrap();
  150. match T::from_str(&v) {
  151. Ok(value) => Some(value),
  152. Err(_) => None,
  153. }
  154. }
  155. fn params_get_value<T: std::str::FromStr>(
  156. params: &HashMap<String, String>,
  157. key: &str,
  158. ) -> Option<T> {
  159. let v = params.get(key);
  160. if v.is_none() {
  161. return None;
  162. }
  163. let v = v.unwrap();
  164. API::params_parser_value(Some(v))
  165. }
  166. fn params_get_value_default<T: std::str::FromStr>(
  167. params: &HashMap<String, String>,
  168. key: &str,
  169. default: T,
  170. ) -> Result<T, HttpError> {
  171. let v = params.get(key);
  172. if v.is_none() {
  173. return Ok(default);
  174. }
  175. let v = v.unwrap();
  176. match v.parse::<T>() {
  177. Ok(v) => return Ok(v),
  178. Err(_) => {
  179. return Err(HttpError::new(
  180. StatusCode::BAD_REQUEST,
  181. format!("Invalid parameter: {}", key),
  182. ));
  183. }
  184. }
  185. }
  186. pub fn response_error(code: StatusCode, msg: &str) -> Result<Response<Full<Bytes>>, HttpError> {
  187. let bytes = Bytes::from(api_msg_error(msg));
  188. let mut response = Response::new(Full::new(bytes));
  189. response
  190. .headers_mut()
  191. .insert("Content-Type", "application/json".parse().unwrap());
  192. *response.status_mut() = code;
  193. Ok(response)
  194. }
  195. pub fn response_build(
  196. code: StatusCode,
  197. body: String,
  198. ) -> Result<Response<Full<Bytes>>, HttpError> {
  199. let mut response = Response::new(Full::new(Bytes::from(body)));
  200. response
  201. .headers_mut()
  202. .insert("Content-Type", "application/json".parse().unwrap());
  203. *response.status_mut() = code;
  204. Ok(response)
  205. }
  206. async fn api_auth_refresh(
  207. this: Arc<HttpServer>,
  208. _param: APIRouteParam,
  209. req: Request<body::Incoming>,
  210. ) -> Result<Response<Full<Bytes>>, HttpError> {
  211. let token = HttpServer::get_token_from_header(&req)?;
  212. let unauth_response =
  213. || API::response_error(StatusCode::UNAUTHORIZED, "Incorrect username or password.");
  214. if token.is_none() {
  215. return unauth_response();
  216. }
  217. let token = token.unwrap();
  218. let conf = this.get_conf();
  219. let jtw = Jwt::new(
  220. &conf.username.as_str(),
  221. conf.password.as_str(),
  222. "",
  223. conf.token_expired_time,
  224. );
  225. let calim = jtw.decode_token(token.as_str());
  226. if calim.is_err() {
  227. return unauth_response();
  228. }
  229. let token_new = jtw.refresh_token(token.as_str());
  230. if token_new.is_err() {
  231. return unauth_response();
  232. }
  233. let token_new = token_new.unwrap();
  234. let mut resp = API::response_build(
  235. StatusCode::OK,
  236. api_msg_auth_token(&token_new.token, &token_new.expire),
  237. );
  238. let cookie_token = format!("Bearer {}", token_new.token);
  239. let token_urlencode = urlencoding::encode(cookie_token.as_str());
  240. let cookie = format!(
  241. "token={}; HttpOnly; Max-Age={}; Path={}",
  242. token_urlencode, token_new.expire, REST_API_PATH
  243. );
  244. resp.as_mut()
  245. .unwrap()
  246. .headers_mut()
  247. .insert(hyper::header::SET_COOKIE, cookie.parse().unwrap());
  248. resp
  249. }
  250. /// Login
  251. /// API: POST /api/auth/login
  252. /// body:
  253. /// {
  254. /// "username": "admin"
  255. /// "password": "password"
  256. /// }
  257. async fn api_auth_login(
  258. this: Arc<HttpServer>,
  259. _param: APIRouteParam,
  260. req: Request<body::Incoming>,
  261. ) -> Result<Response<Full<Bytes>>, HttpError> {
  262. let whole_body = String::from_utf8(req.into_body().collect().await?.to_bytes().into())?;
  263. let userinfo = api_msg_parse_auth(whole_body.as_str());
  264. if let Err(e) = userinfo {
  265. return API::response_error(StatusCode::BAD_REQUEST, e.to_string().as_str());
  266. }
  267. let conf = this.get_conf();
  268. let userinfo = userinfo.unwrap();
  269. if !this.login_attempts_check() {
  270. return API::response_error(
  271. StatusCode::FORBIDDEN,
  272. "Too many login attempts, please try again later.",
  273. );
  274. }
  275. if userinfo.username != conf.username
  276. || utils::verify_password(userinfo.password.as_str(), conf.password.as_str()) != true
  277. {
  278. return API::response_error(
  279. StatusCode::UNAUTHORIZED,
  280. "Incorrect username or password.",
  281. );
  282. }
  283. this.login_attempts_reset();
  284. let jtw = Jwt::new(
  285. userinfo.username.as_str(),
  286. conf.password.as_str(),
  287. "",
  288. conf.token_expired_time,
  289. );
  290. let token = jtw.encode_token();
  291. let mut resp = API::response_build(
  292. StatusCode::OK,
  293. api_msg_auth_token(&token.token, &token.expire),
  294. );
  295. let cookie_token = format!("Bearer {}", token.token);
  296. let token_urlencode = urlencoding::encode(cookie_token.as_str());
  297. let cookie = format!(
  298. "token={}; HttpOnly; Max-Age={}; Path={}",
  299. token_urlencode, token.expire, REST_API_PATH
  300. );
  301. resp.as_mut()
  302. .unwrap()
  303. .headers_mut()
  304. .insert(hyper::header::SET_COOKIE, cookie.parse().unwrap());
  305. resp
  306. }
  307. async fn api_auth_logout(
  308. _this: Arc<HttpServer>,
  309. _param: APIRouteParam,
  310. _req: Request<body::Incoming>,
  311. ) -> Result<Response<Full<Bytes>>, HttpError> {
  312. let mut response = Response::new(Full::new(Bytes::from("")));
  313. let cookie = format!("token=none; HttpOnly; Max-Age=1; Path={}", REST_API_PATH);
  314. response
  315. .headers_mut()
  316. .insert(hyper::header::SET_COOKIE, cookie.parse().unwrap());
  317. *response.status_mut() = StatusCode::NO_CONTENT;
  318. Ok(response)
  319. }
  320. async fn api_auth_check(
  321. _this: Arc<HttpServer>,
  322. _param: APIRouteParam,
  323. _req: Request<body::Incoming>,
  324. ) -> Result<Response<Full<Bytes>>, HttpError> {
  325. API::response_build(StatusCode::OK, "".to_string())
  326. }
  327. async fn api_auth_change_password(
  328. this: Arc<HttpServer>,
  329. _param: APIRouteParam,
  330. req: Request<body::Incoming>,
  331. ) -> Result<Response<Full<Bytes>>, HttpError> {
  332. let unauth_response =
  333. || API::response_error(StatusCode::UNAUTHORIZED, "Incorrect username or password.");
  334. let token = HttpServer::get_token_from_header(&req)?;
  335. let whole_body = String::from_utf8(req.into_body().collect().await?.to_bytes().into())?;
  336. if token.is_none() {
  337. return unauth_response();
  338. }
  339. let password_info = match api_msg_parse_auth_password_change(whole_body.as_str()) {
  340. Ok(v) => v,
  341. Err(e) => {
  342. return API::response_error(StatusCode::BAD_REQUEST, e.to_string().as_str());
  343. }
  344. };
  345. if !this.login_attempts_check() {
  346. return API::response_error(
  347. StatusCode::FORBIDDEN,
  348. "Too many login attempts, please try again later.",
  349. );
  350. }
  351. let mut conf = this.get_conf_mut();
  352. if utils::verify_password(password_info.0.as_str(), conf.password.as_str()) != true {
  353. return API::response_error(StatusCode::FORBIDDEN, "Incorrect password.");
  354. }
  355. let hashed_password = match utils::hash_password(password_info.1.as_str(), Some(10000)) {
  356. Ok(v) => v,
  357. Err(e) => {
  358. return API::response_error(
  359. StatusCode::INTERNAL_SERVER_ERROR,
  360. e.to_string().as_str(),
  361. );
  362. }
  363. };
  364. let data_server = this.get_data_server();
  365. conf.password = hashed_password.clone();
  366. let ret = data_server.set_config(PASSWORD_CONFIG_KEY, hashed_password.as_str());
  367. if let Err(e) = ret {
  368. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  369. }
  370. this.login_attempts_reset();
  371. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  372. }
  373. /// Restart the service <br>
  374. /// API: PUT /api/service/restart
  375. ///
  376. async fn api_service_restart(
  377. _this: Arc<HttpServer>,
  378. _param: APIRouteParam,
  379. _req: Request<body::Incoming>,
  380. ) -> Result<Response<Full<Bytes>>, HttpError> {
  381. let mut response = Response::new(Full::new(Bytes::from("")));
  382. response
  383. .headers_mut()
  384. .insert("Content-Type", "application/json".parse().unwrap());
  385. *response.status_mut() = StatusCode::NO_CONTENT;
  386. Plugin::smartdns_restart();
  387. Ok(response)
  388. }
  389. /// Get the number of cache <br>
  390. /// API: GET /api/cache/count
  391. ///
  392. async fn api_cache_count(
  393. _this: Arc<HttpServer>,
  394. _param: APIRouteParam,
  395. _req: Request<body::Incoming>,
  396. ) -> Result<Response<Full<Bytes>>, HttpError> {
  397. API::response_build(
  398. StatusCode::OK,
  399. api_msg_gen_cache_number(Plugin::dns_cache_total_num()),
  400. )
  401. }
  402. /// Flush the cache <br>
  403. /// API: PUT /api/cache/flush
  404. ///
  405. async fn api_cache_flush(
  406. _this: Arc<HttpServer>,
  407. _param: APIRouteParam,
  408. _req: Request<body::Incoming>,
  409. ) -> Result<Response<Full<Bytes>>, HttpError> {
  410. Plugin::dns_cache_flush();
  411. API::response_build(
  412. StatusCode::OK,
  413. api_msg_gen_cache_number(Plugin::dns_cache_total_num()),
  414. )
  415. }
  416. /// Get the number of domain list <br>
  417. /// API: GET /api/domain/count
  418. ///
  419. async fn api_domain_get_list_count(
  420. this: Arc<HttpServer>,
  421. _param: APIRouteParam,
  422. _req: Request<body::Incoming>,
  423. ) -> Result<Response<Full<Bytes>>, HttpError> {
  424. let data_server = this.get_data_server();
  425. let count = data_server.get_domain_list_count();
  426. let body = api_msg_gen_count(count as i64);
  427. API::response_build(StatusCode::OK, body)
  428. }
  429. /// Get the domain by id <br>
  430. /// API: GET /api/domain/{id}
  431. async fn api_domain_get_by_id(
  432. this: Arc<HttpServer>,
  433. param: APIRouteParam,
  434. _req: Request<body::Incoming>,
  435. ) -> Result<Response<Full<Bytes>>, HttpError> {
  436. let id = API::params_parser_value(param.get("id"));
  437. if id.is_none() {
  438. return API::response_error(StatusCode::BAD_REQUEST, "Invalid parameter.");
  439. }
  440. let id = id.unwrap();
  441. let mut get_param = DomainListGetParam::new();
  442. get_param.id = Some(id);
  443. let data_server = this.get_data_server();
  444. let domain_list = data_server.get_domain_list(&get_param)?;
  445. if domain_list.domain_list.len() == 0 {
  446. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  447. }
  448. let body = api_msg_gen_domain(&domain_list.domain_list[0]);
  449. API::response_build(StatusCode::OK, body)
  450. }
  451. /// Delete the client by id <br>
  452. /// API: DELETE /api/client/{id}
  453. /// parameter: <br>
  454. async fn api_client_delete_by_id(
  455. this: Arc<HttpServer>,
  456. param: APIRouteParam,
  457. _req: Request<body::Incoming>,
  458. ) -> Result<Response<Full<Bytes>>, HttpError> {
  459. let id = match API::params_parser_value(param.get("id")) {
  460. Some(v) => v,
  461. None => return API::response_error(StatusCode::BAD_REQUEST, "Invalid parameter."),
  462. };
  463. let data_server = this.get_data_server();
  464. let ret = match data_server.delete_client_by_id(id) {
  465. Ok(v) => v,
  466. Err(e) => {
  467. return API::response_error(
  468. StatusCode::INTERNAL_SERVER_ERROR,
  469. e.to_string().as_str(),
  470. )
  471. }
  472. };
  473. if ret == 0 {
  474. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  475. }
  476. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  477. }
  478. /// Delete the domain by id <br>
  479. /// API: DELETE /api/domain/{id}
  480. ///
  481. async fn api_domain_delete_by_id(
  482. this: Arc<HttpServer>,
  483. param: APIRouteParam,
  484. _req: Request<body::Incoming>,
  485. ) -> Result<Response<Full<Bytes>>, HttpError> {
  486. let id = match API::params_parser_value(param.get("id")) {
  487. Some(v) => v,
  488. None => return API::response_error(StatusCode::BAD_REQUEST, "Invalid parameter."),
  489. };
  490. let data_server = this.get_data_server();
  491. let ret = match data_server.delete_domain_by_id(id) {
  492. Ok(v) => v,
  493. Err(e) => {
  494. return API::response_error(
  495. StatusCode::INTERNAL_SERVER_ERROR,
  496. e.to_string().as_str(),
  497. )
  498. }
  499. };
  500. if ret == 0 {
  501. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  502. }
  503. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  504. }
  505. /// Get the domain list <br>
  506. /// API: GET /api/domain <br>
  507. /// parameter: <br>
  508. /// page_num: u32: Page number <br>
  509. /// page_size: u32: Page size <br>
  510. /// domain: String: Domain <br>
  511. /// domain_type: String: Domain type <br>
  512. /// domain_group: String: Domain group <br>
  513. /// client: String: Client <br>
  514. /// reply_code: String: Reply code <br>
  515. ///
  516. ///
  517. async fn api_domain_get_list(
  518. this: Arc<HttpServer>,
  519. _param: APIRouteParam,
  520. req: Request<body::Incoming>,
  521. ) -> Result<Response<Full<Bytes>>, HttpError> {
  522. let params = API::get_params(&req);
  523. let page_num = API::params_get_value_default(&params, "page_num", 1 as u64)?;
  524. let page_size = API::params_get_value_default(&params, "page_size", 10 as u64)?;
  525. if page_num == 0 || page_size == 0 {
  526. return API::response_error(
  527. StatusCode::BAD_REQUEST,
  528. "Invalid parameter: page_num or page_size",
  529. );
  530. }
  531. let id = API::params_get_value(&params, "id");
  532. let domain = API::params_get_value(&params, "domain");
  533. let domain_filter_mode = API::params_get_value(&params, "domain_filter_mode");
  534. let domain_type = API::params_get_value(&params, "domain_type");
  535. let domain_group = API::params_get_value(&params, "domain_group");
  536. let client = API::params_get_value(&params, "client");
  537. let reply_code = API::params_get_value(&params, "reply_code");
  538. let order = API::params_get_value(&params, "order");
  539. let is_blocked = API::params_get_value(&params, "is_blocked");
  540. let timestamp_after = API::params_get_value(&params, "timestamp_after");
  541. let timestamp_before = API::params_get_value(&params, "timestamp_before");
  542. let cursor = API::params_get_value(&params, "cursor");
  543. let cursor_direction =
  544. match API::params_get_value_default(&params, "cursor_direction", "next".to_string()) {
  545. Ok(v) => v,
  546. Err(e) => {
  547. return Ok(e.to_response());
  548. }
  549. };
  550. let total_count = API::params_get_value(&params, "total_count");
  551. let mut param = DomainListGetParam::new();
  552. param.id = id;
  553. param.page_num = page_num;
  554. param.page_size = page_size;
  555. param.domain = domain;
  556. param.domain_filter_mode = domain_filter_mode;
  557. param.domain_type = domain_type;
  558. param.domain_group = domain_group;
  559. param.client = client;
  560. param.reply_code = reply_code;
  561. param.order = order;
  562. param.is_blocked = is_blocked;
  563. param.timestamp_after = timestamp_after;
  564. param.timestamp_before = timestamp_before;
  565. if cursor.is_some() || total_count.is_some() {
  566. let param_cursor = DomainListGetParamCursor {
  567. id: if cursor.is_some() { cursor } else { None },
  568. total_count: total_count.unwrap(),
  569. direction: cursor_direction,
  570. };
  571. param.cursor = Some(param_cursor);
  572. }
  573. let data_server = this.get_data_server();
  574. let ret = API::call_blocking(this, move || {
  575. let ret = data_server
  576. .get_domain_list(&param)
  577. .map_err(|e| e.to_string());
  578. if let Err(e) = ret {
  579. return Err(e.to_string());
  580. }
  581. let ret = ret.unwrap();
  582. return Ok(ret);
  583. })
  584. .await;
  585. if let Err(e) = ret {
  586. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  587. }
  588. let ret = ret.unwrap();
  589. if let Err(e) = ret {
  590. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  591. }
  592. let domain_list = ret.unwrap();
  593. let list_count = domain_list.total_count;
  594. let mut total_page = list_count / page_size;
  595. if list_count % page_size != 0 {
  596. total_page += 1;
  597. }
  598. let total_count = domain_list.total_count;
  599. let body = api_msg_gen_domain_list(&domain_list, total_page, total_count);
  600. API::response_build(StatusCode::OK, body)
  601. }
  602. /// Delete the domain list before timestamp <br>
  603. /// API: DELETE /api/domain <br>
  604. /// parameter: <br>
  605. /// timestamp: u64: Unix timestamp <br>
  606. ///
  607. async fn api_domain_delete_list(
  608. this: Arc<HttpServer>,
  609. _param: APIRouteParam,
  610. req: Request<body::Incoming>,
  611. ) -> Result<Response<Full<Bytes>>, HttpError> {
  612. let params = API::get_params(&req);
  613. let timestamp_before = API::params_get_value(&params, "timestamp_before");
  614. if timestamp_before.is_none() {
  615. return API::response_error(StatusCode::BAD_REQUEST, "Invalid parameter.");
  616. }
  617. let timestamp_before = timestamp_before.unwrap();
  618. let data_server = this.get_data_server();
  619. let ret = data_server.delete_domain_before_timestamp(timestamp_before);
  620. if let Err(e) = ret {
  621. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  622. }
  623. if *ret.as_ref().unwrap() == 0 {
  624. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  625. }
  626. let body = api_msg_gen_count(ret.unwrap() as i64);
  627. API::response_build(StatusCode::OK, body)
  628. }
  629. async fn api_client_get_list(
  630. this: Arc<HttpServer>,
  631. _param: APIRouteParam,
  632. _req: Request<body::Incoming>,
  633. ) -> Result<Response<Full<Bytes>>, HttpError> {
  634. let data_server = this.get_data_server();
  635. let ret = API::call_blocking(this, move || {
  636. let ret = data_server.get_client_list();
  637. if let Err(e) = ret {
  638. return Err(e.to_string());
  639. }
  640. let ret = ret.unwrap();
  641. return Ok(ret);
  642. }).await;
  643. let ret = match ret {
  644. Ok(v) => v,
  645. Err(e) => {
  646. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  647. },
  648. };
  649. if let Err(e) = ret {
  650. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  651. }
  652. let client_list = ret.unwrap();
  653. let body = api_msg_gen_client_list(&client_list, client_list.len() as u32);
  654. API::response_build(StatusCode::OK, body)
  655. }
  656. async fn api_log_stream(
  657. this: Arc<HttpServer>,
  658. _param: APIRouteParam,
  659. mut req: Request<body::Incoming>,
  660. ) -> Result<Response<Full<Bytes>>, HttpError> {
  661. if hyper_tungstenite::is_upgrade_request(&req) {
  662. let (response, websocket) = hyper_tungstenite::upgrade(&mut req, None)
  663. .map_err(|e| HttpError::new(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
  664. tokio::spawn(async move {
  665. if let Err(e) = http_server_stream::serve_log_stream(this, websocket).await {
  666. dns_log!(LogLevel::DEBUG, "Error in websocket connection: {e}");
  667. }
  668. });
  669. Ok(response)
  670. } else {
  671. return API::response_error(StatusCode::BAD_REQUEST, "Need websocket upgrade.");
  672. }
  673. }
  674. async fn api_log_set_level(
  675. this: Arc<HttpServer>,
  676. _param: APIRouteParam,
  677. _req: Request<body::Incoming>,
  678. ) -> Result<Response<Full<Bytes>>, HttpError> {
  679. let whole_body = String::from_utf8(_req.into_body().collect().await?.to_bytes().into())?;
  680. let level = api_msg_parse_loglevel(whole_body.as_str());
  681. if let Err(e) = level {
  682. return API::response_error(StatusCode::BAD_REQUEST, e.to_string().as_str());
  683. }
  684. let level = level.unwrap();
  685. dns_log_set_level(level);
  686. let data_server = this.get_data_server();
  687. _ = data_server.set_config("log-level", level.to_string().as_str());
  688. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  689. }
  690. async fn api_log_get_level(
  691. _this: Arc<HttpServer>,
  692. _param: APIRouteParam,
  693. _req: Request<body::Incoming>,
  694. ) -> Result<Response<Full<Bytes>>, HttpError> {
  695. let level = dns_log_get_level();
  696. let msg = api_msg_gen_loglevel(level);
  697. API::response_build(StatusCode::OK, msg)
  698. }
  699. async fn api_server_version(
  700. _this: Arc<HttpServer>,
  701. _param: APIRouteParam,
  702. _req: Request<body::Incoming>,
  703. ) -> Result<Response<Full<Bytes>>, HttpError> {
  704. let server_version = &smartdns::smartdns_version();
  705. let ui_version = &smartdns::smartdns_ui_version();
  706. let msg = api_msg_gen_version(server_version, ui_version);
  707. API::response_build(StatusCode::OK, msg)
  708. }
  709. async fn api_upstream_server_get_list(
  710. this: Arc<HttpServer>,
  711. _param: APIRouteParam,
  712. _req: Request<body::Incoming>,
  713. ) -> Result<Response<Full<Bytes>>, HttpError> {
  714. let data_server = this.get_data_server();
  715. let upstream_server_list = data_server.get_upstream_server_list()?;
  716. let body = api_msg_gen_upstream_server_list(&upstream_server_list);
  717. API::response_build(StatusCode::OK, body)
  718. }
  719. async fn api_config_get_settings(
  720. this: Arc<HttpServer>,
  721. param: APIRouteParam,
  722. _req: Request<body::Incoming>,
  723. ) -> Result<Response<Full<Bytes>>, HttpError> {
  724. let key = API::params_get_value(&param, "key");
  725. let data_server = this.get_data_server();
  726. let settings = data_server.get_config_list();
  727. if settings.is_err() {
  728. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  729. }
  730. let mut settings = settings.unwrap();
  731. this.get_conf().settings_map().iter().for_each(|(k, v)| {
  732. if settings.get(k).is_none() {
  733. settings.insert(k.to_string(), v.to_string());
  734. }
  735. });
  736. let pass = settings.get(PASSWORD_CONFIG_KEY);
  737. if pass.is_some() {
  738. let pass = "********".to_string();
  739. settings.insert(PASSWORD_CONFIG_KEY.to_string(), pass);
  740. }
  741. if key.is_some() {
  742. let key : String = key.unwrap();
  743. let value = settings.get(key.as_str());
  744. if value.is_none() {
  745. return API::response_error(StatusCode::NOT_FOUND, "Not found");
  746. }
  747. let mut map = std::collections::HashMap::new();
  748. map.insert(key, value.unwrap().clone());
  749. let msg = api_msg_gen_key_value(&map);
  750. return API::response_build(StatusCode::OK, msg);
  751. }
  752. let msg = api_msg_gen_key_value(&settings);
  753. API::response_build(StatusCode::OK, msg)
  754. }
  755. async fn api_config_set_settings(
  756. this: Arc<HttpServer>,
  757. _param: APIRouteParam,
  758. req: Request<body::Incoming>,
  759. ) -> Result<Response<Full<Bytes>>, HttpError> {
  760. let data_server = this.get_data_server();
  761. let whole_body = String::from_utf8(req.into_body().collect().await?.to_bytes().into())?;
  762. let settings = api_msg_parse_key_value(whole_body.as_str());
  763. if let Err(e) = settings {
  764. return API::response_error(StatusCode::BAD_REQUEST, e.to_string().as_str());
  765. }
  766. let settings = settings.unwrap();
  767. for (key, value) in settings {
  768. if key == PASSWORD_CONFIG_KEY {
  769. continue;
  770. }
  771. let ret = data_server.set_config(key.as_str(), value.as_str());
  772. if let Err(e) = ret {
  773. return API::response_error(
  774. StatusCode::INTERNAL_SERVER_ERROR,
  775. e.to_string().as_str(),
  776. );
  777. }
  778. }
  779. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  780. }
  781. async fn api_stats_get_top_client(
  782. this: Arc<HttpServer>,
  783. _param: APIRouteParam,
  784. _req: Request<body::Incoming>,
  785. ) -> Result<Response<Full<Bytes>>, HttpError> {
  786. let data_server = this.get_data_server();
  787. let params = API::get_params(&_req);
  788. let count = API::params_get_value(&params, "count");
  789. let ret = API::call_blocking(this, move || {
  790. let ret = data_server.get_top_client_top_list(count);
  791. if let Err(e) = ret {
  792. return Err(e.to_string());
  793. }
  794. let ret = ret.unwrap();
  795. return Ok(ret);
  796. })
  797. .await;
  798. if let Err(e) = ret {
  799. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  800. }
  801. let ret = ret.unwrap();
  802. if let Err(e) = ret {
  803. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  804. }
  805. let body = api_msg_gen_top_client_list(&ret.unwrap());
  806. API::response_build(StatusCode::OK, body)
  807. }
  808. async fn api_stats_get_top_domain(
  809. this: Arc<HttpServer>,
  810. _param: APIRouteParam,
  811. _req: Request<body::Incoming>,
  812. ) -> Result<Response<Full<Bytes>>, HttpError> {
  813. let data_server = this.get_data_server();
  814. let params = API::get_params(&_req);
  815. let count = API::params_get_value(&params, "count");
  816. let ret = API::call_blocking(this, move || {
  817. let ret = data_server.get_top_domain_top_list(count);
  818. if let Err(e) = ret {
  819. return Err(e.to_string());
  820. }
  821. let ret = ret.unwrap();
  822. return Ok(ret);
  823. })
  824. .await;
  825. if let Err(e) = ret {
  826. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  827. }
  828. let ret = ret.unwrap();
  829. if let Err(e) = ret {
  830. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  831. }
  832. let body = api_msg_gen_top_domain_list(&ret.unwrap());
  833. API::response_build(StatusCode::OK, body)
  834. }
  835. async fn api_stats_get_metrics(
  836. this: Arc<HttpServer>,
  837. _param: APIRouteParam,
  838. mut req: Request<body::Incoming>,
  839. ) -> Result<Response<Full<Bytes>>, HttpError> {
  840. let data_server = this.get_data_server();
  841. if hyper_tungstenite::is_upgrade_request(&req) {
  842. let (response, websocket) = hyper_tungstenite::upgrade(&mut req, None)
  843. .map_err(|e| HttpError::new(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
  844. tokio::spawn(async move {
  845. if let Err(e) = http_server_stream::serve_metrics(data_server, websocket).await {
  846. dns_log!(LogLevel::DEBUG, "Error in websocket connection: {e}");
  847. }
  848. });
  849. Ok(response)
  850. } else {
  851. let metrics = data_server.get_metrics()?;
  852. let body = api_msg_gen_metrics_data(&metrics);
  853. return API::response_build(StatusCode::OK, body);
  854. }
  855. }
  856. async fn api_stats_get_overview(
  857. this: Arc<HttpServer>,
  858. _param: APIRouteParam,
  859. _req: Request<body::Incoming>,
  860. ) -> Result<Response<Full<Bytes>>, HttpError> {
  861. let data_server = this.get_data_server();
  862. let overview = data_server.get_overview()?;
  863. let body = api_msg_gen_stats_overview(&overview);
  864. return API::response_build(StatusCode::OK, body);
  865. }
  866. async fn api_stats_refresh(
  867. this: Arc<HttpServer>,
  868. _param: APIRouteParam,
  869. _req: Request<body::Incoming>,
  870. ) -> Result<Response<Full<Bytes>>, HttpError> {
  871. let data_server = this.get_data_server();
  872. let ret = API::call_blocking(this, move || -> Result<(), String> {
  873. data_server.get_stat().refresh();
  874. Ok(())
  875. })
  876. .await;
  877. if let Err(e) = ret {
  878. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  879. }
  880. API::response_build(StatusCode::NO_CONTENT, "".to_string())
  881. }
  882. async fn api_stats_get_daily_query_count(
  883. this: Arc<HttpServer>,
  884. param: APIRouteParam,
  885. _req: Request<body::Incoming>,
  886. ) -> Result<Response<Full<Bytes>>, HttpError> {
  887. let data_server = this.get_data_server();
  888. let past_days = API::params_get_value(&param, "past_days");
  889. let ret = API::call_blocking(this, move || {
  890. let ret = data_server.get_daily_query_count(past_days);
  891. if let Err(e) = ret {
  892. return Err(e.to_string());
  893. }
  894. let ret = ret.unwrap();
  895. return Ok(ret);
  896. })
  897. .await;
  898. if let Err(e) = ret {
  899. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  900. }
  901. let ret = ret.unwrap();
  902. if let Err(e) = ret {
  903. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  904. }
  905. let body = api_msg_gen_daily_query_count(&ret.unwrap());
  906. API::response_build(StatusCode::OK, body)
  907. }
  908. async fn api_stats_get_hourly_query_count(
  909. this: Arc<HttpServer>,
  910. _param: APIRouteParam,
  911. _req: Request<body::Incoming>,
  912. ) -> Result<Response<Full<Bytes>>, HttpError> {
  913. let params = API::get_params(&_req);
  914. let past_hours = API::params_get_value(&params, "past_hours");
  915. let data_server = this.get_data_server();
  916. let ret = API::call_blocking(this, move || {
  917. let ret = data_server.get_hourly_query_count(past_hours);
  918. if let Err(e) = ret {
  919. return Err(e.to_string());
  920. }
  921. let ret = ret.unwrap();
  922. return Ok(ret);
  923. })
  924. .await;
  925. if let Err(e) = ret {
  926. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  927. }
  928. let ret = ret.unwrap();
  929. if let Err(e) = ret {
  930. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  931. }
  932. let body = api_msg_gen_hourly_query_count(&ret.unwrap());
  933. API::response_build(StatusCode::OK, body)
  934. }
  935. async fn api_whois(
  936. this: Arc<HttpServer>,
  937. _param: APIRouteParam,
  938. _req: Request<body::Incoming>,
  939. ) -> Result<Response<Full<Bytes>>, HttpError> {
  940. let params = API::get_params(&_req);
  941. let domain = API::params_get_value(&params, "domain");
  942. if domain.is_none() {
  943. return API::response_error(StatusCode::BAD_REQUEST, "Invalid parameter.");
  944. }
  945. let domain: String = domain.unwrap();
  946. let data_server = this.get_data_server();
  947. let ret = data_server.whois(domain.as_str()).await;
  948. if let Err(e) = ret {
  949. return API::response_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string().as_str());
  950. }
  951. let body = api_msg_gen_whois_info(&ret.unwrap());
  952. API::response_build(StatusCode::OK, body)
  953. }
  954. async fn api_tool_term(
  955. this: Arc<HttpServer>,
  956. _param: APIRouteParam,
  957. mut req: Request<body::Incoming>,
  958. ) -> Result<Response<Full<Bytes>>, HttpError> {
  959. if this.get_conf().enable_terminal != true {
  960. return API::response_error(StatusCode::FORBIDDEN, "Terminal is disabled.");
  961. }
  962. if hyper_tungstenite::is_upgrade_request(&req) {
  963. let (response, websocket) = hyper_tungstenite::upgrade(&mut req, None)
  964. .map_err(|e| HttpError::new(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
  965. tokio::spawn(async move {
  966. if let Err(e) = http_server_stream::serve_term(websocket).await {
  967. dns_log!(LogLevel::DEBUG, "Error in websocket connection: {e}");
  968. }
  969. });
  970. Ok(response)
  971. } else {
  972. return API::response_error(StatusCode::BAD_REQUEST, "Need websocket upgrade.");
  973. }
  974. }
  975. async fn call_blocking<F, R>(
  976. this: Arc<HttpServer>,
  977. func: F,
  978. ) -> Result<R, Box<dyn std::error::Error + Send>>
  979. where
  980. F: FnOnce() -> R + Send + 'static,
  981. R: Send + 'static,
  982. {
  983. let rt = this.get_data_server().get_plugin().get_runtime();
  984. let ret = rt.spawn_blocking(move || -> R {
  985. return func();
  986. });
  987. let ret = ret.await;
  988. if ret.is_err() {
  989. return Err(Box::new(ret.err().unwrap()));
  990. }
  991. let ret = ret.unwrap();
  992. return Ok(ret);
  993. }
  994. }