-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add an encapsulated file stream in axum-extra to make it more conveni… #3047
base: main
Are you sure you want to change the base?
Conversation
…ent when you need to return a file as a response
…s with file name and content size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good to me 💯
Can you add an entry in the https://github.com/tokio-rs/axum/blob/main/axum-extra/CHANGELOG.md ? |
Yes, I added it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few things I'd like to see improved before we ship this, but maybe it's easier if we merge now and I post a follow-up PR. It's nothing big.
Okay, I improved it. Can you review it again? |
the usage of this PR feature seems rather limited. for example, it seems that it does not handle HTTP range requests and it limited the response header. it fixed to and even in download mode, it does not support inline, only support attachment model. people may want to steam a video file, and need HTTP range requests support. as a framework, the feature builtin should be more general. I suggest put this as an external crate, if it is limited to |
@ttys3 yes I see your point. |
Wait, why would we not add stuff like range header support to this and have it in axum-extra then? It's a very common feature request. |
I added file streaming support for range headers with the I just wanted simple support for streaming file downloads, so I didn't make it complicated, and perhaps it should have been added to the |
But as a standalone crate is it too simple, maybe it should be added to the attachment feature? |
let mut buffer = vec![0; buffer_size]; | ||
|
||
let stream = async_stream::try_stream! { | ||
let mut total_read = 0; | ||
|
||
while total_read < end { | ||
let bytes_to_read = std::cmp::min(buffer_size as u64, end - total_read); | ||
let n = file.read(&mut buffer[..bytes_to_read as usize]).await.map_err(|e| { | ||
std::io::Error::new(std::io::ErrorKind::Other, e) | ||
})?; | ||
if n == 0 { | ||
break; // EOF | ||
} | ||
total_read += n as u64; | ||
yield buffer[..n].to_vec(); | ||
|
||
} | ||
}; | ||
Ok(stream) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible to replace this entire part with AsyncReadExt::take
and then going back to ReaderStream
I still think it makes sense to have this as a feature. It's independent of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to split the example change into a separate PR.
/// Alias for `tokio_util::io::ReaderStream<File>`. | ||
pub type AsyncReaderStream = ReaderStream<File>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the type alias? ReaderStream<File>
is not a very complex type.
I've pushed a bunch of minor changes, hope that's fine. Previous review comments should still be valid. |
Motivation
In use will need to return a file stream, encapsulates a file stream structure to save the return time to add the header
Solution
In axum-extra add a response structure, the construction needs to pass a file stream, in the response will add the header: “application/octet-stream”, I added the documentation and examples these will be more detailed
See examples/stream-to-file for a short demonstration I've added usage to this example.
I just started using rust, so some of the code may not be well written