Compare commits
1 Commits
master
...
4-update-c
Author | SHA1 | Date |
---|---|---|
plazmoid | 1124495540 | 3 years ago |
8 changed files with 221 additions and 8 deletions
@ -0,0 +1,65 @@ |
||||
use crate::worker::Worker; |
||||
use once_cell::sync::Lazy; |
||||
use sha2::{Digest, Sha512}; |
||||
use std::fs; |
||||
use std::path::PathBuf; |
||||
use u_lib::utils::{Hexlify, SharedStorage}; |
||||
|
||||
pub struct FileMeta { |
||||
hashsum: String, |
||||
path: PathBuf, |
||||
name: String, |
||||
} |
||||
|
||||
static FILES: Lazy<SharedStorage<String, FileMeta>> = SharedStorage::new(); |
||||
|
||||
pub struct FileIndex; |
||||
|
||||
impl FileIndex { |
||||
pub fn search_by_name(pat: impl Into<String>) -> Option<String> { |
||||
let name = pat.into(); |
||||
let (key, _) = FILES.lock().iter().find(|(_, v)| v.name == name)?; |
||||
Some(*key) |
||||
} |
||||
|
||||
pub fn get(key: impl Into<String>) -> Option<FileMeta> { |
||||
let name = key.into(); |
||||
FILES.get(&name).and_then(|r| Some(*r)) |
||||
} |
||||
} |
||||
|
||||
impl Worker for FileIndex { |
||||
fn process(&mut self) { |
||||
let hexlify = |data: &[u8]| format!("{:x}", Hexlify(data)); |
||||
let mut hasher = Sha512::new(); |
||||
for file in fs::read_dir("./files/hosted/").unwrap() { |
||||
let file = match file { |
||||
Ok(f) => f.path(), |
||||
Err(e) => { |
||||
warn!("Error reading file: {}", e); |
||||
continue; |
||||
} |
||||
}; |
||||
if file.is_file() { |
||||
let file_data = fs::read(file).unwrap(); |
||||
hasher.update(file_data); |
||||
let hashsum = hasher.finalize_reset(); |
||||
let shrinked_sum = hashsum |
||||
.iter() |
||||
.cloned() |
||||
.take(32) |
||||
.map(|b| b ^ 0x5a) |
||||
.collect::<Vec<u8>>(); |
||||
let shrinked_sum = hexlify(&shrinked_sum); |
||||
let hashsum = hexlify(&hashsum); |
||||
let name = file.file_name().unwrap().to_string_lossy().into_owned(); |
||||
let meta = FileMeta { |
||||
hashsum, |
||||
name, |
||||
path: file, |
||||
}; |
||||
FILES.lock().insert(shrinked_sum, meta); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,78 @@ |
||||
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
|
@ -0,0 +1,5 @@ |
||||
pub mod files; |
||||
pub mod mapper; |
||||
|
||||
pub use files::FileIndex; |
||||
pub use mapper::Mapper; |
@ -0,0 +1,3 @@ |
||||
pub trait Worker { |
||||
fn process(&mut self); |
||||
} |
Loading…
Reference in new issue