You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.2 KiB
78 lines
2.2 KiB
use once_cell::sync::Lazy; |
|
use std::collections::HashSet; |
|
use std::io::Read; |
|
use std::iter::Iterator; |
|
use std::time::{Duration, SystemTime}; |
|
use u_lib::utils::SharedStorage; |
|
use uuid::Uuid; |
|
|
|
type Data = Box<dyn Read + Send + Sync>; |
|
|
|
/// This struct holds uids of various readable objects (files, streams, etc...) |
|
/// with timeout and permissions for any uids to read data |
|
struct MappedData { |
|
//ids that allowed to read the data |
|
for_ids: HashSet<Uuid>, |
|
created: SystemTime, |
|
timeout: Duration, |
|
data: Data, |
|
} |
|
|
|
impl MappedData { |
|
pub fn new( |
|
ids: impl Iterator<Item = Uuid>, |
|
data: impl Read + Send + Sync + 'static, |
|
timeout: Duration, |
|
) -> Self { |
|
MappedData { |
|
for_ids: ids.collect(), |
|
created: SystemTime::now(), |
|
timeout, |
|
data: Box::new(data), |
|
} |
|
} |
|
} |
|
|
|
static MAPPER: Lazy<SharedStorage<Uuid, MappedData>> = SharedStorage::new(); |
|
|
|
pub struct Mapper; |
|
|
|
impl Mapper { |
|
fn remove_overdue() { |
|
MAPPER |
|
.lock() |
|
.retain(|_, v| v.created.elapsed().unwrap() < v.timeout); |
|
} |
|
|
|
pub fn get(item_uid: Uuid, getter_uid: Uuid) -> Option<Data> { |
|
Self::remove_overdue(); |
|
let allowed_ids = MAPPER.lock().get(&item_uid)?.for_ids; |
|
if allowed_ids.contains(&getter_uid) { |
|
MAPPER.lock().remove(&item_uid).map(|d| d.data) |
|
} else { |
|
None |
|
} |
|
} |
|
|
|
pub fn set( |
|
for_ids: impl Iterator<Item = Uuid>, |
|
data: impl Read + Send + Sync + 'static, |
|
timeout: Option<Duration>, |
|
) -> Uuid { |
|
Self::remove_overdue(); |
|
let uid = Uuid::new_v4(); |
|
let timeout = timeout.unwrap_or(Duration::from_secs(60)); |
|
let mapped = MappedData::new(for_ids, data, timeout); |
|
MAPPER.lock().insert(uid, mapped); |
|
uid |
|
} |
|
} |
|
|
|
// init: |
|
// fill index struct with files allowed to download (probably auto-refresh index on file adding) |
|
// hashmap<stripped_hash_of_file_name, PathBuf> |
|
// download: |
|
// 1) agent sends download_request with hash of wanted file |
|
// 2) handler checks if this agent is allowed to dl file |
|
// 3) if all ok, create in entry in mapper and return its uid and hashsum to agent |
|
// 4) agent downloads file by uid, uid destructed after that
|
|
|