edition 2018, clippy, fmt
This commit is contained in:
@@ -8,6 +8,7 @@ repository = "https://github.com/algesten/ureq"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["web", "request", "http", "rest", "client"]
|
keywords = ["web", "request", "http", "rest", "client"]
|
||||||
categories = ["web-programming::http-client"]
|
categories = ["web-programming::http-client"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["tls"]
|
default = ["tls"]
|
||||||
|
|||||||
56
src/agent.rs
56
src/agent.rs
@@ -1,10 +1,10 @@
|
|||||||
|
use crate::error::Error;
|
||||||
|
use crate::pool::ConnectionPool;
|
||||||
|
use crate::response::{self, Response};
|
||||||
use cookie::{Cookie, CookieJar};
|
use cookie::{Cookie, CookieJar};
|
||||||
use error::Error;
|
|
||||||
use pool::ConnectionPool;
|
|
||||||
use response::{self, Response};
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use header::{add_header, get_all_headers, get_header, has_header, Header};
|
use crate::header::{add_header, get_all_headers, get_header, has_header, Header};
|
||||||
|
|
||||||
// to get to share private fields
|
// to get to share private fields
|
||||||
include!("request.rs");
|
include!("request.rs");
|
||||||
@@ -112,12 +112,8 @@ impl Agent {
|
|||||||
/// println!("Oh no error!");
|
/// println!("Oh no error!");
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn set(&mut self, header: &str, value: &str) -> &mut Agent
|
pub fn set(&mut self, header: &str, value: &str) -> &mut Agent {
|
||||||
{
|
add_header(&mut self.headers, Header::new(header, value));
|
||||||
add_header(
|
|
||||||
&mut self.headers,
|
|
||||||
Header::new(header, value),
|
|
||||||
);
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,8 +129,7 @@ impl Agent {
|
|||||||
/// .call();
|
/// .call();
|
||||||
/// println!("{:?}", r);
|
/// println!("{:?}", r);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn auth(&mut self, user: &str, pass: &str) -> &mut Agent
|
pub fn auth(&mut self, user: &str, pass: &str) -> &mut Agent {
|
||||||
{
|
|
||||||
let pass = basic_auth(user, pass);
|
let pass = basic_auth(user, pass);
|
||||||
self.auth_kind("Basic", &pass)
|
self.auth_kind("Basic", &pass)
|
||||||
}
|
}
|
||||||
@@ -152,8 +147,7 @@ impl Agent {
|
|||||||
/// .get("/my_page")
|
/// .get("/my_page")
|
||||||
/// .call();
|
/// .call();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn auth_kind(&mut self, kind: &str, pass: &str) -> &mut Agent
|
pub fn auth_kind(&mut self, kind: &str, pass: &str) -> &mut Agent {
|
||||||
{
|
|
||||||
let value = format!("{} {}", kind, pass);
|
let value = format!("{} {}", kind, pass);
|
||||||
self.set("Authorization", &value);
|
self.set("Authorization", &value);
|
||||||
self
|
self
|
||||||
@@ -169,8 +163,7 @@ impl Agent {
|
|||||||
/// .call();
|
/// .call();
|
||||||
/// println!("{:?}", r);
|
/// println!("{:?}", r);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn request(&self, method: &str, path: &str) -> Request
|
pub fn request(&self, method: &str, path: &str) -> Request {
|
||||||
{
|
|
||||||
Request::new(&self, method.into(), path.into())
|
Request::new(&self, method.into(), path.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +183,7 @@ impl Agent {
|
|||||||
state
|
state
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|state| state.jar.get(name))
|
.and_then(|state| state.jar.get(name))
|
||||||
.map(|c| c.clone())
|
.cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a cookie in this agent.
|
/// Set a cookie in this agent.
|
||||||
@@ -212,56 +205,47 @@ impl Agent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Make a GET request from this agent.
|
/// Make a GET request from this agent.
|
||||||
pub fn get(&self, path: &str) -> Request
|
pub fn get(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("GET", path)
|
self.request("GET", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a HEAD request from this agent.
|
/// Make a HEAD request from this agent.
|
||||||
pub fn head(&self, path: &str) -> Request
|
pub fn head(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("HEAD", path)
|
self.request("HEAD", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a POST request from this agent.
|
/// Make a POST request from this agent.
|
||||||
pub fn post(&self, path: &str) -> Request
|
pub fn post(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("POST", path)
|
self.request("POST", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a PUT request from this agent.
|
/// Make a PUT request from this agent.
|
||||||
pub fn put(&self, path: &str) -> Request
|
pub fn put(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("PUT", path)
|
self.request("PUT", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a DELETE request from this agent.
|
/// Make a DELETE request from this agent.
|
||||||
pub fn delete(&self, path: &str) -> Request
|
pub fn delete(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("DELETE", path)
|
self.request("DELETE", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a TRACE request from this agent.
|
/// Make a TRACE request from this agent.
|
||||||
pub fn trace(&self, path: &str) -> Request
|
pub fn trace(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("TRACE", path)
|
self.request("TRACE", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a OPTIONS request from this agent.
|
/// Make a OPTIONS request from this agent.
|
||||||
pub fn options(&self, path: &str) -> Request
|
pub fn options(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("OPTIONS", path)
|
self.request("OPTIONS", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a CONNECT request from this agent.
|
/// Make a CONNECT request from this agent.
|
||||||
pub fn connect(&self, path: &str) -> Request
|
pub fn connect(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("CONNECT", path)
|
self.request("CONNECT", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a PATCH request from this agent.
|
/// Make a PATCH request from this agent.
|
||||||
pub fn patch(&self, path: &str) -> Request
|
pub fn patch(&self, path: &str) -> Request {
|
||||||
{
|
|
||||||
self.request("PATCH", path)
|
self.request("PATCH", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +256,7 @@ impl Agent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn basic_auth(user: &str, pass: &str) -> String {
|
fn basic_auth(user: &str, pass: &str) -> String {
|
||||||
let safe = match user.find(":") {
|
let safe = match user.find(':') {
|
||||||
Some(idx) => &user[..idx],
|
Some(idx) => &user[..idx],
|
||||||
None => user,
|
None => user,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
use crate::stream::Stream;
|
||||||
use chunked_transfer;
|
use chunked_transfer;
|
||||||
use std::io::{copy, empty, Cursor, Read, Result as IoResult};
|
use std::io::{copy, empty, Cursor, Read, Result as IoResult};
|
||||||
use stream::Stream;
|
|
||||||
|
|
||||||
#[cfg(feature = "charset")]
|
#[cfg(feature = "charset")]
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
#[cfg(feature = "charset")]
|
#[cfg(feature = "charset")]
|
||||||
use encoding::EncoderTrap;
|
use encoding::EncoderTrap;
|
||||||
#[cfg(feature = "charset")]
|
#[cfg(feature = "charset")]
|
||||||
use response::DEFAULT_CHARACTER_SET;
|
use crate::response::DEFAULT_CHARACTER_SET;
|
||||||
|
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
use super::SerdeValue;
|
use super::SerdeValue;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use crate::error::Error;
|
||||||
use ascii::{AsAsciiStr, AsciiString};
|
use ascii::{AsAsciiStr, AsciiString};
|
||||||
use error::Error;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -60,11 +60,11 @@ impl Header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_header<'a, 'b>(headers: &'b Vec<Header>, name: &'a str) -> Option<&'b str> {
|
pub fn get_header<'a, 'b>(headers: &'b [Header], name: &'a str) -> Option<&'b str> {
|
||||||
headers.iter().find(|h| h.is_name(name)).map(|h| h.value())
|
headers.iter().find(|h| h.is_name(name)).map(|h| h.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_all_headers<'a, 'b>(headers: &'b Vec<Header>, name: &'a str) -> Vec<&'b str> {
|
pub fn get_all_headers<'a, 'b>(headers: &'b [Header], name: &'a str) -> Vec<&'b str> {
|
||||||
headers
|
headers
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|h| h.is_name(name))
|
.filter(|h| h.is_name(name))
|
||||||
@@ -72,7 +72,7 @@ pub fn get_all_headers<'a, 'b>(headers: &'b Vec<Header>, name: &'a str) -> Vec<&
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_header(headers: &Vec<Header>, name: &str) -> bool {
|
pub fn has_header(headers: &[Header], name: &str) -> bool {
|
||||||
get_header(headers, name).is_some()
|
get_header(headers, name).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ impl FromStr for Header {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
//
|
//
|
||||||
let line = AsciiString::from_str(s).map_err(|_| Error::BadHeader)?;
|
let line = AsciiString::from_str(s).map_err(|_| Error::BadHeader)?;
|
||||||
let index = s.find(":").ok_or_else(|| Error::BadHeader)?;
|
let index = s.find(':').ok_or_else(|| Error::BadHeader)?;
|
||||||
|
|
||||||
// no value?
|
// no value?
|
||||||
if index >= s.len() {
|
if index >= s.len() {
|
||||||
|
|||||||
39
src/lib.rs
39
src/lib.rs
@@ -1,3 +1,4 @@
|
|||||||
|
#![warn(clippy::all)]
|
||||||
//! ureq is a minimal request library.
|
//! ureq is a minimal request library.
|
||||||
//!
|
//!
|
||||||
//! The goals of this library are:
|
//! The goals of this library are:
|
||||||
@@ -120,10 +121,10 @@ mod serde_macros;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
pub use agent::{Agent, Request};
|
pub use crate::agent::{Agent, Request};
|
||||||
pub use error::Error;
|
pub use crate::error::Error;
|
||||||
pub use header::Header;
|
pub use crate::header::Header;
|
||||||
pub use response::Response;
|
pub use crate::response::Response;
|
||||||
|
|
||||||
// re-export
|
// re-export
|
||||||
pub use cookie::Cookie;
|
pub use cookie::Cookie;
|
||||||
@@ -140,62 +141,52 @@ pub fn agent() -> Agent {
|
|||||||
/// ```
|
/// ```
|
||||||
/// ureq::request("GET", "https://www.google.com").call();
|
/// ureq::request("GET", "https://www.google.com").call();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn request(method: &str, path: &str) -> Request
|
pub fn request(method: &str, path: &str) -> Request {
|
||||||
{
|
|
||||||
Agent::new().request(method, path)
|
Agent::new().request(method, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a GET request.
|
/// Make a GET request.
|
||||||
pub fn get(path: &str) -> Request
|
pub fn get(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("GET", path)
|
request("GET", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a HEAD request.
|
/// Make a HEAD request.
|
||||||
pub fn head(path: &str) -> Request
|
pub fn head(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("HEAD", path)
|
request("HEAD", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a POST request.
|
/// Make a POST request.
|
||||||
pub fn post(path: &str) -> Request
|
pub fn post(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("POST", path)
|
request("POST", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a PUT request.
|
/// Make a PUT request.
|
||||||
pub fn put(path: &str) -> Request
|
pub fn put(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("PUT", path)
|
request("PUT", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a DELETE request.
|
/// Make a DELETE request.
|
||||||
pub fn delete(path: &str) -> Request
|
pub fn delete(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("DELETE", path)
|
request("DELETE", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a TRACE request.
|
/// Make a TRACE request.
|
||||||
pub fn trace(path: &str) -> Request
|
pub fn trace(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("TRACE", path)
|
request("TRACE", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make an OPTIONS request.
|
/// Make an OPTIONS request.
|
||||||
pub fn options(path: &str) -> Request
|
pub fn options(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("OPTIONS", path)
|
request("OPTIONS", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make an CONNECT request.
|
/// Make an CONNECT request.
|
||||||
pub fn connect(path: &str) -> Request
|
pub fn connect(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("CONNECT", path)
|
request("CONNECT", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make an PATCH request.
|
/// Make an PATCH request.
|
||||||
pub fn patch(path: &str) -> Request
|
pub fn patch(path: &str) -> Request {
|
||||||
{
|
|
||||||
request("PATCH", path)
|
request("PATCH", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
src/pool.rs
10
src/pool.rs
@@ -1,10 +1,10 @@
|
|||||||
use agent::Unit;
|
use crate::agent::Unit;
|
||||||
|
use crate::stream::Stream;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Read, Result as IoResult};
|
use std::io::{Read, Result as IoResult};
|
||||||
use stream::Stream;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub const DEFAULT_HOST: &'static str = "localhost";
|
pub const DEFAULT_HOST: &str = "localhost";
|
||||||
|
|
||||||
/// Holder of recycled connections.
|
/// Holder of recycled connections.
|
||||||
///
|
///
|
||||||
@@ -106,7 +106,7 @@ impl<R: Read + Sized> PoolReturnRead<R> {
|
|||||||
|
|
||||||
fn do_read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
fn do_read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||||
match self.reader.as_mut() {
|
match self.reader.as_mut() {
|
||||||
None => return Ok(0),
|
None => Ok(0),
|
||||||
Some(reader) => reader.read(buf),
|
Some(reader) => reader.read(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,4 +128,4 @@ impl<R: Read + Sized> Drop for PoolReturnRead<R> {
|
|||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.return_connection();
|
self.return_connection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use agent::Unit;
|
use crate::agent::Unit;
|
||||||
|
use crate::header::Header;
|
||||||
|
use crate::pool::PoolReturnRead;
|
||||||
|
use crate::stream::Stream;
|
||||||
use ascii::AsciiString;
|
use ascii::AsciiString;
|
||||||
use chunked_transfer::Decoder as ChunkDecoder;
|
use chunked_transfer::Decoder as ChunkDecoder;
|
||||||
use header::Header;
|
|
||||||
use pool::PoolReturnRead;
|
|
||||||
use std::io::{Cursor, Error as IoError, ErrorKind, Read, Result as IoResult};
|
use std::io::{Cursor, Error as IoError, ErrorKind, Read, Result as IoResult};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use stream::Stream;
|
|
||||||
|
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
use serde_json;
|
use serde_json;
|
||||||
@@ -15,10 +15,10 @@ use encoding::label::encoding_from_whatwg_label;
|
|||||||
#[cfg(feature = "charset")]
|
#[cfg(feature = "charset")]
|
||||||
use encoding::DecoderTrap;
|
use encoding::DecoderTrap;
|
||||||
|
|
||||||
use error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
pub const DEFAULT_CONTENT_TYPE: &'static str = "text/plain";
|
pub const DEFAULT_CONTENT_TYPE: &str = "text/plain";
|
||||||
pub const DEFAULT_CHARACTER_SET: &'static str = "utf-8";
|
pub const DEFAULT_CHARACTER_SET: &str = "utf-8";
|
||||||
|
|
||||||
/// Response instances are created as results of firing off requests.
|
/// Response instances are created as results of firing off requests.
|
||||||
///
|
///
|
||||||
@@ -200,7 +200,7 @@ impl Response {
|
|||||||
self.header("content-type")
|
self.header("content-type")
|
||||||
.map(|header| {
|
.map(|header| {
|
||||||
header
|
header
|
||||||
.find(";")
|
.find(';')
|
||||||
.map(|index| &header[0..index])
|
.map(|index| &header[0..index])
|
||||||
.unwrap_or(header)
|
.unwrap_or(header)
|
||||||
})
|
})
|
||||||
@@ -258,8 +258,9 @@ impl Response {
|
|||||||
|
|
||||||
let is_head = (&self.unit).as_ref().map(|u| u.is_head).unwrap_or(false);
|
let is_head = (&self.unit).as_ref().map(|u| u.is_head).unwrap_or(false);
|
||||||
|
|
||||||
let is_chunked = self.header("transfer-encoding")
|
let is_chunked = self
|
||||||
.map(|enc| enc.len() > 0) // whatever it says, do chunked
|
.header("transfer-encoding")
|
||||||
|
.map(|enc| !enc.is_empty()) // whatever it says, do chunked
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
let use_chunked = !is_http10 && !is_head && is_chunked;
|
let use_chunked = !is_http10 && !is_head && is_chunked;
|
||||||
@@ -276,7 +277,10 @@ impl Response {
|
|||||||
|
|
||||||
let stream = Box::new(self.stream.expect("No reader in response?!"));
|
let stream = Box::new(self.stream.expect("No reader in response?!"));
|
||||||
let stream_ptr = Box::into_raw(stream);
|
let stream_ptr = Box::into_raw(stream);
|
||||||
let mut yolo = YoloRead { stream: stream_ptr, dealloc: false };
|
let mut yolo = YoloRead {
|
||||||
|
stream: stream_ptr,
|
||||||
|
dealloc: false,
|
||||||
|
};
|
||||||
let unit = self.unit;
|
let unit = self.unit;
|
||||||
|
|
||||||
match (use_chunked, limit_bytes) {
|
match (use_chunked, limit_bytes) {
|
||||||
@@ -293,7 +297,7 @@ impl Response {
|
|||||||
(false, None) => {
|
(false, None) => {
|
||||||
yolo.dealloc = true; // dealloc when read drops.
|
yolo.dealloc = true; // dealloc when read drops.
|
||||||
Box::new(yolo)
|
Box::new(yolo)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +402,7 @@ impl Response {
|
|||||||
let mut headers: Vec<Header> = Vec::new();
|
let mut headers: Vec<Header> = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let line = read_next_line(&mut reader).map_err(|_| Error::BadHeader)?;
|
let line = read_next_line(&mut reader).map_err(|_| Error::BadHeader)?;
|
||||||
if line.len() == 0 {
|
if line.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if let Ok(header) = line.as_str().parse::<Header>() {
|
if let Ok(header) = line.as_str().parse::<Header>() {
|
||||||
@@ -444,7 +448,7 @@ fn parse_status_line(line: &str) -> Result<((usize, usize), u16), Error> {
|
|||||||
let status = status.parse::<u16>().map_err(|_| Error::BadStatus)?;
|
let status = status.parse::<u16>().map_err(|_| Error::BadStatus)?;
|
||||||
|
|
||||||
let status_text = split.next().ok_or_else(|| Error::BadStatus)?;
|
let status_text = split.next().ok_or_else(|| Error::BadStatus)?;
|
||||||
if status_text.len() == 0 {
|
if status_text.is_empty() {
|
||||||
return Err(Error::BadStatus);
|
return Err(Error::BadStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +507,7 @@ fn read_next_line<R: Read>(reader: &mut R) -> IoResult<AsciiString> {
|
|||||||
let byte = reader.bytes().next();
|
let byte = reader.bytes().next();
|
||||||
|
|
||||||
let byte = match byte {
|
let byte = match byte {
|
||||||
Some(b) => try!(b),
|
Some(b) => r#try!(b),
|
||||||
None => return Err(IoError::new(ErrorKind::ConnectionAborted, "Unexpected EOF")),
|
None => return Err(IoError::new(ErrorKind::ConnectionAborted, "Unexpected EOF")),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -577,7 +581,7 @@ impl LimitedRead {
|
|||||||
impl Read for LimitedRead {
|
impl Read for LimitedRead {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||||
let left = self.limit - self.position;
|
let left = self.limit - self.position;
|
||||||
if left <= 0 {
|
if left == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
let from = if left < buf.len() {
|
let from = if left < buf.len() {
|
||||||
@@ -603,9 +607,9 @@ impl Read for LimitedRead {
|
|||||||
pub fn charset_from_content_type(header: Option<&str>) -> &str {
|
pub fn charset_from_content_type(header: Option<&str>) -> &str {
|
||||||
header
|
header
|
||||||
.and_then(|header| {
|
.and_then(|header| {
|
||||||
header.find(";").and_then(|semi| {
|
header.find(';').and_then(|semi| {
|
||||||
(&header[semi + 1..])
|
(&header[semi + 1..])
|
||||||
.find("=")
|
.find('=')
|
||||||
.map(|equal| (&header[semi + equal + 2..]).trim())
|
.map(|equal| (&header[semi + equal + 2..]).trim())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -696,7 +700,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_borked_header() {
|
fn parse_borked_header() {
|
||||||
let s = format!("HTTP/1.1 BORKED\r\n");
|
let s = "HTTP/1.1 BORKED\r\n".to_string();
|
||||||
let resp: Response = s.parse::<Response>().unwrap_err().into();
|
let resp: Response = s.parse::<Response>().unwrap_err().into();
|
||||||
assert_eq!(resp.http_version(), "HTTP/1.1");
|
assert_eq!(resp.http_version(), "HTTP/1.1");
|
||||||
assert_eq!(resp.status(), 500);
|
assert_eq!(resp.status(), 500);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use agent::Unit;
|
use crate::agent::Unit;
|
||||||
use error::Error;
|
use crate::error::Error;
|
||||||
use std::io::{Cursor, Read, Result as IoResult, Write};
|
use std::io::{Cursor, Read, Result as IoResult, Write};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
@@ -95,7 +95,7 @@ pub fn connect_http(unit: &Unit) -> Result<Stream, Error> {
|
|||||||
let hostname = unit.url.host_str().unwrap();
|
let hostname = unit.url.host_str().unwrap();
|
||||||
let port = unit.url.port().unwrap_or(80);
|
let port = unit.url.port().unwrap_or(80);
|
||||||
|
|
||||||
connect_host(unit, hostname, port).map(|tcp| Stream::Http(tcp))
|
connect_host(unit, hostname, port).map(Stream::Http)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
@@ -119,7 +119,7 @@ pub fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<TcpStream,
|
|||||||
.map_err(|e| Error::DnsFailed(format!("{}", e)))?
|
.map_err(|e| Error::DnsFailed(format!("{}", e)))?
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if ips.len() == 0 {
|
if ips.is_empty() {
|
||||||
return Err(Error::DnsFailed(format!("No ip address for {}", hostname)));
|
return Err(Error::DnsFailed(format!("No ip address for {}", hostname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +133,8 @@ pub fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<TcpStream,
|
|||||||
&sock_addr,
|
&sock_addr,
|
||||||
Duration::from_millis(unit.timeout_connect as u64),
|
Duration::from_millis(unit.timeout_connect as u64),
|
||||||
),
|
),
|
||||||
}.map_err(|err| Error::ConnectionFailed(format!("{}", err)))?;
|
}
|
||||||
|
.map_err(|err| Error::ConnectionFailed(format!("{}", err)))?;
|
||||||
|
|
||||||
// rust's absurd api returns Err if we set 0.
|
// rust's absurd api returns Err if we set 0.
|
||||||
if unit.timeout_read > 0 {
|
if unit.timeout_read > 0 {
|
||||||
@@ -152,7 +153,7 @@ pub fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<TcpStream,
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn connect_test(unit: &Unit) -> Result<Stream, Error> {
|
pub fn connect_test(unit: &Unit) -> Result<Stream, Error> {
|
||||||
use test;
|
use crate::test;
|
||||||
test::resolve_handler(unit)
|
test::resolve_handler(unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use test;
|
use crate::test;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use test;
|
use crate::test;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use crate::test;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use test;
|
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use test;
|
use crate::test;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use agent::Unit;
|
use crate::agent::Unit;
|
||||||
use error::Error;
|
use crate::error::Error;
|
||||||
|
use crate::stream::Stream;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use stream::Stream;
|
|
||||||
|
|
||||||
mod agent_test;
|
mod agent_test;
|
||||||
mod auth;
|
mod auth;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use test;
|
use crate::test;
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ fn agent_pool() {
|
|||||||
let state = lock.as_mut().unwrap();
|
let state = lock.as_mut().unwrap();
|
||||||
let pool = state.pool();
|
let pool = state.pool();
|
||||||
assert_eq!(pool.len(), 1);
|
assert_eq!(pool.len(), 1);
|
||||||
let foo = format!("{:?}", pool.get("s3.amazonaws.com", 443));
|
let f = format!("{:?}", pool.get("s3.amazonaws.com", 443));
|
||||||
assert_eq!(foo, "Some(Stream[https])"); // not a great way of testing.
|
assert_eq!(f, "Some(Stream[https])"); // not a great way of testing.
|
||||||
}
|
}
|
||||||
|
|
||||||
// req 2 should be done with a reused connection
|
// req 2 should be done with a reused connection
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
use crate::test;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use test;
|
|
||||||
|
|
||||||
use super::super::*;
|
use super::super::*;
|
||||||
|
|
||||||
|
|||||||
16
src/unit.rs
16
src/unit.rs
@@ -1,11 +1,11 @@
|
|||||||
use base64;
|
use base64;
|
||||||
use body::{send_body, Payload, SizedReader};
|
use crate::body::{send_body, Payload, SizedReader};
|
||||||
use std::io::{Result as IoResult, Write};
|
use std::io::{Result as IoResult, Write};
|
||||||
use stream::{connect_http, connect_https, connect_test, Stream};
|
use crate::stream::{connect_http, connect_https, connect_test, Stream};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
//
|
//
|
||||||
|
|
||||||
use pool::DEFAULT_HOST;
|
use crate::pool::DEFAULT_HOST;
|
||||||
|
|
||||||
/// It's a "unit of work". Maybe a bad name for it?
|
/// It's a "unit of work". Maybe a bad name for it?
|
||||||
///
|
///
|
||||||
@@ -31,7 +31,7 @@ impl Unit {
|
|||||||
|
|
||||||
let is_chunked = req.header("transfer-encoding")
|
let is_chunked = req.header("transfer-encoding")
|
||||||
// if the user has set an encoding header, obey that.
|
// if the user has set an encoding header, obey that.
|
||||||
.map(|enc| enc.len() > 0)
|
.map(|enc| !enc.is_empty())
|
||||||
// otherwise, no chunking.
|
// otherwise, no chunking.
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ impl Unit {
|
|||||||
let query_string = combine_query(&url, &req.query, mix_queries);
|
let query_string = combine_query(&url, &req.query, mix_queries);
|
||||||
|
|
||||||
let cookie_headers: Vec<_> = {
|
let cookie_headers: Vec<_> = {
|
||||||
let mut state = req.agent.lock().unwrap();
|
let state = req.agent.lock().unwrap();
|
||||||
match state.as_ref().map(|state| &state.jar) {
|
match state.as_ref().map(|state| &state.jar) {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(jar) => match_cookies(jar, &hostname, url.path(), is_secure),
|
Some(jar) => match_cookies(jar, &hostname, url.path(), is_secure),
|
||||||
@@ -210,7 +210,7 @@ fn match_cookies<'a>(jar: &'a CookieJar, domain: &str, path: &str, is_secure: bo
|
|||||||
|
|
||||||
/// Combine the query of the url and the query options set on the request object.
|
/// Combine the query of the url and the query options set on the request object.
|
||||||
fn combine_query(url: &Url, query: &QString, mix_queries: bool) -> String {
|
fn combine_query(url: &Url, query: &QString, mix_queries: bool) -> String {
|
||||||
match (url.query(), query.len() > 0 && mix_queries) {
|
match (url.query(), !query.is_empty() && mix_queries) {
|
||||||
(Some(urlq), true) => format!("?{}&{}", urlq, query),
|
(Some(urlq), true) => format!("?{}&{}", urlq, query),
|
||||||
(Some(urlq), false) => format!("?{}", urlq),
|
(Some(urlq), false) => format!("?{}", urlq),
|
||||||
(None, true) => format!("?{}", query),
|
(None, true) => format!("?{}", query),
|
||||||
@@ -273,7 +273,7 @@ fn send_prelude(unit: &Unit, method: &str, stream: &mut Stream) -> IoResult<()>
|
|||||||
write!(prelude, "\r\n")?;
|
write!(prelude, "\r\n")?;
|
||||||
|
|
||||||
// write all to the wire
|
// write all to the wire
|
||||||
stream.write_all(&mut prelude[..])?;
|
stream.write_all(&prelude[..])?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@ fn save_cookies(unit: &Unit, resp: &Response) {
|
|||||||
};
|
};
|
||||||
match Cookie::parse_encoded(&to_parse[..]) {
|
match Cookie::parse_encoded(&to_parse[..]) {
|
||||||
Err(_) => (), // ignore unparseable cookies
|
Err(_) => (), // ignore unparseable cookies
|
||||||
Ok(mut cookie) => {
|
Ok(cookie) => {
|
||||||
let cookie = cookie.into_owned();
|
let cookie = cookie.into_owned();
|
||||||
add_jar.add(cookie)
|
add_jar.add(cookie)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user