Skip to content

Commit

Permalink
Update HTTP client example
Browse files Browse the repository at this point in the history
Now support IPv6.
  • Loading branch information
Thomasdezeeuw committed Jan 1, 2025
1 parent 81a7047 commit 94cffc9
Showing 1 changed file with 5 additions and 22 deletions.
27 changes: 5 additions & 22 deletions examples/http_client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::net::{SocketAddr, SocketAddrV4};
use std::{env, io, mem, str};
use std::net::SocketAddr;
use std::{env, io, str};

use a10::net::socket;
use a10::{AsyncFd, Ring, SubmissionQueue};
Expand All @@ -22,13 +22,8 @@ fn main() -> io::Result<()> {

// Get an IPv4 address for the domain (using blocking I/O).
let address = std::net::ToSocketAddrs::to_socket_addrs(&addr_host)?
.filter(SocketAddr::is_ipv4)
.next()
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "failed to lookup ip"))?;
let address = match address {
SocketAddr::V4(address) => address,
SocketAddr::V6(_) => unreachable!(),
};

// Create our future that makes the request.
let request_future = request(ring.submission_queue().clone(), &host, address);
Expand All @@ -50,7 +45,7 @@ fn main() -> io::Result<()> {
}

/// Make a HTTP GET request to `address`.
async fn request(sq: SubmissionQueue, host: &str, address: SocketAddrV4) -> io::Result<Vec<u8>> {
async fn request(sq: SubmissionQueue, host: &str, address: SocketAddr) -> io::Result<Vec<u8>> {
// Create a new TCP, IPv4 socket.
let domain = libc::AF_INET;
let r#type = libc::SOCK_STREAM | libc::SOCK_CLOEXEC;
Expand All @@ -59,14 +54,13 @@ async fn request(sq: SubmissionQueue, host: &str, address: SocketAddrV4) -> io::
let socket: AsyncFd = socket(sq, domain, r#type, protocol, flags).await?;

// Connect.
let addr = to_sockaddr_storage(address);
socket.connect(addr).await?;
socket.connect(address).await?;

// Send a HTTP GET / request to the socket.
let host = host.split_once(':').map(|(h, _)| h).unwrap_or(host);
let version = env!("CARGO_PKG_VERSION");
let request = format!("GET / HTTP/1.1\r\nHost: {host}\r\nUser-Agent: A10-example/{version}\r\nAccept: */*\r\n\r\n");
socket.send(request, 0).await?;
socket.send_all(request, 0).await?;

// Receiving the response.
let recv_buf = socket.recv(Vec::with_capacity(8192), 0).await?;
Expand All @@ -77,14 +71,3 @@ async fn request(sq: SubmissionQueue, host: &str, address: SocketAddrV4) -> io::

Ok(recv_buf)
}

fn to_sockaddr_storage(addr: SocketAddrV4) -> libc::sockaddr_in {
// SAFETY: a `sockaddr_in` of all zeros is valid.
let mut storage: libc::sockaddr_in = unsafe { mem::zeroed() };
storage.sin_family = libc::AF_INET as _;
storage.sin_port = addr.port().to_be();
storage.sin_addr = libc::in_addr {
s_addr: u32::from_ne_bytes(addr.ip().octets()),
};
storage
}

0 comments on commit 94cffc9

Please sign in to comment.