Skip to content

Commit 613f9ff

Browse files
authored
feat: add Host struct and convert from String and Url
1 parent f49acaa commit 613f9ff

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ native-tls = "0.2.3"
1919
thiserror = "1.0.9"
2020
async-std = { version = "1.4.0", default-features = false, features = ["std"], optional = true }
2121
tokio = { version = "0.2.9", default-features = false, features = ["io-util"], optional = true }
22+
url = "2.1.1"
2223

2324
[features]
2425
default = ["runtime-async-std"]

src/lib.rs

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ mod tls_stream;
4747
pub use accept::accept;
4848
pub use acceptor::{Error as AcceptError, TlsAcceptor};
4949
pub use connect::{connect, TlsConnector};
50+
pub use host::Host;
5051
pub use tls_stream::TlsStream;
5152

5253
#[doc(inline)]
@@ -97,9 +98,66 @@ mod accept {
9798
}
9899
}
99100

101+
mod host {
102+
use url::Url;
103+
104+
/// The host part of a domain (without scheme, port and path).
105+
///
106+
/// This is the argument to the [`connect`](crate::connect::connect) function. Strings and string slices are
107+
/// converted into Hosts automatically, as is [Url](url::Url) with the `host-from-url` feature (enabled by default).
108+
#[derive(Debug)]
109+
pub struct Host(String);
110+
111+
impl Host {
112+
/// The host as string. Consumes self.
113+
pub fn as_string(self) -> String {
114+
self.0
115+
}
116+
}
117+
118+
impl From<&str> for Host {
119+
fn from(host: &str) -> Self {
120+
Self(host.into())
121+
}
122+
}
123+
124+
impl From<String> for Host {
125+
fn from(host: String) -> Self {
126+
Self(host)
127+
}
128+
}
129+
130+
impl From<&String> for Host {
131+
fn from(host: &String) -> Self {
132+
Self(host.into())
133+
}
134+
}
135+
136+
impl From<Url> for Host {
137+
fn from(url: Url) -> Self {
138+
Self(
139+
url.host_str()
140+
.expect("URL has to include a host part.")
141+
.into(),
142+
)
143+
}
144+
}
145+
146+
impl From<&Url> for Host {
147+
fn from(url: &Url) -> Self {
148+
Self(
149+
url.host_str()
150+
.expect("URL has to include a host part.")
151+
.into(),
152+
)
153+
}
154+
}
155+
}
156+
100157
mod connect {
101158
use std::fmt::{self, Debug};
102159

160+
use crate::host::Host;
103161
use crate::runtime::{AsyncRead, AsyncWrite};
104162
use crate::TlsStream;
105163
use crate::{Certificate, Identity, Protocol};
@@ -127,11 +185,11 @@ mod connect {
127185
/// # #[cfg(feature = "runtime-tokio")]
128186
/// # fn main() {}
129187
/// ```
130-
pub async fn connect<S>(domain: &str, stream: S) -> native_tls::Result<TlsStream<S>>
188+
pub async fn connect<S>(host: impl Into<Host>, stream: S) -> native_tls::Result<TlsStream<S>>
131189
where
132190
S: AsyncRead + AsyncWrite + Unpin,
133191
{
134-
let stream = TlsConnector::new().connect(domain, stream).await?;
192+
let stream = TlsConnector::new().connect(host, stream).await?;
135193
Ok(stream)
136194
}
137195

@@ -280,13 +338,19 @@ mod connect {
280338
/// # #[cfg(feature = "runtime-tokio")]
281339
/// # fn main() {}
282340
/// ```
283-
pub async fn connect<S>(&self, domain: &str, stream: S) -> native_tls::Result<TlsStream<S>>
341+
pub async fn connect<S>(
342+
&self,
343+
host: impl Into<Host>,
344+
stream: S,
345+
) -> native_tls::Result<TlsStream<S>>
284346
where
285347
S: AsyncRead + AsyncWrite + Unpin,
286348
{
349+
let host: Host = host.into();
350+
let domain = host.as_string();
287351
let connector = self.builder.build()?;
288352
let connector = crate::connector::TlsConnector::from(connector);
289-
let stream = connector.connect(domain, stream).await?;
353+
let stream = connector.connect(&domain, stream).await?;
290354
Ok(stream)
291355
}
292356
}

tests/google.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ async fn fetch_google() {
5656
// Send off the request by first negotiating an SSL handshake, then writing
5757
// of our request, then flushing, then finally read off the response.
5858
let connector = async_native_tls::TlsConnector::new();
59-
let mut socket = t!(connector.connect("google.com", socket).await);
59+
let url = url::Url::parse("https://google.com/").unwrap();
60+
let mut socket = t!(connector.connect(&url, socket).await);
6061
t!(socket.write_all(b"GET / HTTP/1.0\r\n\r\n").await);
6162
let mut data = Vec::new();
6263
t!(socket.read_to_end(&mut data).await);

0 commit comments

Comments
 (0)