I am trying to send a HTTP request with IPv6.
While there are a lot of HTTP libraries (reqwest, hyper, etc). I couldn't find a library or a way to send a request with it.
In python, i was able to specify TCP family class with creating a custom TCPConnector.
import aiohttp
import socket
conn = aiohttp.TCPConnector(family=socket.AF_INET6)
I looked through the same TCPConnector
, ClientBuilder
things in Rust.
Reqwest's ClientBuilder
doesn't supports it. See: https://docs.rs/reqwest/0.11.0/reqwest/struct.ClientBuilder.html
Hyper's HTTPConnector
also doesn't supports it. See: https://docs.rs/hyper/0.14.4/hyper/client/struct.HttpConnector.html
It is not obvious but if you specify the local_address option, the connection will use that ip address to send the request.
I use Reqwest (v0.11.1
in the example) now.
use std::net::IpAddr;
use std::{collections::HashMap, str::FromStr};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest::Client::builder()
.local_address(IpAddr::from_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334")?)
.build()?;
let resp = client
.get("https://httpbin.org/ip")
.send()
.await?
.json::<HashMap<String, String>>()
.await?;
println!("{:#?}", resp);
Ok(())
}
This also works i but i prefer reqwest
now.
Fortunately, i found a HTTP library called isahc library that i can specify IP version.
use isahc::{config::IpVersion, prelude::*, HttpClient};
HttpClient::builder()
.ip_version(IpVersion::V6)
Isahc's isahc::HttpClientBuilder
struct has ip_version
method that you can specify IP version. (see)
use isahc::{config::IpVersion, prelude::*, HttpClient};
use std::{
io::{copy, stdout},
time::Duration,
};
fn main() -> Result<(), isahc::Error> {
let client = HttpClient::builder()
.timeout(Duration::from_secs(5))
.ip_version(IpVersion::V6)
.build()?;
let mut response = client.get("some url")?;
copy(response.body_mut(), &mut stdout())?;
Ok(())
}