Feature Proposal: Add `try_clone` method to `Body` trait
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 173
- Forks
- 69
- Avg merge
- 6d 15h
- Merged PRs (30d)
- 4
Description
Description
When building HTTP clients with tower, tower-http, http-body, we often need to reuse the body data—most commonly for:
- Retrying requests after transient errors
- Following 3xx redirects
- Others...
It is awkward now when working with something like tower::retry, because any middleware is free to wrap the original body in a new type that does not implement Clone.
Once the concrete type is erased (e.g. BoxBody), it forces users to add an extra warpper (“clone adapter”) to make it compile, or to buffer the entire body data, neither of which is ideal.
Proposal
Add a default method to the Body trait:
/// Try to clone this body if the underlying implementation supports it.
///
/// Returns `Some(cloned)` if the entire body can be reproduced verbatim, `None` otherwise.
///
/// Implementations that wrap another body must delegate this call so that the capability is preserved through arbitrary middleware.
fn try_clone(&self) -> Option<Self>
where
Self: Sized,
{
None
}
- No breaking change—every existing type continues to compile, and works as before.
- Middleware that only wrap the inner body can forward the call in one line.
- Retry/redirect policies can attempt try_clone() first and only fall back to buffering when it returns None, keeping the fast path zero-copy.
Alternatives considered
rewind() would also work, which reset the body stream to begining. it good for seekable I/O like files maybe.
/// Return value tell is if rewind success.
///
/// For example: body construct from short `String`, `Vec<u8>`, `Bytes`,... always return true, and retry goes on.
/// body construct from channel/stream, return false, so that retry can not continue.
fn rewind(&mut self) -> bool {
false
}
However, I believe try_clone is more general and the better choice.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue identifies the Body trait as the entry point; read its current definition and implementations, then inspect the retry and redirect use cases named here. Confirm the API shape, delegation expectations, and coverage needed for successful cloning versus unsupported bodies before considering the proposal complete.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100