wrap field instead of implementing clone for whole data struct

This commit is contained in:
Dull Bananas 2025-06-14 23:57:51 -07:00
parent 9e1af15ee0
commit abecc6cedc
2 changed files with 10 additions and 17 deletions

View file

@ -356,9 +356,10 @@ clone_trait_object!(UrlVerifier);
/// prevent denial of service attacks, where an attacker triggers fetching of recursive objects. /// prevent denial of service attacks, where an attacker triggers fetching of recursive objects.
/// ///
/// <https://www.w3.org/TR/activitypub/#security-recursive-objects> /// <https://www.w3.org/TR/activitypub/#security-recursive-objects>
#[derive(Clone)]
pub struct Data<T: Clone> { pub struct Data<T: Clone> {
pub(crate) config: FederationConfig<T>, pub(crate) config: FederationConfig<T>,
pub(crate) request_counter: AtomicU32, pub(crate) request_counter: RequestCounter,
} }
impl<T: Clone> Data<T> { impl<T: Clone> Data<T> {
@ -381,7 +382,7 @@ impl<T: Clone> Data<T> {
} }
/// Total number of outgoing HTTP requests made with this data. /// Total number of outgoing HTTP requests made with this data.
pub fn request_count(&self) -> u32 { pub fn request_count(&self) -> u32 {
self.request_counter.load(Ordering::Relaxed) self.request_counter.0.load(Ordering::Relaxed)
} }
/// Add HTTP signature to arbitrary request /// Add HTTP signature to arbitrary request
@ -412,21 +413,13 @@ impl<T: Clone> Deref for Data<T> {
} }
} }
impl<T: Clone> Clone for Data<T> { /// Wrapper to implement `Clone`
fn clone(&self) -> Self { #[derive(Default)]
Data { pub(crate) struct RequestCounter(pub(crate) AtomicU32);
config: self.config.clone(),
request_counter: self.request_counter.load(Ordering::Relaxed).into(),
}
}
fn clone_from(&mut self, source: &Self) { impl Clone for RequestCounter {
let Data { fn clone(&self) -> Self {
config, RequestCounter(self.0.load(Ordering::Relaxed).into())
request_counter,
} = self;
config.clone_from(&source.config);
*request_counter.get_mut() = source.request_counter.load(Ordering::Relaxed);
} }
} }

View file

@ -106,7 +106,7 @@ async fn fetch_object_http_with_accept<T: Clone, Kind: DeserializeOwned>(
config.verify_url_valid(url).await?; config.verify_url_valid(url).await?;
info!("Fetching remote object {}", url.to_string()); info!("Fetching remote object {}", url.to_string());
let mut counter = data.request_counter.fetch_add(1, Ordering::SeqCst); let mut counter = data.request_counter.0.fetch_add(1, Ordering::SeqCst);
// fetch_add returns old value so we need to increment manually here // fetch_add returns old value so we need to increment manually here
counter += 1; counter += 1;
if counter > config.http_fetch_limit { if counter > config.http_fetch_limit {