mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-29 00:00:18 +02:00
fix(axum-extra): don't require S generic param when using FileStream::from_path() (#3437)
This commit is contained in:
committed by
David Mládek
parent
0c2e4a2d09
commit
a77c2cf478
@@ -70,52 +70,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [`FileStream`] from a file path.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use axum::{
|
|
||||||
/// http::StatusCode,
|
|
||||||
/// response::IntoResponse,
|
|
||||||
/// Router,
|
|
||||||
/// routing::get
|
|
||||||
/// };
|
|
||||||
/// use axum_extra::response::file_stream::FileStream;
|
|
||||||
/// use tokio::fs::File;
|
|
||||||
/// use tokio_util::io::ReaderStream;
|
|
||||||
///
|
|
||||||
/// async fn file_stream() -> impl IntoResponse {
|
|
||||||
/// FileStream::<ReaderStream<File>>::from_path("test.txt")
|
|
||||||
/// .await
|
|
||||||
/// .map_err(|e| (StatusCode::NOT_FOUND, format!("File not found: {e}")))
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// let app = Router::new().route("/file-stream", get(file_stream));
|
|
||||||
/// # let _: Router = app;
|
|
||||||
/// ```
|
|
||||||
pub async fn from_path(path: impl AsRef<Path>) -> io::Result<FileStream<ReaderStream<File>>> {
|
|
||||||
let file = File::open(&path).await?;
|
|
||||||
let mut content_size = None;
|
|
||||||
let mut file_name = None;
|
|
||||||
|
|
||||||
if let Ok(metadata) = file.metadata().await {
|
|
||||||
content_size = Some(metadata.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(file_name_os) = path.as_ref().file_name() {
|
|
||||||
if let Some(file_name_str) = file_name_os.to_str() {
|
|
||||||
file_name = Some(file_name_str.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(FileStream {
|
|
||||||
stream: ReaderStream::new(file),
|
|
||||||
file_name,
|
|
||||||
content_size,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the file name of the [`FileStream`].
|
/// Set the file name of the [`FileStream`].
|
||||||
///
|
///
|
||||||
/// This adds the attachment `Content-Disposition` header with the given `file_name`.
|
/// This adds the attachment `Content-Disposition` header with the given `file_name`.
|
||||||
@@ -259,6 +213,53 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Split because the general impl requires to specify `S` and this one does not.
|
||||||
|
impl FileStream<ReaderStream<File>> {
|
||||||
|
/// Create a [`FileStream`] from a file path.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use axum::{
|
||||||
|
/// http::StatusCode,
|
||||||
|
/// response::IntoResponse,
|
||||||
|
/// Router,
|
||||||
|
/// routing::get
|
||||||
|
/// };
|
||||||
|
/// use axum_extra::response::file_stream::FileStream;
|
||||||
|
///
|
||||||
|
/// async fn file_stream() -> impl IntoResponse {
|
||||||
|
/// FileStream::from_path("test.txt")
|
||||||
|
/// .await
|
||||||
|
/// .map_err(|e| (StatusCode::NOT_FOUND, format!("File not found: {e}")))
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let app = Router::new().route("/file-stream", get(file_stream));
|
||||||
|
/// # let _: Router = app;
|
||||||
|
/// ```
|
||||||
|
pub async fn from_path(path: impl AsRef<Path>) -> io::Result<Self> {
|
||||||
|
let file = File::open(&path).await?;
|
||||||
|
let mut content_size = None;
|
||||||
|
let mut file_name = None;
|
||||||
|
|
||||||
|
if let Ok(metadata) = file.metadata().await {
|
||||||
|
content_size = Some(metadata.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(file_name_os) = path.as_ref().file_name() {
|
||||||
|
if let Some(file_name_str) = file_name_os.to_str() {
|
||||||
|
file_name = Some(file_name_str.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
stream: ReaderStream::new(file),
|
||||||
|
file_name,
|
||||||
|
content_size,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<S> IntoResponse for FileStream<S>
|
impl<S> IntoResponse for FileStream<S>
|
||||||
where
|
where
|
||||||
S: TryStream + Send + 'static,
|
S: TryStream + Send + 'static,
|
||||||
@@ -474,7 +475,7 @@ mod tests {
|
|||||||
let app = Router::new().route(
|
let app = Router::new().route(
|
||||||
"/from_path",
|
"/from_path",
|
||||||
get(move || async move {
|
get(move || async move {
|
||||||
FileStream::<ReaderStream<File>>::from_path(Path::new("CHANGELOG.md"))
|
FileStream::from_path(Path::new("CHANGELOG.md"))
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_response()
|
.into_response()
|
||||||
|
|||||||
Reference in New Issue
Block a user