@@ -125,6 +125,13 @@ impl Body {
|
|||||||
(reuse, self)
|
(reuse, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn try_clone(&self) -> Option<Body> {
|
||||||
|
match self.inner {
|
||||||
|
Inner::Reusable(ref chunk) => Some(Body::reusable(chunk.clone())),
|
||||||
|
Inner::Streaming { .. } => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn into_stream(self) -> ImplStream {
|
pub(crate) fn into_stream(self) -> ImplStream {
|
||||||
ImplStream(self)
|
ImplStream(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,20 @@ impl Request {
|
|||||||
&mut self.body
|
&mut self.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to clone the request.
|
||||||
|
///
|
||||||
|
/// `None` is returned if the request can not be cloned, i.e. if the body is a stream.
|
||||||
|
pub fn try_clone(&self) -> Option<Request> {
|
||||||
|
let body = match self.body.as_ref() {
|
||||||
|
Some(ref body) => Some(body.try_clone()?),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
let mut req = Request::new(self.method().clone(), self.url().clone());
|
||||||
|
*req.headers_mut() = self.headers().clone();
|
||||||
|
req.body = body;
|
||||||
|
Some(req)
|
||||||
|
}
|
||||||
|
|
||||||
pub(super) fn pieces(self) -> (Method, Url, HeaderMap, Option<Body>) {
|
pub(super) fn pieces(self) -> (Method, Url, HeaderMap, Option<Body>) {
|
||||||
(self.method, self.url, self.headers, self.body)
|
(self.method, self.url, self.headers, self.body)
|
||||||
}
|
}
|
||||||
@@ -323,6 +337,36 @@ impl RequestBuilder {
|
|||||||
Err(err) => Pending::new_err(err),
|
Err(err) => Pending::new_err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to clone the RequestBuilder.
|
||||||
|
///
|
||||||
|
/// `None` is returned if the RequestBuilder can not be cloned,
|
||||||
|
/// i.e. if the request body is a stream.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use reqwest::Error;
|
||||||
|
/// #
|
||||||
|
/// # fn run() -> Result<(), 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(())
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn try_clone(&self) -> Option<RequestBuilder> {
|
||||||
|
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 {
|
impl fmt::Debug for Request {
|
||||||
@@ -380,6 +424,7 @@ pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::Client;
|
use super::Client;
|
||||||
|
use crate::Method;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
@@ -488,6 +533,52 @@ mod tests {
|
|||||||
assert_eq!(req.url().as_str(), "https://google.com/");
|
assert_eq!(req.url().as_str(), "https://google.com/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_clone_reusable() {
|
||||||
|
let client = Client::new();
|
||||||
|
let builder = client.post("http://httpbin.org/post")
|
||||||
|
.header("foo", "bar")
|
||||||
|
.body("from a &str!");
|
||||||
|
let req = builder
|
||||||
|
.try_clone()
|
||||||
|
.expect("clone successful")
|
||||||
|
.build()
|
||||||
|
.expect("request is valid");
|
||||||
|
assert_eq!(req.url().as_str(), "http://httpbin.org/post");
|
||||||
|
assert_eq!(req.method(), Method::POST);
|
||||||
|
assert_eq!(req.headers()["foo"], "bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn try_clone_no_body() {
|
||||||
|
let client = Client::new();
|
||||||
|
let builder = client.get("http://httpbin.org/get");
|
||||||
|
let req = builder
|
||||||
|
.try_clone()
|
||||||
|
.expect("clone successful")
|
||||||
|
.build()
|
||||||
|
.expect("request is valid");
|
||||||
|
assert_eq!(req.url().as_str(), "http://httpbin.org/get");
|
||||||
|
assert_eq!(req.method(), Method::GET);
|
||||||
|
assert!(req.body().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "unstable-stream")]
|
||||||
|
fn try_clone_stream() {
|
||||||
|
let chunks: Vec<Result<_, ::std::io::Error>> = vec![
|
||||||
|
Ok("hello"),
|
||||||
|
Ok(" "),
|
||||||
|
Ok("world"),
|
||||||
|
];
|
||||||
|
let stream = futures_util::stream::iter(chunks);
|
||||||
|
let client = Client::new();
|
||||||
|
let builder = client.get("http://httpbin.org/get")
|
||||||
|
.body(super::Body::wrap_stream(stream));
|
||||||
|
let clone = builder.try_clone();
|
||||||
|
assert!(clone.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
use {body, Method};
|
use {body, Method};
|
||||||
use super::Client;
|
use super::Client;
|
||||||
|
|||||||
Reference in New Issue
Block a user