GitHub

Original file line numberDiff line numberDiff line change

@@ -111,7 +111,7 @@ mod test;

111111

pub use crate::agent::Agent;

112112

pub use crate::error::Error;

113113

pub use crate::header::Header;

114-

pub use crate::request::Request;

114+

pub use crate::request::{Request, IpVersion};

115115

pub use crate::response::Response;

116116
117117

// re-export

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,8 @@

1+

use ureq::IpVersion;

2+
3+

fn main() {

4+

ureq::get("https://google.com/")

5+

.set_preferred_ip_version(IpVersion::V6)

6+

.call();

7+

println!("done");

8+

}

Original file line numberDiff line numberDiff line change

@@ -21,6 +21,16 @@ lazy_static! {

2121

{ Url::parse("http://localhost/").expect("Failed to parse URL_BASE") };

2222

}

2323
24+

#[derive(Copy, Clone, Debug)]

25+

pub enum IpVersion {

26+

V4,

27+

V6,

28+

}

29+
30+

impl Default for IpVersion {

31+

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

32+

}

33+
2434

/// Request instances are builders that creates a request.

2535

///

2636

/// ```

@@ -45,6 +55,7 @@ pub struct Request {

4555

pub(crate) timeout_read: u64,

4656

pub(crate) timeout_write: u64,

4757

pub(crate) redirects: u32,

58+

pub(crate) preferred_ip_version: IpVersion,

4859

}

4960
5061

impl ::std::fmt::Debug for Request {

@@ -219,6 +230,20 @@ impl Request {

219230

self

220231

}

221232
233+

/// Set IP version to use.

234+

///

235+

/// ```

236+

/// let req = ureq::get("/my_page")

237+

/// .set_preferred_ip_version(IpVersion::V4)

238+

/// .call();

239+

///

240+

/// assert_eq!(IpVersion::V4, req.preferred_api_version);

241+

/// ```

242+

pub fn set_preferred_ip_version(&mut self, ip_version: IpVersion) -> &mut Request {

243+

self.preferred_ip_version = ip_version;

244+

self

245+

}

246+
222247

/// Returns the value for a set header.

223248

///

224249

/// ```

Original file line numberDiff line numberDiff line change

@@ -11,6 +11,7 @@ use rustls::StreamOwned;

1111
1212

use crate::error::Error;

1313

use crate::unit::Unit;

14+

use crate::request::IpVersion;

1415
1516

#[allow(clippy::large_enum_variant)]

1617

pub enum Stream {

@@ -167,8 +168,18 @@ pub(crate) fn connect_host(unit: &Unit, hostname: &str, port: u16) -> Result<Tcp

167168

return Err(Error::DnsFailed(format!("No ip address for {}", hostname)));

168169

}

169170
170-

// pick first ip, or should we randomize?

171-

let sock_addr = ips[0];

171+

let sock_addr =

172+

if let Some(ip) = ips.iter().find(

173+

|&&ip|

174+

match (ip, unit.preferred_ip_version) {

175+

(std::net::SocketAddr::V6(_), IpVersion::V6) => true,

176+

(std::net::SocketAddr::V4(_), IpVersion::V4) => true,

177+

_ => false,

178+

}) {

179+

*ip

180+

} else {

181+

ips[0]

182+

};

172183
173184

// connect with a configured timeout.

174185

let stream = match unit.timeout_connect {

Original file line numberDiff line numberDiff line change

@@ -11,7 +11,7 @@ use crate::agent::AgentState;

1111

use crate::body::{self, Payload, SizedReader};

1212

use crate::header;

1313

use crate::stream::{self, connect_https, connect_test, Stream};

14-

use crate::{Error, Header, Request, Response};

14+

use crate::{Error, Header, Request, Response, IpVersion};

1515
1616

use crate::pool::DEFAULT_HOST;

1717

@@ -29,6 +29,7 @@ pub(crate) struct Unit {

2929

pub timeout_read: u64,

3030

pub timeout_write: u64,

3131

pub method: String,

32+

pub preferred_ip_version: IpVersion,

3233

}

3334
3435

impl Unit {

@@ -82,6 +83,7 @@ impl Unit {

8283

is_chunked,

8384

query_string,

8485

headers,

86+

preferred_ip_version: req.preferred_ip_version,

8587

timeout_connect: req.timeout_connect,

8688

timeout_read: req.timeout_read,

8789

timeout_write: req.timeout_write,

Read the original on github.com ↗