Skip to content
Permalink
Browse files

Add ability to set preferred IP version

  • Loading branch information
dnlserrano committed Nov 4, 2019
1 parent 594340a commit 289d7f592660d2fc954636b6ca85cf16c4c84ec0
Showing with 50 additions and 4 deletions.
  1. +1 −1 src/lib.rs
  2. +8 −0 src/main.rs
  3. +25 −0 src/request.rs
  4. +13 −2 src/stream.rs
  5. +3 −1 src/unit.rs
@@ -111,7 +111,7 @@ mod test;
pub use crate::agent::Agent;
pub use crate::error::Error;
pub use crate::header::Header;
pub use crate::request::Request;
pub use crate::request::{Request, IpVersion};
pub use crate::response::Response;

// re-export
@@ -0,0 +1,8 @@
use ureq::IpVersion;

fn main() {
ureq::get("https://google.com/")
.set_preferred_ip_version(IpVersion::V6)
.call();
println!("done");
}
@@ -21,6 +21,16 @@ lazy_static! {
{ Url::parse("http://localhost/").expect("Failed to parse URL_BASE") };
}

#[derive(Copy, Clone, Debug)]
pub enum IpVersion {
V4,
V6,
}

impl Default for IpVersion {
fn default() -> Self { IpVersion::V6 }
}

/// Request instances are builders that creates a request.
///
/// ```
@@ -45,6 +55,7 @@ pub struct Request {
pub(crate) timeout_read: u64,
pub(crate) timeout_write: u64,
pub(crate) redirects: u32,
pub(crate) preferred_ip_version: IpVersion,
}

impl ::std::fmt::Debug for Request {
@@ -219,6 +230,20 @@ impl Request {
self
}

/// Set IP version to use.
///
/// ```
/// let req = ureq::get("/my_page")
/// .set_preferred_ip_version(IpVersion::V4)
/// .call();
///
/// assert_eq!(IpVersion::V4, req.preferred_api_version);
/// ```
pub fn set_preferred_ip_version(&mut self, ip_version: IpVersion) -> &mut Request {
self.preferred_ip_version = ip_version;
self
}

/// Returns the value for a set header.
///
/// ```
@@ -11,6 +11,7 @@ use rustls::StreamOwned;

use crate::error::Error;
use crate::unit::Unit;
use crate::request::IpVersion;

#[allow(clippy::large_enum_variant)]
pub enum Stream {
@@ -167,8 +168,18 @@ pub(crate) fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<Tcp
return Err(Error::DnsFailed(format!("No ip address for {}", hostname)));
}

// pick first ip, or should we randomize?
let sock_addr = ips[0];
let sock_addr =
if let Some(ip) = ips.iter().find(
|&&ip|
match (ip, unit.preferred_ip_version) {
(std::net::SocketAddr::V6(_), IpVersion::V6) => true,
(std::net::SocketAddr::V4(_), IpVersion::V4) => true,
_ => false,
}) {
*ip
} else {
ips[0]
};

// connect with a configured timeout.
let stream = match unit.timeout_connect {
@@ -11,7 +11,7 @@ use crate::agent::AgentState;
use crate::body::{self, Payload, SizedReader};
use crate::header;
use crate::stream::{self, connect_https, connect_test, Stream};
use crate::{Error, Header, Request, Response};
use crate::{Error, Header, Request, Response, IpVersion};

use crate::pool::DEFAULT_HOST;

@@ -29,6 +29,7 @@ pub(crate) struct Unit {
pub timeout_read: u64,
pub timeout_write: u64,
pub method: String,
pub preferred_ip_version: IpVersion,
}

impl Unit {
@@ -82,6 +83,7 @@ impl Unit {
is_chunked,
query_string,
headers,
preferred_ip_version: req.preferred_ip_version,
timeout_connect: req.timeout_connect,
timeout_read: req.timeout_read,
timeout_write: req.timeout_write,

0 comments on commit 289d7f5

Please sign in to comment.
You can’t perform that action at this time.