Skip to main content

trillium_async_std/
client.rs

1use crate::{AsyncStdRuntime, AsyncStdTransport};
2use async_std::net::{TcpStream, ToSocketAddrs};
3use std::{
4    io::{Error, ErrorKind, Result},
5    net::SocketAddr,
6};
7use trillium_server_common::{Connector, Destination, Transport, url::Url};
8
9/// configuration for the tcp Connector
10#[derive(Default, Debug, Clone, Copy)]
11pub struct ClientConfig {
12    /// disable [nagle's algorithm](https://en.wikipedia.org/wiki/Nagle%27s_algorithm)
13    pub nodelay: Option<bool>,
14
15    /// set a time to live for the tcp protocol
16    pub ttl: Option<u32>,
17}
18
19impl ClientConfig {
20    /// constructs a default ClientConfig
21    pub const fn new() -> Self {
22        Self {
23            nodelay: None,
24            ttl: None,
25        }
26    }
27
28    /// chainable setter to set default nodelay
29    pub const fn with_nodelay(mut self, nodelay: bool) -> Self {
30        self.nodelay = Some(nodelay);
31        self
32    }
33
34    /// chainable setter for ip ttl
35    pub const fn with_ttl(mut self, ttl: u32) -> Self {
36        self.ttl = Some(ttl);
37        self
38    }
39}
40
41impl Connector for ClientConfig {
42    type Runtime = AsyncStdRuntime;
43    type Transport = AsyncStdTransport<TcpStream>;
44    type Udp = crate::AsyncStdUdpSocket;
45
46    async fn connect(&self, url: &Url) -> Result<Self::Transport> {
47        self.connect_to(Destination::from_url(url)?).await
48    }
49
50    async fn connect_to(&self, destination: Destination) -> Result<Self::Transport> {
51        if destination.secure() {
52            return Err(Error::new(
53                ErrorKind::InvalidInput,
54                "this connector does not support TLS",
55            ));
56        }
57
58        let addrs = destination.addrs();
59        let mut tcp = if addrs.is_empty() {
60            let host = destination.host().ok_or_else(|| {
61                Error::new(
62                    ErrorKind::InvalidInput,
63                    "destination has neither host nor addresses",
64                )
65            })?;
66            Self::Transport::connect((host, destination.port())).await?
67        } else {
68            Self::Transport::connect(addrs).await?
69        };
70
71        if let Some(nodelay) = self.nodelay {
72            tcp.set_nodelay(nodelay)?;
73        }
74
75        if let Some(ttl) = self.ttl {
76            tcp.set_ip_ttl(ttl)?;
77        }
78
79        Ok(tcp)
80    }
81
82    fn runtime(&self) -> Self::Runtime {
83        AsyncStdRuntime::default()
84    }
85
86    async fn resolve(&self, host: &str, port: u16) -> Result<Vec<SocketAddr>> {
87        (host, port).to_socket_addrs().await.map(Iterator::collect)
88    }
89}