From 0f78fc277e1ef580cc4f51ade726cb31bb1878e0 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Mon, 27 Dec 2021 21:37:22 +0100 Subject: [PATCH] Call `stream_from_cdn` with `CdnUrl` --- audio/src/fetch/mod.rs | 9 +++++---- audio/src/fetch/receive.rs | 14 ++++++++------ core/src/cdn_url.rs | 10 ++++++++-- core/src/spclient.rs | 8 +++++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/audio/src/fetch/mod.rs b/audio/src/fetch/mod.rs index 3efdc1e9..346a786f 100644 --- a/audio/src/fetch/mod.rs +++ b/audio/src/fetch/mod.rs @@ -399,12 +399,13 @@ impl AudioFileStreaming { INITIAL_DOWNLOAD_SIZE }; + trace!("Streaming {}", file_id); + let cdn_url = CdnUrl::new(file_id).resolve_audio(&session).await?; - let url = cdn_url.try_get_url()?; - trace!("Streaming {:?}", url); - - let mut streamer = session.spclient().stream_file(url, 0, download_size)?; + let mut streamer = session + .spclient() + .stream_from_cdn(&cdn_url, 0, download_size)?; let request_time = Instant::now(); // Get the first chunk with the headers to get the file size. diff --git a/audio/src/fetch/receive.rs b/audio/src/fetch/receive.rs index 41f4ef84..e04c58d2 100644 --- a/audio/src/fetch/receive.rs +++ b/audio/src/fetch/receive.rs @@ -43,6 +43,8 @@ async fn receive_data( let mut data_offset = requested_offset; let mut request_length = requested_length; + // TODO : check Content-Length and Content-Range headers + let old_number_of_request = shared .number_of_open_requests .fetch_add(1, Ordering::SeqCst); @@ -180,14 +182,14 @@ impl AudioFileFetch { ranges_to_request.subtract_range_set(&download_status.downloaded); ranges_to_request.subtract_range_set(&download_status.requested); - // Likewise, checking for the URL expiry once will guarantee validity long enough. - let url = self.shared.cdn_url.try_get_url()?; + // TODO : refresh cdn_url when the token expired for range in ranges_to_request.iter() { - let streamer = self - .session - .spclient() - .stream_file(url, range.start, range.length)?; + let streamer = self.session.spclient().stream_from_cdn( + &self.shared.cdn_url, + range.start, + range.length, + )?; download_status.requested.add_range(range); diff --git a/core/src/cdn_url.rs b/core/src/cdn_url.rs index 409d7f25..befdefd6 100644 --- a/core/src/cdn_url.rs +++ b/core/src/cdn_url.rs @@ -39,13 +39,15 @@ pub enum CdnUrlError { Expired, #[error("resolved storage is not for CDN")] Storage, + #[error("no URLs resolved")] + Unresolved, } impl From for Error { fn from(err: CdnUrlError) -> Self { match err { CdnUrlError::Expired => Error::deadline_exceeded(err), - CdnUrlError::Storage => Error::unavailable(err), + CdnUrlError::Storage | CdnUrlError::Unresolved => Error::unavailable(err), } } } @@ -66,7 +68,7 @@ impl CdnUrl { pub async fn resolve_audio(&self, session: &Session) -> Result { let file_id = self.file_id; - let response = session.spclient().get_audio_urls(file_id).await?; + let response = session.spclient().get_audio_storage(file_id).await?; let msg = CdnUrlMessage::parse_from_bytes(&response)?; let urls = MaybeExpiringUrls::try_from(msg)?; @@ -78,6 +80,10 @@ impl CdnUrl { } pub fn try_get_url(&self) -> Result<&str, Error> { + if self.urls.is_empty() { + return Err(CdnUrlError::Unresolved.into()); + } + let now = Local::now(); let url = self.urls.iter().find(|url| match url.1 { Some(expiry) => now < expiry.as_utc(), diff --git a/core/src/spclient.rs b/core/src/spclient.rs index c4285cd4..1adfa3f8 100644 --- a/core/src/spclient.rs +++ b/core/src/spclient.rs @@ -13,6 +13,7 @@ use rand::Rng; use crate::{ apresolve::SocketAddress, + cdn_url::CdnUrl, error::ErrorKind, protocol::{ canvaz::EntityCanvazRequest, connect::PutStateRequest, @@ -261,7 +262,7 @@ impl SpClient { .await } - pub async fn get_audio_urls(&self, file_id: FileId) -> SpClientResult { + pub async fn get_audio_storage(&self, file_id: FileId) -> SpClientResult { let endpoint = format!( "/storage-resolve/files/audio/interactive/{}", file_id.to_base16() @@ -269,12 +270,13 @@ impl SpClient { self.request(&Method::GET, &endpoint, None, None).await } - pub fn stream_file( + pub fn stream_from_cdn( &self, - url: &str, + cdn_url: &CdnUrl, offset: usize, length: usize, ) -> Result, Error> { + let url = cdn_url.try_get_url()?; let req = Request::builder() .method(&Method::GET) .uri(url)