mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 21:39:21 +00:00
Start to implement requests limit
This commit is contained in:
parent
89d2cedfb7
commit
ebc5ebea2a
36
Cargo.lock
generated
36
Cargo.lock
generated
@ -293,6 +293,15 @@ dependencies = [
|
|||||||
"const-random",
|
"const-random",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
|
||||||
|
dependencies = [
|
||||||
|
"const-random",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.10"
|
version = "0.7.10"
|
||||||
@ -509,9 +518,9 @@ checksum = "404b1fe4f65288577753b17e3b36a04596ee784493ec249bf81c7f2d2acd751c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.9"
|
version = "0.1.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
@ -549,6 +558,7 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"dashmap",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures",
|
"futures",
|
||||||
"image",
|
"image",
|
||||||
@ -666,6 +676,17 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dashmap"
|
||||||
|
version = "3.11.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f260e2fc850179ef410018660006951c1b55b79e8087e87111a2c388994b9b5"
|
||||||
|
dependencies = [
|
||||||
|
"ahash 0.3.8",
|
||||||
|
"cfg-if",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deflate"
|
name = "deflate"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
@ -1075,7 +1096,7 @@ version = "0.6.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
checksum = "8e6073d0ca812575946eb5f35ff68dbe519907b25c42530389ff946dc84c6ead"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash 0.2.18",
|
||||||
"autocfg 0.1.7",
|
"autocfg 0.1.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1271,9 +1292,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lexical"
|
name = "lexical"
|
||||||
version = "4.2.0"
|
version = "4.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eaad0ee8120fc0cf7df7e8fdbe79bf9d6189351404feb88f4e4a4bb5307bc594"
|
checksum = "0afaeae1c07c575338ef6809875bfea8daa9ea8b2ee381ef1f93ba0c6e32f003"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"lexical-core",
|
"lexical-core",
|
||||||
@ -1282,12 +1303,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lexical-core"
|
name = "lexical-core"
|
||||||
version = "0.6.7"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f86d66d380c9c5a685aaac7a11818bdfa1f733198dfd9ec09c70b762cd12ad6f"
|
checksum = "d7043aa5c05dd34fb73b47acb8c3708eac428de4545ea3682ed2f11293ebd890"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -28,3 +28,4 @@ lazy_static = "1.4.0"
|
|||||||
mime_guess = "2.0.3"
|
mime_guess = "2.0.3"
|
||||||
pdf = "0.6.3"
|
pdf = "0.6.3"
|
||||||
regex = "1.4.2"
|
regex = "1.4.2"
|
||||||
|
dashmap = "3.11.10"
|
@ -57,6 +57,9 @@ pub mod database_tables_names {
|
|||||||
pub const NOTIFICATIONS_TABLE: &str = "comunic_notifications";
|
pub const NOTIFICATIONS_TABLE: &str = "comunic_notifications";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lifetime of limit counter (1 hour)
|
||||||
|
pub const LIMIT_COUNTER_LIFETIME: u64 = 60 * 60;
|
||||||
|
|
||||||
/// The account image to show for user who do not have any
|
/// The account image to show for user who do not have any
|
||||||
pub const DEFAULT_ACCOUNT_IMAGE: &str = "avatars/0Reverse.png";
|
pub const DEFAULT_ACCOUNT_IMAGE: &str = "avatars/0Reverse.png";
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ use crate::controllers::routes::{get_routes, RequestResult, Route};
|
|||||||
use crate::controllers::routes::Method::{GET, POST};
|
use crate::controllers::routes::Method::{GET, POST};
|
||||||
use crate::data::config::Config;
|
use crate::data::config::Config;
|
||||||
use crate::data::http_request_handler::{HttpRequestHandler, PostFile, RequestValue};
|
use crate::data::http_request_handler::{HttpRequestHandler, PostFile, RequestValue};
|
||||||
|
use crate::helpers::requests_limit_helper;
|
||||||
|
|
||||||
/// Main server functions
|
/// Main server functions
|
||||||
///
|
///
|
||||||
@ -237,6 +238,9 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
let route = route.unwrap();
|
let route = route.unwrap();
|
||||||
|
|
||||||
|
// Clean requests limit
|
||||||
|
requests_limit_helper::clean_cache().unwrap();
|
||||||
|
|
||||||
// Execute the request
|
// Execute the request
|
||||||
let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body);
|
let mut request = HttpRequestHandler::new(custom_req.req, custom_req.body);
|
||||||
|
|
||||||
@ -280,6 +284,10 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
|
|||||||
|
|
||||||
/// Given the configuration, start the server
|
/// Given the configuration, start the server
|
||||||
pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
||||||
|
|
||||||
|
// Initialize limit helper
|
||||||
|
requests_limit_helper::init();
|
||||||
|
|
||||||
let addr = conf.server_listen_address();
|
let addr = conf.server_listen_address();
|
||||||
println!("Start to listen on http://{}/", addr);
|
println!("Start to listen on http://{}/", addr);
|
||||||
|
|
||||||
|
@ -16,3 +16,4 @@ pub mod survey_helper;
|
|||||||
pub mod comments_helper;
|
pub mod comments_helper;
|
||||||
pub mod notifications_helper;
|
pub mod notifications_helper;
|
||||||
pub mod webapp_helper;
|
pub mod webapp_helper;
|
||||||
|
pub mod requests_limit_helper;
|
60
src/helpers/requests_limit_helper.rs
Normal file
60
src/helpers/requests_limit_helper.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
//! # Requests limit helper
|
||||||
|
//!
|
||||||
|
//! Handle the limitation of requests, depending on threshold criterias
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use crate::constants::LIMIT_COUNTER_LIFETIME;
|
||||||
|
use crate::data::error::ResultBoxError;
|
||||||
|
use crate::utils::date_utils;
|
||||||
|
|
||||||
|
/// Information about a IP address limitation
|
||||||
|
struct IpInfo {
|
||||||
|
time_start: u64,
|
||||||
|
count: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Limits cache
|
||||||
|
type Cache = Arc<dashmap::DashMap<String, IpInfo>>;
|
||||||
|
|
||||||
|
static mut LIMITS_CACHE: Option<Arc<Mutex<Cache>>> = None;
|
||||||
|
|
||||||
|
/// Initialize limit cache storage
|
||||||
|
pub fn init() {
|
||||||
|
let limits_cache = Arc::new(dashmap::DashMap::new());
|
||||||
|
let limits_cache = Some(Arc::new(Mutex::new(limits_cache)));
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
LIMITS_CACHE = limits_cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get access to the cache. This resource must absolutely be released as quickly as possible
|
||||||
|
fn get_cache() -> ResultBoxError<Cache> {
|
||||||
|
let cache: Cache;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let guard = LIMITS_CACHE.as_ref().unwrap().lock();
|
||||||
|
cache = guard.unwrap().clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(cache)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clean cached information
|
||||||
|
pub fn clean_cache() -> ResultBoxError {
|
||||||
|
let time = date_utils::time();
|
||||||
|
|
||||||
|
let cache = get_cache()?;
|
||||||
|
let obsolete_ips: Vec<String> = cache
|
||||||
|
.iter()
|
||||||
|
.filter(|k| k.time_start + LIMIT_COUNTER_LIFETIME < time)
|
||||||
|
.map(|k| k.key().to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for obsolete_ip in obsolete_ips {
|
||||||
|
cache.remove(&obsolete_ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user