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

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