feat: extract file streaming into its own function

This commit is contained in:
kale 2024-05-27 16:58:13 +02:00
parent 0ac7b54a49
commit 0db27f3671
Signed by: kalmenn
GPG key ID: F500055C44BC3834

View file

@ -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;
}
}
}