Implement more realistic doctests. (#222)
Add is_test and fn main headers to various doctests, and use real URLs along with the ? operator.
This commit is contained in:
committed by
GitHub
parent
ec8dace1af
commit
203573d27c
123
src/agent.rs
123
src/agent.rs
@@ -44,25 +44,22 @@ pub(crate) struct AgentConfig {
|
|||||||
/// can keep a state.
|
/// can keep a state.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// let mut agent = ureq::agent();
|
/// let mut agent = ureq::agent();
|
||||||
///
|
///
|
||||||
/// let auth = agent
|
/// agent
|
||||||
/// .post("/login")
|
/// .post("http://example.com/login")
|
||||||
/// .call(); // blocks.
|
/// .call()?;
|
||||||
///
|
|
||||||
/// if auth.is_err() {
|
|
||||||
/// println!("Noes!");
|
|
||||||
/// }
|
|
||||||
///
|
///
|
||||||
/// let secret = agent
|
/// let secret = agent
|
||||||
/// .get("/my-protected-page")
|
/// .get("http://example.com/my-protected-page")
|
||||||
/// .call(); // blocks and waits for request.
|
/// .call()?
|
||||||
|
/// .into_string()?;
|
||||||
///
|
///
|
||||||
/// if secret.is_err() {
|
/// println!("Secret is: {}", secret);
|
||||||
/// println!("Wot?!");
|
/// # Ok(())
|
||||||
/// } else {
|
/// # }
|
||||||
/// println!("Secret is: {}", secret.unwrap().into_string().unwrap());
|
|
||||||
/// }
|
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Agent uses an inner Arc, so cloning an Agent results in an instance
|
/// Agent uses an inner Arc, so cloning an Agent results in an instance
|
||||||
@@ -99,12 +96,15 @@ impl Agent {
|
|||||||
/// Request by providing the HTTP verb such as `GET`, `POST`...
|
/// Request by providing the HTTP verb such as `GET`, `POST`...
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// let agent = ureq::agent();
|
/// let agent = ureq::agent();
|
||||||
///
|
///
|
||||||
/// let r = agent
|
/// let resp = agent
|
||||||
/// .request("GET", "/my_page")
|
/// .request("GET", "http://httpbin.org/status/200")
|
||||||
/// .call();
|
/// .call()?;
|
||||||
/// println!("{:?}", r);
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn request(&self, method: &str, path: &str) -> Request {
|
pub fn request(&self, method: &str, path: &str) -> Request {
|
||||||
Request::new(self.clone(), method.into(), path.into())
|
Request::new(self.clone(), method.into(), path.into())
|
||||||
@@ -143,15 +143,18 @@ impl Agent {
|
|||||||
/// use std::io::Write;
|
/// use std::io::Write;
|
||||||
/// use std::fs::File;
|
/// use std::fs::File;
|
||||||
///
|
///
|
||||||
/// let mut file = File::create("cookies.json").unwrap();
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
///
|
/// # ureq::is_test(true);
|
||||||
/// let agent = ureq::agent();
|
/// let agent = ureq::agent();
|
||||||
///
|
///
|
||||||
/// // Cookies set by www.google.com are stored in agent.
|
/// // Cookies set by www.google.com are stored in agent.
|
||||||
/// agent.get("https://www.google.com/").call().unwrap();
|
/// agent.get("https://www.google.com/").call()?;
|
||||||
///
|
///
|
||||||
/// // Saves (persistent) cookies
|
/// // Saves (persistent) cookies
|
||||||
|
/// let mut file = File::create("cookies.json")?;
|
||||||
/// agent.cookie_store().save_json(&mut file).unwrap();
|
/// agent.cookie_store().save_json(&mut file).unwrap();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "cookies")]
|
#[cfg(feature = "cookies")]
|
||||||
pub fn cookie_store(&self) -> CookieStoreGuard<'_> {
|
pub fn cookie_store(&self) -> CookieStoreGuard<'_> {
|
||||||
@@ -209,10 +212,14 @@ impl AgentBuilder {
|
|||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// let proxy = ureq::Proxy::new("user:password@cool.proxy:9090").unwrap();
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let proxy = ureq::Proxy::new("user:password@cool.proxy:9090")?;
|
||||||
/// let agent = ureq::AgentBuilder::new()
|
/// let agent = ureq::AgentBuilder::new()
|
||||||
/// .proxy(proxy)
|
/// .proxy(proxy)
|
||||||
/// .build();
|
/// .build();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn proxy(mut self, proxy: Proxy) -> Self {
|
pub fn proxy(mut self, proxy: Proxy) -> Self {
|
||||||
self.config.proxy = Some(proxy);
|
self.config.proxy = Some(proxy);
|
||||||
@@ -224,7 +231,9 @@ impl AgentBuilder {
|
|||||||
/// connection pooling.
|
/// connection pooling.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let agent = ureq::AgentBuilder::new().max_idle_connections(200).build();
|
/// let agent = ureq::AgentBuilder::new()
|
||||||
|
/// .max_idle_connections(200)
|
||||||
|
/// .build();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn max_idle_connections(mut self, max: usize) -> Self {
|
pub fn max_idle_connections(mut self, max: usize) -> Self {
|
||||||
self.max_idle_connections = max;
|
self.max_idle_connections = max;
|
||||||
@@ -236,7 +245,9 @@ impl AgentBuilder {
|
|||||||
/// would disable connection pooling.
|
/// would disable connection pooling.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let agent = ureq::AgentBuilder::new().max_idle_connections_per_host(200).build();
|
/// let agent = ureq::AgentBuilder::new()
|
||||||
|
/// .max_idle_connections_per_host(200)
|
||||||
|
/// .build();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn max_idle_connections_per_host(mut self, max: usize) -> Self {
|
pub fn max_idle_connections_per_host(mut self, max: usize) -> Self {
|
||||||
self.max_idle_connections_per_host = max;
|
self.max_idle_connections_per_host = max;
|
||||||
@@ -274,10 +285,15 @@ impl AgentBuilder {
|
|||||||
/// The default is 30 seconds.
|
/// The default is 30 seconds.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .timeout_connect(std::time::Duration::from_secs(1))
|
/// .timeout_connect(Duration::from_secs(1))
|
||||||
/// .build();
|
/// .build();
|
||||||
/// let r = agent.get("/my_page").call();
|
/// let result = agent.get("http://httpbin.org/delay/20").call();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn timeout_connect(mut self, timeout: Duration) -> Self {
|
pub fn timeout_connect(mut self, timeout: Duration) -> Self {
|
||||||
self.config.timeout_connect = Some(timeout);
|
self.config.timeout_connect = Some(timeout);
|
||||||
@@ -288,13 +304,18 @@ impl AgentBuilder {
|
|||||||
/// If both this and `.timeout()` are both set, `.timeout()`
|
/// If both this and `.timeout()` are both set, `.timeout()`
|
||||||
/// takes precedence.
|
/// takes precedence.
|
||||||
///
|
///
|
||||||
/// The default is `0`, which means it can block forever.
|
/// The default is no timeout. In other words, requests may block forever on reads by default.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .timeout_read(std::time::Duration::from_secs(1))
|
/// .timeout_read(Duration::from_secs(1))
|
||||||
/// .build();
|
/// .build();
|
||||||
/// let r = agent.get("/my_page").call();
|
/// let result = agent.get("http://httpbin.org/delay/20").call();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn timeout_read(mut self, timeout: Duration) -> Self {
|
pub fn timeout_read(mut self, timeout: Duration) -> Self {
|
||||||
self.config.timeout_read = Some(timeout);
|
self.config.timeout_read = Some(timeout);
|
||||||
@@ -305,13 +326,18 @@ impl AgentBuilder {
|
|||||||
/// If both this and `.timeout()` are both set, `.timeout()`
|
/// If both this and `.timeout()` are both set, `.timeout()`
|
||||||
/// takes precedence.
|
/// takes precedence.
|
||||||
///
|
///
|
||||||
/// The default is `0`, which means it can block forever.
|
/// The default is no timeout. In other words, requests may block forever on writes by default.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// use std::time::Duration;
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .timeout_write(std::time::Duration::from_secs(1))
|
/// .timeout_read(Duration::from_secs(1))
|
||||||
/// .build();
|
/// .build();
|
||||||
/// let r = agent.get("/my_page").call();
|
/// let result = agent.get("http://httpbin.org/delay/20").call();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn timeout_write(mut self, timeout: Duration) -> Self {
|
pub fn timeout_write(mut self, timeout: Duration) -> Self {
|
||||||
self.config.timeout_write = Some(timeout);
|
self.config.timeout_write = Some(timeout);
|
||||||
@@ -327,11 +353,15 @@ impl AgentBuilder {
|
|||||||
/// not `.timeout_connect()`.
|
/// not `.timeout_connect()`.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// // wait max 1 second for whole request to complete.
|
/// // wait max 1 second for whole request to complete.
|
||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .timeout(std::time::Duration::from_secs(1))
|
/// .timeout(std::time::Duration::from_secs(1))
|
||||||
/// .build();
|
/// .build();
|
||||||
/// let r = agent.get("/my_page").call();
|
/// let result = agent.get("http://httpbin.org/delay/20").call();
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||||
self.config.timeout = Some(timeout);
|
self.config.timeout = Some(timeout);
|
||||||
@@ -346,12 +376,15 @@ impl AgentBuilder {
|
|||||||
/// If the redirect count hits this limit (and it's > 0), TooManyRedirects is returned.
|
/// If the redirect count hits this limit (and it's > 0), TooManyRedirects is returned.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let r = ureq::builder()
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// .redirects(10)
|
/// # ureq::is_test(true);
|
||||||
|
/// let result = ureq::builder()
|
||||||
|
/// .redirects(1)
|
||||||
/// .build()
|
/// .build()
|
||||||
/// .get("/my_page")
|
/// .get("http://httpbin.org/redirect/3")
|
||||||
/// .call();
|
/// .call();
|
||||||
/// println!("{:?}", r);
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn redirects(mut self, n: u32) -> Self {
|
pub fn redirects(mut self, n: u32) -> Self {
|
||||||
self.config.redirects = n;
|
self.config.redirects = n;
|
||||||
@@ -362,11 +395,15 @@ impl AgentBuilder {
|
|||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// let tls_config = std::sync::Arc::new(rustls::ClientConfig::new());
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// use std::sync::Arc;
|
||||||
|
/// let tls_config = Arc::new(rustls::ClientConfig::new());
|
||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .tls_config(tls_config.clone())
|
/// .tls_config(tls_config.clone())
|
||||||
/// .build();
|
/// .build();
|
||||||
/// let req = agent.post("https://cool.server");
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
pub fn tls_config(mut self, tls_config: Arc<rustls::ClientConfig>) -> Self {
|
pub fn tls_config(mut self, tls_config: Arc<rustls::ClientConfig>) -> Self {
|
||||||
@@ -382,11 +419,12 @@ impl AgentBuilder {
|
|||||||
///
|
///
|
||||||
/// Example
|
/// Example
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
/// use cookie_store::CookieStore;
|
/// use cookie_store::CookieStore;
|
||||||
/// use std::fs::File;
|
/// use std::fs::File;
|
||||||
/// use std::io::BufReader;
|
/// use std::io::BufReader;
|
||||||
///
|
/// let file = File::open("cookies.json")?;
|
||||||
/// let file = File::open("cookies.json").unwrap();
|
|
||||||
/// let read = BufReader::new(file);
|
/// let read = BufReader::new(file);
|
||||||
///
|
///
|
||||||
/// // Read persisted cookies from cookies.json
|
/// // Read persisted cookies from cookies.json
|
||||||
@@ -396,7 +434,8 @@ impl AgentBuilder {
|
|||||||
/// let agent = ureq::builder()
|
/// let agent = ureq::builder()
|
||||||
/// .cookie_store(my_store)
|
/// .cookie_store(my_store)
|
||||||
/// .build();
|
/// .build();
|
||||||
///;
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(feature = "cookies")]
|
#[cfg(feature = "cookies")]
|
||||||
pub fn cookie_store(mut self, cookie_store: CookieStore) -> Self {
|
pub fn cookie_store(mut self, cookie_store: CookieStore) -> Self {
|
||||||
|
|||||||
116
src/request.rs
116
src/request.rs
@@ -18,11 +18,13 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||||||
/// Request instances are builders that creates a request.
|
/// Request instances are builders that creates a request.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut request = ureq::get("https://www.google.com/");
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
///
|
/// # ureq::is_test(true);
|
||||||
/// let response = request
|
/// let response = ureq::get("http://example.com/form")
|
||||||
/// .query("foo", "bar baz") // add ?foo=bar%20baz
|
/// .query("foo", "bar baz") // add ?foo=bar+baz
|
||||||
/// .call(); // run the request
|
/// .call()?; // run the request
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Request {
|
pub struct Request {
|
||||||
@@ -61,13 +63,16 @@ impl Request {
|
|||||||
/// Use `.timeout_connect()` and `.timeout_read()` to avoid blocking forever.
|
/// Use `.timeout_connect()` and `.timeout_read()` to avoid blocking forever.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let r = ureq::builder()
|
/// use std::time::Duration;
|
||||||
/// .timeout_connect(std::time::Duration::from_secs(10)) // max 10 seconds
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::builder()
|
||||||
|
/// .timeout_connect(Duration::from_secs(10))
|
||||||
/// .build()
|
/// .build()
|
||||||
/// .get("/my_page")
|
/// .get("http://example.com/")
|
||||||
/// .call();
|
/// .call()?;
|
||||||
///
|
/// # Ok(())
|
||||||
/// println!("{:?}", r);
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn call(self) -> Result<Response> {
|
pub fn call(self) -> Result<Response> {
|
||||||
self.do_call(Payload::Empty)
|
self.do_call(Payload::Empty)
|
||||||
@@ -104,8 +109,11 @@ impl Request {
|
|||||||
/// ```
|
/// ```
|
||||||
/// # fn main() -> Result<(), ureq::Error> {
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// # ureq::is_test(true);
|
/// # ureq::is_test(true);
|
||||||
/// let r = ureq::post("http://example.com/form")
|
/// let resp = ureq::post("http://httpbin.org/post")
|
||||||
/// .send_json(ureq::json!({ "name": "martin", "rust": true }))?;
|
/// .send_json(ureq::json!({
|
||||||
|
/// "name": "martin",
|
||||||
|
/// "rust": true,
|
||||||
|
/// }))?;
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -122,10 +130,12 @@ impl Request {
|
|||||||
/// The `Content-Length` header is implicitly set to the length of the serialized value.
|
/// The `Content-Length` header is implicitly set to the length of the serialized value.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let body = b"Hello world!";
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let r = ureq::post("/my_page")
|
/// # ureq::is_test(true);
|
||||||
/// .send_bytes(body);
|
/// let resp = ureq::put("http://httpbin.org/put")
|
||||||
/// println!("{:?}", r);
|
/// .send_bytes(&[0; 1000])?;
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn send_bytes(self, data: &[u8]) -> Result<Response> {
|
pub fn send_bytes(self, data: &[u8]) -> Result<Response> {
|
||||||
self.do_call(Payload::Bytes(data))
|
self.do_call(Payload::Bytes(data))
|
||||||
@@ -147,10 +157,13 @@ impl Request {
|
|||||||
/// ```
|
/// ```
|
||||||
/// // this example requires features = ["charset"]
|
/// // this example requires features = ["charset"]
|
||||||
///
|
///
|
||||||
/// let r = ureq::post("/my_page")
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::post("http://httpbin.org/post")
|
||||||
/// .set("Content-Type", "text/plain; charset=iso-8859-1")
|
/// .set("Content-Type", "text/plain; charset=iso-8859-1")
|
||||||
/// .send_string("Hällo Wörld!");
|
/// .send_string("Hällo Wörld!")?;
|
||||||
/// println!("{:?}", r);
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn send_string(self, data: &str) -> Result<Response> {
|
pub fn send_string(self, data: &str) -> Result<Response> {
|
||||||
let charset =
|
let charset =
|
||||||
@@ -164,14 +177,15 @@ impl Request {
|
|||||||
/// The `Content-Length` header is implicitly set to the length of the serialized value.
|
/// The `Content-Length` header is implicitly set to the length of the serialized value.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// #[macro_use]
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// extern crate ureq;
|
/// # ureq::is_test(true);
|
||||||
///
|
/// let resp = ureq::post("http://httpbin.org/post")
|
||||||
/// fn main() {
|
/// .send_form(&[
|
||||||
/// let r = ureq::post("/my_page")
|
/// ("foo", "bar"),
|
||||||
/// .send_form(&[("foo", "bar"),("foo2", "bar2")]);
|
/// ("foo2", "bar2"),
|
||||||
/// println!("{:?}", r);
|
/// ])?;
|
||||||
/// }
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn send_form(mut self, data: &[(&str, &str)]) -> Result<Response> {
|
pub fn send_form(mut self, data: &[(&str, &str)]) -> Result<Response> {
|
||||||
if self.header("Content-Type").is_none() {
|
if self.header("Content-Type").is_none() {
|
||||||
@@ -194,12 +208,13 @@ impl Request {
|
|||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::io::Cursor;
|
/// use std::io::Cursor;
|
||||||
///
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let read = Cursor::new(vec![0x20; 100_000]);
|
/// # ureq::is_test(true);
|
||||||
///
|
/// let read = Cursor::new(vec![0x20; 100]);
|
||||||
/// let resp = ureq::post("http://localhost/example-upload")
|
/// let resp = ureq::post("http://httpbin.org/post")
|
||||||
/// .set("Content-Type", "text/plain")
|
/// .send(read)?;
|
||||||
/// .send(read);
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn send(self, reader: impl Read) -> Result<Response> {
|
pub fn send(self, reader: impl Read) -> Result<Response> {
|
||||||
self.do_call(Payload::Reader(Box::new(reader)))
|
self.do_call(Payload::Reader(Box::new(reader)))
|
||||||
@@ -208,16 +223,14 @@ impl Request {
|
|||||||
/// Set a header field.
|
/// Set a header field.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let r = ureq::get("/my_page")
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// .set("X-API-Key", "foobar")
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::get("http://httpbin.org/bytes/1000")
|
||||||
/// .set("Accept", "text/plain")
|
/// .set("Accept", "text/plain")
|
||||||
/// .call();
|
/// .set("Range", "bytes=500-999")
|
||||||
///
|
/// .call()?;
|
||||||
/// if r.is_ok() {
|
/// # Ok(())
|
||||||
/// println!("yay got {}", r.unwrap().into_string().unwrap());
|
/// # }
|
||||||
/// } else {
|
|
||||||
/// println!("Oh no error!");
|
|
||||||
/// }
|
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set(mut self, header: &str, value: &str) -> Self {
|
pub fn set(mut self, header: &str, value: &str) -> Self {
|
||||||
header::add_header(&mut self.headers, Header::new(header, value));
|
header::add_header(&mut self.headers, Header::new(header, value));
|
||||||
@@ -282,12 +295,14 @@ impl Request {
|
|||||||
/// For example, to set `?format=json&dest=/login`
|
/// For example, to set `?format=json&dest=/login`
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let r = ureq::get("/my_page")
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::get("http://httpbin.org/response-headers")
|
||||||
/// .query("format", "json")
|
/// .query("format", "json")
|
||||||
/// .query("dest", "/login")
|
/// .query("dest", "/login")
|
||||||
/// .call();
|
/// .call()?;
|
||||||
///
|
/// # Ok(())
|
||||||
/// println!("{:?}", r);
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn query(mut self, param: &str, value: &str) -> Self {
|
pub fn query(mut self, param: &str, value: &str) -> Self {
|
||||||
self.query_params
|
self.query_params
|
||||||
@@ -302,10 +317,11 @@ impl Request {
|
|||||||
/// Example:
|
/// Example:
|
||||||
/// ```
|
/// ```
|
||||||
/// # fn main() -> Result<(), ureq::Error> {
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let result = ureq::get("http://httpbin.org/status/500")
|
/// # ureq::is_test(true);
|
||||||
|
/// let response = ureq::get("http://httpbin.org/status/500")
|
||||||
/// .error_for_status(false)
|
/// .error_for_status(false)
|
||||||
/// .call();
|
/// .call()?;
|
||||||
/// assert!(result.is_ok());
|
/// assert_eq!(response.status(), 500);
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
|||||||
@@ -30,13 +30,17 @@ pub const DEFAULT_CHARACTER_SET: &str = "utf-8";
|
|||||||
/// [`into_string()`](#method.into_string) consumes the response.
|
/// [`into_string()`](#method.into_string) consumes the response.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let response = ureq::get("http://example.com/").call().unwrap();
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let response = ureq::get("http://example.com/").call()?;
|
||||||
///
|
///
|
||||||
/// // socket is still open and the response body has not been read.
|
/// // socket is still open and the response body has not been read.
|
||||||
///
|
///
|
||||||
/// let text = response.into_string().unwrap();
|
/// let text = response.into_string()?;
|
||||||
///
|
///
|
||||||
/// // response is consumed, and body has been read.
|
/// // response is consumed, and body has been read.
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
url: Option<String>,
|
url: Option<String>,
|
||||||
@@ -74,9 +78,13 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let resp = ureq::Response::new(401, "Authorization Required", "Please log in").unwrap();
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
|
/// # ureq::is_test(true);
|
||||||
|
/// let resp = ureq::Response::new(401, "Authorization Required", "Please log in")?;
|
||||||
///
|
///
|
||||||
/// assert_eq!(resp.status(), 401);
|
/// assert_eq!(resp.status(), 401);
|
||||||
|
/// # Ok(())
|
||||||
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(status: u16, status_text: &str, body: &str) -> Result<Response, Error> {
|
pub fn new(status: u16, status_text: &str, body: &str) -> Result<Response, Error> {
|
||||||
let r = format!("HTTP/1.1 {} {}\r\n\r\n{}\n", status, status_text, body);
|
let r = format!("HTTP/1.1 {} {}\r\n\r\n{}\n", status, status_text, body);
|
||||||
@@ -170,10 +178,12 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[cfg(feature = "tls")] {
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let resp = ureq::get("https://www.google.com/").call().unwrap();
|
/// # ureq::is_test(true);
|
||||||
/// assert_eq!("text/html; charset=ISO-8859-1", resp.header("content-type").unwrap());
|
/// let resp = ureq::get("http://example.com/").call()?;
|
||||||
|
/// assert!(matches!(resp.header("content-type"), Some("text/html; charset=ISO-8859-1")));
|
||||||
/// assert_eq!("text/html", resp.content_type());
|
/// assert_eq!("text/html", resp.content_type());
|
||||||
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn content_type(&self) -> &str {
|
pub fn content_type(&self) -> &str {
|
||||||
@@ -192,10 +202,12 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[cfg(feature = "tls")] {
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let resp = ureq::get("https://www.google.com/").call().unwrap();
|
/// # ureq::is_test(true);
|
||||||
/// assert_eq!("text/html; charset=ISO-8859-1", resp.header("content-type").unwrap());
|
/// let resp = ureq::get("http://example.com/").call()?;
|
||||||
|
/// assert!(matches!(resp.header("content-type"), Some("text/html; charset=ISO-8859-1")));
|
||||||
/// assert_eq!("ISO-8859-1", resp.charset());
|
/// assert_eq!("ISO-8859-1", resp.charset());
|
||||||
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn charset(&self) -> &str {
|
pub fn charset(&self) -> &str {
|
||||||
@@ -213,22 +225,22 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[cfg(feature = "tls")] {
|
|
||||||
/// use std::io::Read;
|
/// use std::io::Read;
|
||||||
///
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let resp =
|
/// # ureq::is_test(true);
|
||||||
/// ureq::get("https://ureq.s3.eu-central-1.amazonaws.com/hello_world.json")
|
/// let resp = ureq::get("http://httpbin.org/bytes/100")
|
||||||
/// .call().unwrap();
|
/// .call()?;
|
||||||
///
|
///
|
||||||
/// assert!(resp.has("Content-Length"));
|
/// assert!(resp.has("Content-Length"));
|
||||||
/// let len = resp.header("Content-Length")
|
/// let len = resp.header("Content-Length")
|
||||||
/// .and_then(|s| s.parse::<usize>().ok()).unwrap();
|
/// .and_then(|s| s.parse::<usize>().ok()).unwrap();
|
||||||
///
|
///
|
||||||
/// let mut reader = resp.into_reader();
|
/// let mut bytes: Vec<u8> = Vec::with_capacity(len);
|
||||||
/// let mut bytes = vec![];
|
/// resp.into_reader()
|
||||||
/// reader.read_to_end(&mut bytes);
|
/// .read_to_end(&mut bytes)?;
|
||||||
///
|
///
|
||||||
/// assert_eq!(bytes.len(), len);
|
/// assert_eq!(bytes.len(), len);
|
||||||
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn into_reader(self) -> impl Read + Send {
|
pub fn into_reader(self) -> impl Read + Send {
|
||||||
@@ -293,14 +305,14 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[cfg(feature = "tls")] {
|
/// # fn main() -> Result<(), ureq::Error> {
|
||||||
/// let resp =
|
/// # ureq::is_test(true);
|
||||||
/// ureq::get("https://ureq.s3.eu-central-1.amazonaws.com/hello_world.json")
|
/// let text = ureq::get("http://httpbin.org/get/success")
|
||||||
/// .call().unwrap();
|
/// .call()?
|
||||||
|
/// .into_string()?;
|
||||||
///
|
///
|
||||||
/// let text = resp.into_string().unwrap();
|
/// assert!(text.contains("success"));
|
||||||
///
|
/// # Ok(())
|
||||||
/// assert!(text.contains("hello"));
|
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
@@ -376,7 +388,7 @@ impl Response {
|
|||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use serde::Deserialize;
|
/// use serde::Deserialize;
|
||||||
///
|
///
|
||||||
/// #[derive(Deserialize)]
|
/// #[derive(Deserialize)]
|
||||||
/// struct Hello {
|
/// struct Hello {
|
||||||
|
|||||||
@@ -14,15 +14,28 @@ use crate::{Agent, AgentBuilder};
|
|||||||
// that all hostnames resolve to a TestServer on localhost.
|
// that all hostnames resolve to a TestServer on localhost.
|
||||||
pub(crate) fn test_agent() -> Agent {
|
pub(crate) fn test_agent() -> Agent {
|
||||||
let testserver = TestServer::new(|mut stream: TcpStream| -> io::Result<()> {
|
let testserver = TestServer::new(|mut stream: TcpStream| -> io::Result<()> {
|
||||||
read_headers(&stream);
|
let headers = read_headers(&stream);
|
||||||
stream.write_all(b"HTTP/1.1 200 OK\r\n")?;
|
if headers.path() == "/status/500" {
|
||||||
stream.write_all(b"Transfer-Encoding: chunked\r\n")?;
|
stream.write_all(b"HTTP/1.1 500 Server Internal Error\r\n\r\n")?;
|
||||||
stream.write_all(b"Content-Type: text/html; charset=ISO-8859-1\r\n")?;
|
} else if headers.path() == "/bytes/100" {
|
||||||
stream.write_all(b"\r\n")?;
|
stream.write_all(b"HTTP/1.1 200 OK\r\n")?;
|
||||||
stream.write_all(b"7\r\n")?;
|
stream.write_all(b"Content-Length: 100\r\n")?;
|
||||||
stream.write_all(b"success\r\n")?;
|
stream.write_all(b"\r\n")?;
|
||||||
stream.write_all(b"0\r\n")?;
|
stream.write_all(&[0; 100])?;
|
||||||
stream.write_all(b"\r\n")?;
|
} else if headers.path() == "/redirect/3" {
|
||||||
|
stream.write_all(b"HTTP/1.1 302 Found\r\n")?;
|
||||||
|
stream.write_all(b"Location: /redirect/3\r\n")?;
|
||||||
|
stream.write_all(b"\r\n")?;
|
||||||
|
} else {
|
||||||
|
stream.write_all(b"HTTP/1.1 200 OK\r\n")?;
|
||||||
|
stream.write_all(b"Transfer-Encoding: chunked\r\n")?;
|
||||||
|
stream.write_all(b"Content-Type: text/html; charset=ISO-8859-1\r\n")?;
|
||||||
|
stream.write_all(b"\r\n")?;
|
||||||
|
stream.write_all(b"7\r\n")?;
|
||||||
|
stream.write_all(b"success\r\n")?;
|
||||||
|
stream.write_all(b"0\r\n")?;
|
||||||
|
stream.write_all(b"\r\n")?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
// Slightly tricky thing here: we want to make sure the TestServer lives
|
// Slightly tricky thing here: we want to make sure the TestServer lives
|
||||||
@@ -53,7 +66,6 @@ pub struct TestHeaders(Vec<String>);
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl TestHeaders {
|
impl TestHeaders {
|
||||||
// Return the path for a request, e.g. /foo from "GET /foo HTTP/1.1"
|
// Return the path for a request, e.g. /foo from "GET /foo HTTP/1.1"
|
||||||
#[cfg(feature = "cookies")]
|
|
||||||
pub fn path(&self) -> &str {
|
pub fn path(&self) -> &str {
|
||||||
if self.0.len() == 0 {
|
if self.0.len() == 0 {
|
||||||
""
|
""
|
||||||
|
|||||||
Reference in New Issue
Block a user