mirror of
https://github.com/ntex-rs/ntex.git
synced 2025-04-03 21:07:39 +03:00
replace trust-dns with blocking code
This commit is contained in:
parent
cb9e3ffeda
commit
111e4ec717
15 changed files with 90 additions and 152 deletions
|
@ -1,5 +1,9 @@
|
||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
|
## [0.4.3] - 2021-04-03
|
||||||
|
|
||||||
|
* Disable some of regex features
|
||||||
|
|
||||||
## [0.4.2] - 2021-03-16
|
## [0.4.2] - 2021-03-16
|
||||||
|
|
||||||
* Use `IntoPattern` for prefix resources
|
* Use `IntoPattern` for prefix resources
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "ntex-router"
|
name = "ntex-router"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
authors = ["ntex contributors <team@ntex.rs>"]
|
authors = ["ntex contributors <team@ntex.rs>"]
|
||||||
description = "Path router"
|
description = "Path router"
|
||||||
keywords = ["ntex"]
|
keywords = ["ntex"]
|
||||||
|
@ -17,11 +17,11 @@ path = "src/lib.rs"
|
||||||
default = ["http"]
|
default = ["http"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
regex = "1.4"
|
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
bytestring = "1.0"
|
bytestring = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
http = { version = "0.2", optional = true }
|
http = { version = "0.2", optional = true }
|
||||||
|
regex = { version = "1.4.5", default-features = false, features = ["std"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
* util: add custom Ready, Either future and several helper functions
|
* util: add custom Ready, Either future and several helper functions
|
||||||
|
|
||||||
|
* drop trust-dns, use blocking calls
|
||||||
|
|
||||||
* reduce futures crate dependencies
|
* reduce futures crate dependencies
|
||||||
|
|
||||||
## [0.3.13] - 2021-03-26
|
## [0.3.13] - 2021-03-26
|
||||||
|
|
|
@ -62,7 +62,7 @@ num_cpus = "1.13"
|
||||||
nanorand = "0.5"
|
nanorand = "0.5"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
pin-project-lite = "0.2"
|
pin-project-lite = "0.2"
|
||||||
regex = "1.4"
|
regex = { version = "1.4.5", default-features = false, features = ["std"] }
|
||||||
sha-1 = "0.9"
|
sha-1 = "0.9"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
serde = { version = "1.0", features=["derive"] }
|
serde = { version = "1.0", features=["derive"] }
|
||||||
|
@ -73,10 +73,6 @@ url = "2.1"
|
||||||
coo-kie = { version = "0.15", package = "cookie", optional = true }
|
coo-kie = { version = "0.15", package = "cookie", optional = true }
|
||||||
tokio = { version = "1", default-features=false, features = ["sync"] }
|
tokio = { version = "1", default-features=false, features = ["sync"] }
|
||||||
|
|
||||||
# resolver
|
|
||||||
trust-dns-proto = { version = "0.20", default-features = false }
|
|
||||||
trust-dns-resolver = { version = "0.20", default-features = false, features=["system-config", "tokio-runtime"] }
|
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
open-ssl = { version="0.10", package = "openssl", optional = true }
|
open-ssl = { version="0.10", package = "openssl", optional = true }
|
||||||
tokio-openssl = { version = "0.6.1", optional = true }
|
tokio-openssl = { version = "0.6.1", optional = true }
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use derive_more::{Display, From};
|
use derive_more::{Display, From};
|
||||||
use trust_dns_resolver::error::ResolveError;
|
|
||||||
|
|
||||||
#[derive(Debug, From, Display)]
|
#[derive(Debug, From, Display)]
|
||||||
pub enum ConnectError {
|
pub enum ConnectError {
|
||||||
/// Failed to resolve the hostname
|
/// Failed to resolve the hostname
|
||||||
|
#[from(ignore)]
|
||||||
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
||||||
Resolver(ResolveError),
|
Resolver(io::Error),
|
||||||
|
|
||||||
/// No dns records
|
/// No dns records
|
||||||
#[display(fmt = "No dns records found for the input")]
|
#[display(fmt = "No dns records found for the input")]
|
||||||
|
|
|
@ -13,42 +13,13 @@ pub mod openssl;
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
pub mod rustls;
|
pub mod rustls;
|
||||||
|
|
||||||
pub use trust_dns_resolver::config::{self, ResolverConfig, ResolverOpts};
|
use crate::rt::net::TcpStream;
|
||||||
use trust_dns_resolver::system_conf::read_system_conf;
|
|
||||||
pub use trust_dns_resolver::{error::ResolveError, TokioAsyncResolver as DnsResolver};
|
|
||||||
|
|
||||||
use crate::rt::{net::TcpStream, Arbiter};
|
|
||||||
|
|
||||||
pub use self::error::ConnectError;
|
pub use self::error::ConnectError;
|
||||||
pub use self::message::{Address, Connect};
|
pub use self::message::{Address, Connect};
|
||||||
pub use self::resolve::Resolver;
|
pub use self::resolve::Resolver;
|
||||||
pub use self::service::Connector;
|
pub use self::service::Connector;
|
||||||
|
|
||||||
pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> DnsResolver {
|
|
||||||
DnsResolver::tokio(cfg, opts).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DefaultResolver(DnsResolver);
|
|
||||||
|
|
||||||
pub fn default_resolver() -> DnsResolver {
|
|
||||||
if Arbiter::contains_item::<DefaultResolver>() {
|
|
||||||
Arbiter::get_item(|item: &DefaultResolver| item.0.clone())
|
|
||||||
} else {
|
|
||||||
let (cfg, opts) = match read_system_conf() {
|
|
||||||
Ok((cfg, opts)) => (cfg, opts),
|
|
||||||
Err(e) => {
|
|
||||||
log::error!("TRust-DNS can not load system config: {}", e);
|
|
||||||
(ResolverConfig::default(), ResolverOpts::default())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let resolver = DnsResolver::tokio(cfg, opts).unwrap();
|
|
||||||
|
|
||||||
Arbiter::set_item(DefaultResolver(resolver.clone()));
|
|
||||||
resolver
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resolve and connect to remote host
|
/// Resolve and connect to remote host
|
||||||
pub fn connect<T, U>(message: U) -> impl Future<Output = Result<TcpStream, ConnectError>>
|
pub fn connect<T, U>(message: U) -> impl Future<Output = Result<TcpStream, ConnectError>>
|
||||||
where
|
where
|
||||||
|
@ -56,6 +27,6 @@ where
|
||||||
Connect<T>: From<U>,
|
Connect<T>: From<U>,
|
||||||
{
|
{
|
||||||
service::ConnectServiceResponse::new(Box::pin(
|
service::ConnectServiceResponse::new(Box::pin(
|
||||||
Resolver::new(default_resolver()).lookup(message.into()),
|
Resolver::new().lookup(message.into()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::rt::net::TcpStream;
|
||||||
use crate::service::{Service, ServiceFactory};
|
use crate::service::{Service, ServiceFactory};
|
||||||
use crate::util::Ready;
|
use crate::util::Ready;
|
||||||
|
|
||||||
use super::{Address, Connect, ConnectError, Connector, DnsResolver};
|
use super::{Address, Connect, ConnectError, Connector};
|
||||||
|
|
||||||
pub struct OpensslConnector<T> {
|
pub struct OpensslConnector<T> {
|
||||||
connector: Connector<T>,
|
connector: Connector<T>,
|
||||||
|
@ -22,14 +22,6 @@ impl<T> OpensslConnector<T> {
|
||||||
openssl: connector,
|
openssl: connector,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct new connect service with custom dns resolver
|
|
||||||
pub fn with_resolver(connector: SslConnector, resolver: DnsResolver) -> Self {
|
|
||||||
OpensslConnector {
|
|
||||||
connector: Connector::new(resolver),
|
|
||||||
openssl: connector,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address + 'static> OpensslConnector<T> {
|
impl<T: Address + 'static> OpensslConnector<T> {
|
||||||
|
|
|
@ -1,33 +1,22 @@
|
||||||
use std::{
|
use std::{fmt, future::Future, io, marker, net, pin::Pin, task::Context, task::Poll};
|
||||||
fmt, future::Future, marker::PhantomData, net::SocketAddr, pin::Pin, rc::Rc,
|
|
||||||
task::Context, task::Poll,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{default_resolver, Address, Connect, ConnectError, DnsResolver};
|
use super::{Address, Connect, ConnectError};
|
||||||
use crate::service::{Service, ServiceFactory};
|
use crate::service::{Service, ServiceFactory};
|
||||||
use crate::util::{Either, Ready};
|
use crate::util::{Either, Ready};
|
||||||
|
|
||||||
/// DNS Resolver Service
|
/// DNS Resolver Service
|
||||||
pub struct Resolver<T> {
|
pub struct Resolver<T>(marker::PhantomData<T>);
|
||||||
resolver: Rc<DnsResolver>,
|
|
||||||
_t: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> fmt::Debug for Resolver<T> {
|
impl<T> fmt::Debug for Resolver<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Resolver")
|
f.debug_struct("Resolver").finish()
|
||||||
.field("resolver", &self.resolver)
|
|
||||||
.finish()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Resolver<T> {
|
impl<T> Resolver<T> {
|
||||||
/// Create new resolver instance with custom configuration and options.
|
/// Create new resolver instance with custom configuration and options.
|
||||||
pub fn new(resolver: DnsResolver) -> Self {
|
pub fn new() -> Self {
|
||||||
Resolver {
|
Resolver(marker::PhantomData)
|
||||||
resolver: Rc::new(resolver),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,24 +29,29 @@ impl<T: Address> Resolver<T> {
|
||||||
if req.addr.is_some() || req.req.addr().is_some() {
|
if req.addr.is_some() || req.req.addr().is_some() {
|
||||||
Either::Right(Ready::ok(req))
|
Either::Right(Ready::ok(req))
|
||||||
} else if let Ok(ip) = req.host().parse() {
|
} else if let Ok(ip) = req.host().parse() {
|
||||||
req.addr = Some(Either::Left(SocketAddr::new(ip, req.port())));
|
req.addr = Some(Either::Left(net::SocketAddr::new(ip, req.port())));
|
||||||
Either::Right(Ready::ok(req))
|
Either::Right(Ready::ok(req))
|
||||||
} else {
|
} else {
|
||||||
trace!("DNS resolver: resolving host {:?}", req.host());
|
trace!("DNS resolver: resolving host {:?}", req.host());
|
||||||
let resolver = self.resolver.clone();
|
|
||||||
|
|
||||||
Either::Left(async move {
|
Either::Left(async move {
|
||||||
let fut = if let Some(host) = req.host().splitn(2, ':').next() {
|
let host = if req.host().contains(':') {
|
||||||
resolver.lookup_ip(host)
|
req.host().to_string()
|
||||||
} else {
|
} else {
|
||||||
resolver.lookup_ip(req.host())
|
format!("{}:{}", req.host(), req.port())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let fut = crate::rt::task::spawn_blocking(move || {
|
||||||
|
net::ToSocketAddrs::to_socket_addrs(&host)
|
||||||
|
});
|
||||||
|
|
||||||
match fut.await {
|
match fut.await {
|
||||||
Ok(ips) => {
|
Ok(Ok(ips)) => {
|
||||||
let port = req.port();
|
let port = req.port();
|
||||||
let req = req
|
let req = req.set_addrs(ips.map(|mut ip| {
|
||||||
.set_addrs(ips.iter().map(|ip| SocketAddr::new(ip, port)));
|
ip.set_port(port);
|
||||||
|
ip
|
||||||
|
}));
|
||||||
|
|
||||||
trace!(
|
trace!(
|
||||||
"DNS resolver: host {:?} resolved to {:?}",
|
"DNS resolver: host {:?} resolved to {:?}",
|
||||||
|
@ -71,13 +65,24 @@ impl<T: Address> Resolver<T> {
|
||||||
Ok(req)
|
Ok(req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(Err(e)) => {
|
||||||
|
trace!(
|
||||||
|
"DNS resolver: failed to resolve host {:?} err: {}",
|
||||||
|
req.host(),
|
||||||
|
e
|
||||||
|
);
|
||||||
|
Err(ConnectError::Resolver(e))
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
trace!(
|
trace!(
|
||||||
"DNS resolver: failed to resolve host {:?} err: {}",
|
"DNS resolver: failed to resolve host {:?} err: {}",
|
||||||
req.host(),
|
req.host(),
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
Err(e.into())
|
Err(ConnectError::Resolver(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
e,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -87,19 +92,13 @@ impl<T: Address> Resolver<T> {
|
||||||
|
|
||||||
impl<T> Default for Resolver<T> {
|
impl<T> Default for Resolver<T> {
|
||||||
fn default() -> Resolver<T> {
|
fn default() -> Resolver<T> {
|
||||||
Resolver {
|
Resolver(marker::PhantomData)
|
||||||
resolver: Rc::new(default_resolver()),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Clone for Resolver<T> {
|
impl<T> Clone for Resolver<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Resolver {
|
Resolver(marker::PhantomData)
|
||||||
resolver: self.resolver.clone(),
|
|
||||||
_t: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ mod tests {
|
||||||
|
|
||||||
#[crate::rt_test]
|
#[crate::rt_test]
|
||||||
async fn resolver() {
|
async fn resolver() {
|
||||||
let resolver = Resolver::new(DnsResolver::tokio_from_system_conf().unwrap());
|
let resolver = Resolver::new();
|
||||||
assert!(format!("{:?}", resolver).contains("Resolver"));
|
assert!(format!("{:?}", resolver).contains("Resolver"));
|
||||||
let srv = resolver.new_service(()).await.unwrap();
|
let srv = resolver.new_service(()).await.unwrap();
|
||||||
assert!(lazy(|cx| srv.poll_ready(cx)).await.is_ready());
|
assert!(lazy(|cx| srv.poll_ready(cx)).await.is_ready());
|
||||||
|
@ -152,7 +151,7 @@ mod tests {
|
||||||
let res = srv.call(Connect::new("---11213")).await;
|
let res = srv.call(Connect::new("---11213")).await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
|
let addr: net::SocketAddr = "127.0.0.1:8080".parse().unwrap();
|
||||||
let res = srv
|
let res = srv
|
||||||
.call(Connect::new("www.rust-lang.org").set_addrs(vec![addr]))
|
.call(Connect::new("www.rust-lang.org").set_addrs(vec![addr]))
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::rt::net::TcpStream;
|
||||||
use crate::service::{Service, ServiceFactory};
|
use crate::service::{Service, ServiceFactory};
|
||||||
use crate::util::Ready;
|
use crate::util::Ready;
|
||||||
|
|
||||||
use super::{Address, Connect, ConnectError, Connector, DnsResolver};
|
use super::{Address, Connect, ConnectError, Connector};
|
||||||
|
|
||||||
/// Rustls connector factory
|
/// Rustls connector factory
|
||||||
pub struct RustlsConnector<T> {
|
pub struct RustlsConnector<T> {
|
||||||
|
@ -25,14 +25,6 @@ impl<T> RustlsConnector<T> {
|
||||||
connector: Connector::default(),
|
connector: Connector::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct new connect service with custom dns resolver
|
|
||||||
pub fn with_resolver(config: Arc<ClientConfig>, resolver: DnsResolver) -> Self {
|
|
||||||
RustlsConnector {
|
|
||||||
config,
|
|
||||||
connector: Connector::new(resolver),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Address + 'static> RustlsConnector<T> {
|
impl<T: Address + 'static> RustlsConnector<T> {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::rt::net::TcpStream;
|
||||||
use crate::service::{Service, ServiceFactory};
|
use crate::service::{Service, ServiceFactory};
|
||||||
use crate::util::{Either, Ready};
|
use crate::util::{Either, Ready};
|
||||||
|
|
||||||
use super::{Address, Connect, ConnectError, DnsResolver, Resolver};
|
use super::{Address, Connect, ConnectError, Resolver};
|
||||||
|
|
||||||
pub struct Connector<T> {
|
pub struct Connector<T> {
|
||||||
resolver: Resolver<T>,
|
resolver: Resolver<T>,
|
||||||
|
@ -13,9 +13,9 @@ pub struct Connector<T> {
|
||||||
|
|
||||||
impl<T> Connector<T> {
|
impl<T> Connector<T> {
|
||||||
/// Construct new connect service with custom dns resolver
|
/// Construct new connect service with custom dns resolver
|
||||||
pub fn new(resolver: DnsResolver) -> Self {
|
pub fn new() -> Self {
|
||||||
Connector {
|
Connector {
|
||||||
resolver: Resolver::new(resolver),
|
resolver: Resolver::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{rc::Rc, task::Context, task::Poll, time::Duration};
|
use std::{rc::Rc, task::Context, task::Poll, time::Duration};
|
||||||
|
|
||||||
use crate::codec::{AsyncRead, AsyncWrite};
|
use crate::codec::{AsyncRead, AsyncWrite};
|
||||||
use crate::connect::{self, Connect as TcpConnect, Connector as TcpConnector};
|
use crate::connect::{Connect as TcpConnect, Connector as TcpConnector};
|
||||||
use crate::http::{Protocol, Uri};
|
use crate::http::{Protocol, Uri};
|
||||||
use crate::service::{apply_fn, boxed, Service};
|
use crate::service::{apply_fn, boxed, Service};
|
||||||
use crate::util::timeout::{TimeoutError, TimeoutService};
|
use crate::util::timeout::{TimeoutError, TimeoutService};
|
||||||
|
@ -44,8 +44,6 @@ pub struct Connector {
|
||||||
limit: usize,
|
limit: usize,
|
||||||
connector: BoxedConnector,
|
connector: BoxedConnector,
|
||||||
ssl_connector: Option<BoxedConnector>,
|
ssl_connector: Option<BoxedConnector>,
|
||||||
#[allow(dead_code)]
|
|
||||||
resolver: connect::DnsResolver,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Io: AsyncRead + AsyncWrite + Unpin {}
|
trait Io: AsyncRead + AsyncWrite + Unpin {}
|
||||||
|
@ -53,15 +51,15 @@ impl<T: AsyncRead + AsyncWrite + Unpin> Io for T {}
|
||||||
|
|
||||||
impl Default for Connector {
|
impl Default for Connector {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Connector::new(connect::default_resolver())
|
Connector::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Connector {
|
impl Connector {
|
||||||
pub fn new(resolver: connect::DnsResolver) -> Connector {
|
pub fn new() -> Connector {
|
||||||
let conn = Connector {
|
let conn = Connector {
|
||||||
connector: boxed::service(
|
connector: boxed::service(
|
||||||
TcpConnector::new(resolver.clone())
|
TcpConnector::new()
|
||||||
.map(|io| (Box::new(io) as Box<dyn Io>, Protocol::Http1))
|
.map(|io| (Box::new(io) as Box<dyn Io>, Protocol::Http1))
|
||||||
.map_err(ConnectError::from),
|
.map_err(ConnectError::from),
|
||||||
),
|
),
|
||||||
|
@ -71,7 +69,6 @@ impl Connector {
|
||||||
conn_keep_alive: Duration::from_secs(15),
|
conn_keep_alive: Duration::from_secs(15),
|
||||||
disconnect_timeout: Duration::from_millis(3000),
|
disconnect_timeout: Duration::from_millis(3000),
|
||||||
limit: 100,
|
limit: 100,
|
||||||
resolver,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
|
@ -114,23 +111,19 @@ impl Connector {
|
||||||
pub fn openssl(self, connector: OpensslConnector) -> Self {
|
pub fn openssl(self, connector: OpensslConnector) -> Self {
|
||||||
use crate::connect::openssl::OpensslConnector;
|
use crate::connect::openssl::OpensslConnector;
|
||||||
|
|
||||||
let resolver = self.resolver.clone();
|
|
||||||
|
|
||||||
const H2: &[u8] = b"h2";
|
const H2: &[u8] = b"h2";
|
||||||
self.secure_connector(OpensslConnector::with_resolver(connector, resolver).map(
|
self.secure_connector(OpensslConnector::new(connector).map(|sock| {
|
||||||
|sock| {
|
let h2 = sock
|
||||||
let h2 = sock
|
.ssl()
|
||||||
.ssl()
|
.selected_alpn_protocol()
|
||||||
.selected_alpn_protocol()
|
.map(|protos| protos.windows(2).any(|w| w == H2))
|
||||||
.map(|protos| protos.windows(2).any(|w| w == H2))
|
.unwrap_or(false);
|
||||||
.unwrap_or(false);
|
if h2 {
|
||||||
if h2 {
|
(sock, Protocol::Http2)
|
||||||
(sock, Protocol::Http2)
|
} else {
|
||||||
} else {
|
(sock, Protocol::Http1)
|
||||||
(sock, Protocol::Http1)
|
}
|
||||||
}
|
}))
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
|
@ -138,24 +131,20 @@ impl Connector {
|
||||||
pub fn rustls(self, connector: Arc<ClientConfig>) -> Self {
|
pub fn rustls(self, connector: Arc<ClientConfig>) -> Self {
|
||||||
use crate::connect::rustls::{RustlsConnector, Session};
|
use crate::connect::rustls::{RustlsConnector, Session};
|
||||||
|
|
||||||
let resolver = self.resolver.clone();
|
|
||||||
|
|
||||||
const H2: &[u8] = b"h2";
|
const H2: &[u8] = b"h2";
|
||||||
self.secure_connector(RustlsConnector::with_resolver(connector, resolver).map(
|
self.secure_connector(RustlsConnector::new(connector).map(|sock| {
|
||||||
|sock| {
|
let h2 = sock
|
||||||
let h2 = sock
|
.get_ref()
|
||||||
.get_ref()
|
.1
|
||||||
.1
|
.get_alpn_protocol()
|
||||||
.get_alpn_protocol()
|
.map(|protos| protos.windows(2).any(|w| w == H2))
|
||||||
.map(|protos| protos.windows(2).any(|w| w == H2))
|
.unwrap_or(false);
|
||||||
.unwrap_or(false);
|
if h2 {
|
||||||
if h2 {
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
|
||||||
(Box::new(sock) as Box<dyn Io>, Protocol::Http2)
|
} else {
|
||||||
} else {
|
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
|
||||||
(Box::new(sock) as Box<dyn Io>, Protocol::Http1)
|
}
|
||||||
}
|
}))
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set total number of simultaneous connections per type of scheme.
|
/// Set total number of simultaneous connections per type of scheme.
|
||||||
|
|
|
@ -6,7 +6,6 @@ use serde_json::error::Error as JsonError;
|
||||||
|
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
use crate::connect::openssl::{HandshakeError, SslError};
|
use crate::connect::openssl::{HandshakeError, SslError};
|
||||||
use crate::connect::ResolveError;
|
|
||||||
|
|
||||||
use crate::http::error::{HttpError, ParseError, PayloadError};
|
use crate::http::error::{HttpError, ParseError, PayloadError};
|
||||||
use crate::http::header::HeaderValue;
|
use crate::http::header::HeaderValue;
|
||||||
|
@ -91,8 +90,9 @@ pub enum ConnectError {
|
||||||
SslHandshakeError(String),
|
SslHandshakeError(String),
|
||||||
|
|
||||||
/// Failed to resolve the hostname
|
/// Failed to resolve the hostname
|
||||||
|
#[from(ignore)]
|
||||||
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
#[display(fmt = "Failed resolving hostname: {}", _0)]
|
||||||
Resolver(ResolveError),
|
Resolver(io::Error),
|
||||||
|
|
||||||
/// No dns records
|
/// No dns records
|
||||||
#[display(fmt = "No dns records found for the input")]
|
#[display(fmt = "No dns records found for the input")]
|
||||||
|
|
|
@ -4,7 +4,7 @@ use bytes::Bytes;
|
||||||
use futures::SinkExt;
|
use futures::SinkExt;
|
||||||
|
|
||||||
use ntex::codec::{BytesCodec, Framed};
|
use ntex::codec::{BytesCodec, Framed};
|
||||||
use ntex::connect::{Connect, ResolverConfig, ResolverOpts};
|
use ntex::connect::Connect;
|
||||||
use ntex::rt::net::TcpStream;
|
use ntex::rt::net::TcpStream;
|
||||||
use ntex::server::test_server;
|
use ntex::server::test_server;
|
||||||
use ntex::service::{fn_service, Service, ServiceFactory};
|
use ntex::service::{fn_service, Service, ServiceFactory};
|
||||||
|
@ -53,14 +53,13 @@ async fn test_static_str() {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let resolver = ntex::connect::default_resolver();
|
let conn = ntex::connect::Connector::new();
|
||||||
let conn = ntex::connect::Connector::new(resolver.clone());
|
|
||||||
|
|
||||||
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
|
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
|
||||||
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
||||||
|
|
||||||
let connect = Connect::new("127.0.0.1".to_owned());
|
let connect = Connect::new("127.0.0.1".to_owned());
|
||||||
let conn = ntex::connect::Connector::new(resolver);
|
let conn = ntex::connect::Connector::new();
|
||||||
let con = conn.call(connect).await;
|
let con = conn.call(connect).await;
|
||||||
assert!(con.is_err());
|
assert!(con.is_err());
|
||||||
}
|
}
|
||||||
|
@ -75,13 +74,7 @@ async fn test_new_service() {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let resolver = ntex::connect::start_resolver(
|
let factory = ntex::connect::Connector::new();
|
||||||
ResolverConfig::default(),
|
|
||||||
ResolverOpts::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let factory = ntex::connect::Connector::new(resolver);
|
|
||||||
|
|
||||||
let conn = factory.new_service(()).await.unwrap();
|
let conn = factory.new_service(()).await.unwrap();
|
||||||
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
|
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
|
||||||
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
assert_eq!(con.peer_addr().unwrap(), srv.addr());
|
||||||
|
|
|
@ -176,7 +176,7 @@ async fn test_timeout() {
|
||||||
|
|
||||||
let connector = Connector::default()
|
let connector = Connector::default()
|
||||||
.connector(
|
.connector(
|
||||||
ntex::connect::Connector::new(ntex::connect::default_resolver())
|
ntex::connect::Connector::new()
|
||||||
.map(|sock| (sock, ntex::http::Protocol::Http1)),
|
.map(|sock| (sock, ntex::http::Protocol::Http1)),
|
||||||
)
|
)
|
||||||
.timeout(Duration::from_secs(15))
|
.timeout(Duration::from_secs(15))
|
||||||
|
|
|
@ -143,7 +143,7 @@ async fn test_chunked_payload() {
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
let _ = stream.read_to_string(&mut data);
|
let _ = stream.read_to_string(&mut data);
|
||||||
|
|
||||||
let re = Regex::new(r"size=(\d+)").unwrap();
|
let re = Regex::new(r"size=([0-9]+)").unwrap();
|
||||||
let size: usize = match re.captures(&data) {
|
let size: usize = match re.captures(&data) {
|
||||||
Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(),
|
Some(caps) => caps.get(1).unwrap().as_str().parse().unwrap(),
|
||||||
None => panic!("Failed to find size in HTTP Response: {}", data),
|
None => panic!("Failed to find size in HTTP Response: {}", data),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue