diff --git a/server/src/main.rs b/server/src/main.rs index 4a2be50..81b5b12 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,7 +1,7 @@ pub mod error; use error::{handle_rejection, InternalServerError, NotFoundError}; -use hyper::Body; +use hyper::{body, Body}; use std::path::PathBuf; use bytes::Bytes; @@ -49,7 +49,7 @@ pub async fn serve_local_tracks( // FIXME: for now, file paths need to be URL safe to be able to be requested location.push(PathBuf::from(track_name)); - let Ok(mut file) = tokio::fs::File::options().read(true).open(&location).await else { + let Ok(file) = tokio::fs::File::options().read(true).open(&location).await else { return Err(NotFoundError( format!("The requested song could not be found on disk. Tried loading {location:?}") .into(), @@ -59,29 +59,10 @@ pub async fn serve_local_tracks( // TODO: handle range requests - let (mut sender, body) = Body::channel(); + let (sender, body) = Body::channel(); debug!("Starting to stream file"); - tokio::task::spawn(async move { - let mut buf = [0u8; 512]; - - loop { - let bytes_read = match file.read(&mut buf).await { - Ok(0) => break debug!("Done streaming a file"), - Ok(bytes_read) => bytes_read, - Err(err) => break warn!("Couldn't read part of a file. Got err: {err}"), - }; - - let res = sender - .send_data(Bytes::copy_from_slice(&buf[..bytes_read])) - .await; - - if res.is_err() { - warn!("Failed to send some data to a client"); - break; - } - } - }); + tokio::task::spawn(stream_file(sender, file)); if let Ok(response) = hyper::Response::builder() .header("Content-Type", "audio/mpeg") @@ -93,3 +74,24 @@ pub async fn serve_local_tracks( Err(InternalServerError("Failed to build Response".into()).into()) } } + +pub async fn stream_file(mut dest: body::Sender, mut file: tokio::fs::File) { + let mut buf = [0u8; 512]; + + loop { + let bytes_read = match file.read(&mut buf).await { + Ok(0) => break debug!("Done streaming a file"), + Ok(bytes_read) => bytes_read, + Err(err) => break warn!("Couldn't read part of a file. Got err: {err}"), + }; + + let res = dest + .send_data(Bytes::copy_from_slice(&buf[..bytes_read])) + .await; + + if res.is_err() { + warn!("Failed to send some data to a client"); + break; + } + } +}