diff --git a/src/body.rs b/src/body.rs
index 5e847b9..4933c51 100644
--- a/src/body.rs
+++ b/src/body.rs
@@ -109,6 +109,11 @@ impl Body {
}
}
}
+
+ pub(crate) fn try_clone(&self) -> Option
{
+ self.kind.try_clone()
+ .map(|kind| Body { kind })
+ }
}
@@ -117,6 +122,15 @@ enum Kind {
Bytes(Bytes),
}
+impl Kind {
+ fn try_clone(&self) -> Option {
+ match self {
+ Kind::Reader(..) => None,
+ Kind::Bytes(v) => Some(Kind::Bytes(v.clone())),
+ }
+ }
+}
+
impl From> for Body {
#[inline]
fn from(v: Vec) -> Body {
diff --git a/src/request.rs b/src/request.rs
index dcec6c9..b30f0bc 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -81,6 +81,26 @@ impl Request {
&mut self.body
}
+ /// Attempts to clone the `Request`.
+ ///
+ /// None is returned if a body is which can not be cloned. This can be because the body is a
+ /// stream.
+ pub fn try_clone(&self) -> Option {
+ let body = if let Some(ref body) = self.body.as_ref() {
+ if let Some(body) = body.try_clone() {
+ Some(body)
+ } else {
+ return None;
+ }
+ } else {
+ None
+ };
+ let mut req = Request::new(self.method().clone(), self.url().clone());
+ *req.headers_mut() = self.headers().clone();
+ req.body = body;
+ Some(req)
+ }
+
pub(crate) fn into_async(self) -> (async_impl::Request, Option) {
use header::CONTENT_LENGTH;
@@ -484,6 +504,61 @@ impl RequestBuilder {
self.client.execute(self.request?)
}
+ /// Attempts to clone the `RequestBuilder`.
+ ///
+ /// None is returned if a body is which can not be cloned. This can be because the body is a
+ /// stream.
+ ///
+ /// # Examples
+ ///
+ /// With a static body
+ ///
+ /// ```rust
+ /// # fn run() -> Result<(), Box<::std::error::Error>> {
+ /// let client = reqwest::Client::new();
+ /// let builder = client.post("http://httpbin.org/post")
+ /// .body("from a &str!");
+ /// let clone = builder.try_clone();
+ /// assert!(clone.is_some());
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// Without a body
+ ///
+ /// ```rust
+ /// # fn run() -> Result<(), Box<::std::error::Error>> {
+ /// let client = reqwest::Client::new();
+ /// let builder = client.get("http://httpbin.org/get");
+ /// let clone = builder.try_clone();
+ /// assert!(clone.is_some());
+ /// # Ok(())
+ /// # }
+ /// ```
+ ///
+ /// With a non-clonable body
+ ///
+ /// ```rust
+ /// # fn run() -> Result<(), Box<::std::error::Error>> {
+ /// let client = reqwest::Client::new();
+ /// let builder = client.get("http://httpbin.org/get")
+ /// .body(reqwest::Body::new(std::io::empty()));
+ /// let clone = builder.try_clone();
+ /// assert!(clone.is_none());
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn try_clone(&self) -> Option {
+ self.request.as_ref()
+ .ok()
+ .and_then(|req| req.try_clone())
+ .map(|req| {
+ RequestBuilder{
+ client: self.client.clone(),
+ request: Ok(req),
+ }
+ })
+ }
}
impl fmt::Debug for Request {