cllipy fix
This commit is contained in:
@@ -100,17 +100,21 @@ pub(crate) async fn create_mxc_uri_route(
|
|||||||
media_id: &utils::random_string(MXC_LENGTH),
|
media_id: &utils::random_string(MXC_LENGTH),
|
||||||
};
|
};
|
||||||
|
|
||||||
let unused_expires_at = (std::time::SystemTime::now()
|
let unused_expires_at = u64::try_from(
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
std::time::SystemTime::now()
|
||||||
.expect("Time went backwards")
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.as_millis() as u64)
|
.expect("Time went backwards")
|
||||||
.saturating_add(
|
.as_millis(),
|
||||||
services
|
)?
|
||||||
|
.saturating_add(
|
||||||
|
services
|
||||||
.server
|
.server
|
||||||
.config
|
.config
|
||||||
.media_create_unused_expiration_time
|
.media_create_unused_expiration_time
|
||||||
* 1000,
|
// safe because even if it overflows, it will be greater than the current time
|
||||||
);
|
// and the unused media will be deleted anyway
|
||||||
|
.saturating_mul(1000),
|
||||||
|
);
|
||||||
services
|
services
|
||||||
.media
|
.media
|
||||||
.create_pending(&mxc, user, unused_expires_at)
|
.create_pending(&mxc, user, unused_expires_at)
|
||||||
|
|||||||
@@ -427,13 +427,13 @@ pub struct Config {
|
|||||||
///
|
///
|
||||||
/// default: 10
|
/// default: 10
|
||||||
#[serde(default = "default_rc_media_create_per_second")]
|
#[serde(default = "default_rc_media_create_per_second")]
|
||||||
pub rc_media_create_per_second: u64,
|
pub rc_media_create_per_second: u32,
|
||||||
|
|
||||||
/// The maximum burst count for media create requests from a single user.
|
/// The maximum burst count for media create requests from a single user.
|
||||||
///
|
///
|
||||||
/// default: 50
|
/// default: 50
|
||||||
#[serde(default = "default_rc_media_create_burst_count")]
|
#[serde(default = "default_rc_media_create_burst_count")]
|
||||||
pub rc_media_create_burst_count: u64,
|
pub rc_media_create_burst_count: u32,
|
||||||
|
|
||||||
/// default: 192
|
/// default: 192
|
||||||
#[serde(default = "default_max_fetch_prev_events")]
|
#[serde(default = "default_max_fetch_prev_events")]
|
||||||
@@ -3274,8 +3274,8 @@ fn default_ip_lookup_strategy() -> u8 { 5 }
|
|||||||
fn default_max_request_size() -> usize { 24 * 1024 * 1024 }
|
fn default_max_request_size() -> usize { 24 * 1024 * 1024 }
|
||||||
fn default_max_pending_media_uploads() -> usize { 5 }
|
fn default_max_pending_media_uploads() -> usize { 5 }
|
||||||
fn default_media_create_unused_expiration_time() -> u64 { 86400 }
|
fn default_media_create_unused_expiration_time() -> u64 { 86400 }
|
||||||
fn default_rc_media_create_per_second() -> u64 { 10 }
|
fn default_rc_media_create_per_second() -> u32 { 10 }
|
||||||
fn default_rc_media_create_burst_count() -> u64 { 50 }
|
fn default_rc_media_create_burst_count() -> u32 { 50 }
|
||||||
|
|
||||||
fn default_request_conn_timeout() -> u64 { 10 }
|
fn default_request_conn_timeout() -> u64 { 10 }
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,12 @@ impl Data {
|
|||||||
);
|
);
|
||||||
// 8 bytes for unused_expires_at (u64), 1 byte for 0xFF, and
|
// 8 bytes for unused_expires_at (u64), 1 byte for 0xFF, and
|
||||||
// user.as_bytes().len() for user value: [unused_expires_at, 0xFF, user]
|
// user.as_bytes().len() for user value: [unused_expires_at, 0xFF, user]
|
||||||
let mut value = Vec::with_capacity(user.as_bytes().len() + 9);
|
let mut value = Vec::with_capacity(
|
||||||
|
user.as_bytes()
|
||||||
|
.len()
|
||||||
|
.checked_add(9)
|
||||||
|
.expect("User len too large,capacity overflow!"),
|
||||||
|
);
|
||||||
value.extend_from_slice(&unused_expires_at.to_be_bytes());
|
value.extend_from_slice(&unused_expires_at.to_be_bytes());
|
||||||
value.push(0xFF);
|
value.push(0xFF);
|
||||||
value.extend_from_slice(user.as_bytes());
|
value.extend_from_slice(user.as_bytes());
|
||||||
@@ -80,7 +85,7 @@ impl Data {
|
|||||||
|
|
||||||
/// Count the number of pending MXC URIs for a specific user
|
/// Count the number of pending MXC URIs for a specific user
|
||||||
pub(super) async fn count_pending_mxc_for_user(&self, user: &UserId) -> (usize, u64) {
|
pub(super) async fn count_pending_mxc_for_user(&self, user: &UserId) -> (usize, u64) {
|
||||||
let mut count = 0;
|
let mut count: usize = 0;
|
||||||
let mut earliest_expiration = u64::MAX;
|
let mut earliest_expiration = u64::MAX;
|
||||||
let user_bytes = user.as_bytes();
|
let user_bytes = user.as_bytes();
|
||||||
|
|
||||||
@@ -89,18 +94,19 @@ impl Data {
|
|||||||
.ignore_err()
|
.ignore_err()
|
||||||
.ready_for_each(|(_key, value)| {
|
.ready_for_each(|(_key, value)| {
|
||||||
let mut parts = value.splitn(2, |&b| b == 0xFF);
|
let mut parts = value.splitn(2, |&b| b == 0xFF);
|
||||||
if let Some(expires_at_bytes) = parts.next() {
|
match (parts.next(), parts.next()) {
|
||||||
if let Some(user_id_bytes) = parts.next() {
|
| (Some(expires_at_bytes), Some(user_id_bytes))
|
||||||
if user_id_bytes == user_bytes {
|
if user_id_bytes == user_bytes =>
|
||||||
count += 1;
|
{
|
||||||
let expires_at = u64::from_be_bytes(
|
// safe to add 1 even if count = usize::MAX it also > max_uploads
|
||||||
expires_at_bytes.try_into().unwrap_or([0u8; 8]),
|
count = count.saturating_add(1_usize);
|
||||||
);
|
let expires_at =
|
||||||
if expires_at < earliest_expiration {
|
u64::from_be_bytes(expires_at_bytes.try_into().unwrap_or([0_u8; 8]));
|
||||||
earliest_expiration = expires_at;
|
if expires_at < earliest_expiration {
|
||||||
}
|
earliest_expiration = expires_at;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
| _ => {},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
@@ -133,12 +139,10 @@ impl Data {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let user_id_bytes = parts.next()?;
|
let user_id_bytes = parts.next()?;
|
||||||
let user_str = match str_from_bytes(user_id_bytes) {
|
|
||||||
| Ok(v) => v,
|
let Ok(user_str) = str_from_bytes(user_id_bytes) else {
|
||||||
| Err(_) => {
|
tracing::error!("Failed to parse user_str for {}", key);
|
||||||
tracing::error!("Failed to parse user_str for {}", key);
|
return None;
|
||||||
return None;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
let user_id = match user_str.try_into() {
|
let user_id = match user_str.try_into() {
|
||||||
| Ok(v) => v,
|
| Ok(v) => v,
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ impl Service {
|
|||||||
let config = &self.services.server.config;
|
let config = &self.services.server.config;
|
||||||
|
|
||||||
// Rate limiting (rc_media_create)
|
// Rate limiting (rc_media_create)
|
||||||
let rate = config.rc_media_create_per_second as f64;
|
let rate = f64::from(config.rc_media_create_per_second);
|
||||||
let burst = config.rc_media_create_burst_count as f64;
|
let burst = f64::from(config.rc_media_create_burst_count);
|
||||||
|
|
||||||
// Check rate limiting
|
// Check rate limiting
|
||||||
if rate > 0.0 && burst > 0.0 {
|
if rate > 0.0 && burst > 0.0 {
|
||||||
@@ -106,7 +106,7 @@ impl Service {
|
|||||||
.or_insert_with(|| (now, burst));
|
.or_insert_with(|| (now, burst));
|
||||||
|
|
||||||
let elapsed = now.duration_since(*last_time).as_secs_f64();
|
let elapsed = now.duration_since(*last_time).as_secs_f64();
|
||||||
let new_tokens = (*tokens + elapsed * rate).min(burst);
|
let new_tokens = elapsed.mul_add(rate, *tokens).min(burst);
|
||||||
|
|
||||||
if new_tokens >= 1.0 {
|
if new_tokens >= 1.0 {
|
||||||
*last_time = now;
|
*last_time = now;
|
||||||
@@ -126,12 +126,12 @@ impl Service {
|
|||||||
|
|
||||||
// Check if the user has reached the maximum number of pending media uploads
|
// Check if the user has reached the maximum number of pending media uploads
|
||||||
if current_uploads >= max_uploads {
|
if current_uploads >= max_uploads {
|
||||||
let retry_after = earliest_expiration.saturating_sub(
|
let retry_after = earliest_expiration.saturating_sub(u64::try_from(
|
||||||
SystemTime::now()
|
SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis() as u64,
|
.as_millis(),
|
||||||
);
|
)?);
|
||||||
return Err(tuwunel_core::Error::Request(
|
return Err(tuwunel_core::Error::Request(
|
||||||
ruma::api::client::error::ErrorKind::LimitExceeded {
|
ruma::api::client::error::ErrorKind::LimitExceeded {
|
||||||
retry_after: Some(ruma::api::client::error::RetryAfter::Delay(
|
retry_after: Some(ruma::api::client::error::RetryAfter::Delay(
|
||||||
@@ -166,10 +166,12 @@ impl Service {
|
|||||||
return Err!(Request(Forbidden("You did not create this media ID")));
|
return Err!(Request(Forbidden("You did not create this media ID")));
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_time = SystemTime::now()
|
let current_time = u64::try_from(
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
SystemTime::now()
|
||||||
.expect("Time went backwards")
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.as_millis() as u64;
|
.expect("Time went backwards")
|
||||||
|
.as_millis(),
|
||||||
|
)?;
|
||||||
|
|
||||||
if expires_at < current_time {
|
if expires_at < current_time {
|
||||||
return Err!(Request(NotFound("Pending media ID expired")));
|
return Err!(Request(NotFound("Pending media ID expired")));
|
||||||
|
|||||||
Reference in New Issue
Block a user