use crate::client::Client;
use crate::request::IqError;
use std::time::{Duration, Instant};
use wacore_ng::iq::mediaconn::MediaConnSpec;
pub use wacore_ng::iq::mediaconn::MediaConnHost;
pub(crate) const MEDIA_AUTH_REFRESH_RETRY_ATTEMPTS: usize = 1;
pub(crate) fn is_media_auth_error(status_code: u16) -> bool {
matches!(status_code, 401 | 403)
}
#[derive(Debug, Clone)]
pub struct MediaConn {
pub auth: String,
pub ttl: u64,
pub hosts: Vec<MediaConnHost>,
pub fetched_at: Instant,
}
impl MediaConn {
pub fn is_expired(&self) -> bool {
self.fetched_at.elapsed() > Duration::from_secs(self.ttl)
}
}
impl Client {
pub(crate) async fn invalidate_media_conn(&self) {
*self.media_conn.write().await = None;
}
pub(crate) async fn refresh_media_conn(&self, force: bool) -> Result<MediaConn, IqError> {
{
let guard = self.media_conn.read().await;
if !force
&& let Some(conn) = &*guard
&& !conn.is_expired()
{
return Ok(conn.clone());
}
}
let response = self.execute(MediaConnSpec::new()).await?;
let new_conn = MediaConn {
auth: response.auth,
ttl: response.ttl,
hosts: response.hosts,
fetched_at: Instant::now(),
};
let mut write_guard = self.media_conn.write().await;
*write_guard = Some(new_conn.clone());
Ok(new_conn)
}
}