use rong::*;
use std::cell::RefCell;
thread_local! {
static NETWORK_ACCESS_GUARD: RefCell<Box<dyn NetworkAccessGuard>> = RefCell::new(Box::new(DefaultNetworkAccessGuard));
}
pub trait NetworkAccessGuard {
fn check_access(&self, domain: &str) -> JSResult<()>;
}
#[derive(Default)]
struct DefaultNetworkAccessGuard;
impl NetworkAccessGuard for DefaultNetworkAccessGuard {
fn check_access(&self, _domain: &str) -> JSResult<()> {
Ok(()) }
}
pub fn set_network_access_guard(guard: Box<dyn NetworkAccessGuard>) {
NETWORK_ACCESS_GUARD.with(|g| {
*g.borrow_mut() = guard;
});
}
pub fn set_network_access_guard_scoped(
guard: Box<dyn NetworkAccessGuard>,
) -> NetworkAccessGuardScope {
let prev = NETWORK_ACCESS_GUARD.with(|g| std::mem::replace(&mut *g.borrow_mut(), guard));
NetworkAccessGuardScope { prev: Some(prev) }
}
pub struct NetworkAccessGuardScope {
prev: Option<Box<dyn NetworkAccessGuard>>,
}
impl Drop for NetworkAccessGuardScope {
fn drop(&mut self) {
if let Some(prev) = self.prev.take() {
NETWORK_ACCESS_GUARD.with(|g| {
*g.borrow_mut() = prev;
});
}
}
}
pub fn grant_network_access(domain: &str) -> JSResult<()> {
NETWORK_ACCESS_GUARD.with(|guard| guard.borrow().check_access(domain))
}