Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion s3/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ default = ["fail-on-err", "tags", "tokio-native-tls"]
sync = ["attohttpc", "maybe-async/is_sync"]
with-async-std-hyper = ["with-async-std", "surf/hyper-client"]
with-async-std = ["async-std", "futures"]
with-tokio = ["futures", "reqwest", "tokio", "tokio/fs", "tokio-stream"]
with-tokio = ["futures/alloc", "reqwest", "tokio", "tokio/fs", "tokio-stream"]

blocking = ["block_on_proc", "tokio/rt", "tokio/rt-multi-thread"]
fail-on-err = []
Expand Down
23 changes: 23 additions & 0 deletions s3/src/request/request_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,29 @@ impl fmt::Display for ResponseData {
}
}

#[cfg(feature = "with-tokio")]
impl tokio::io::AsyncRead for ResponseDataStream {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>,
) -> std::task::Poll<std::io::Result<()>> {
use futures::StreamExt;
let bytes = self.get_mut().bytes();
match bytes.poll_next_unpin(cx) {
std::task::Poll::Ready(Some(Ok(chunk))) => {
buf.put_slice(&chunk); // Put the chunk into the buffer
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation doesn't check if the chunk size exceeds the buffer's remaining capacity. This could cause a panic if the chunk is larger than the available buffer space. Consider using buf.remaining() to check capacity and handle partial writes appropriately.

Copilot uses AI. Check for mistakes.
std::task::Poll::Ready(Ok(()))
}
std::task::Poll::Ready(Some(Err(error))) => {
std::task::Poll::Ready(Err(std::io::Error::new(std::io::ErrorKind::Other, error)))
}
std::task::Poll::Ready(None) => std::task::Poll::Ready(Ok(())),
Copy link

Copilot AI Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the stream ends (None), the implementation should signal EOF by returning 0 bytes read. The current implementation returns Ok(()) but doesn't indicate to the reader that no more data is available. Consider checking if any bytes were written to the buffer and handle EOF correctly according to AsyncRead semantics.

Suggested change
std::task::Poll::Ready(None) => std::task::Poll::Ready(Ok(())),
// If no bytes were written to the buffer in this poll, signal EOF by returning Ok(())
std::task::Poll::Ready(None) => {
// If the buffer was not filled in this poll, this signals EOF (0 bytes read)
std::task::Poll::Ready(Ok(()))
},

Copilot uses AI. Check for mistakes.
std::task::Poll::Pending => std::task::Poll::Pending,
}
}
}

#[maybe_async::maybe_async]
pub trait Request {
type Response;
Expand Down