1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

add trust-dns optional feature for actix-http and awc (#1969)

This commit is contained in:
fakeshadow 2021-02-09 02:41:20 -08:00 committed by GitHub
parent dddb623a11
commit 519d7f2b8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 98 additions and 15 deletions

View File

@ -109,7 +109,6 @@ smallvec = "1.6"
[dev-dependencies] [dev-dependencies]
actix = { version = "0.11.0-beta.2", default-features = false } actix = { version = "0.11.0-beta.2", default-features = false }
actix-http = { version = "3.0.0-beta.1", features = ["actors"] }
rand = "0.8" rand = "0.8"
env_logger = "0.8" env_logger = "0.8"
serde_derive = "1.0" serde_derive = "1.0"

View File

@ -7,6 +7,7 @@
* `ResponseBuilder::append_header` method which allows using typed headers. [#1869] * `ResponseBuilder::append_header` method which allows using typed headers. [#1869]
* `TestRequest::insert_header` method which allows using typed headers. [#1869] * `TestRequest::insert_header` method which allows using typed headers. [#1869]
* `ContentEncoding` implements all necessary header traits. [#1912] * `ContentEncoding` implements all necessary header traits. [#1912]
* `trust-dns` optional feature to enable `trust-dns-resolver` as client dns resolver. [#1969]
### Changed ### Changed
* `ResponseBuilder::content_type` now takes an `impl IntoHeaderValue` to support using typed * `ResponseBuilder::content_type` now takes an `impl IntoHeaderValue` to support using typed
@ -26,6 +27,8 @@
* `ResponseBuilder::header`; use `ResponseBuilder::append_header`. [#1869] * `ResponseBuilder::header`; use `ResponseBuilder::append_header`. [#1869]
* `TestRequest::with_hdr`; use `TestRequest::default().insert_header()`. [#1869] * `TestRequest::with_hdr`; use `TestRequest::default().insert_header()`. [#1869]
* `TestRequest::with_header`; use `TestRequest::default().insert_header()`. [#1869] * `TestRequest::with_header`; use `TestRequest::default().insert_header()`. [#1869]
* `actors` optional feature. [#1969]
* `ResponseError` impl for `actix::MailboxError`. [#1969]
[#1869]: https://github.com/actix/actix-web/pull/1869 [#1869]: https://github.com/actix/actix-web/pull/1869
[#1894]: https://github.com/actix/actix-web/pull/1894 [#1894]: https://github.com/actix/actix-web/pull/1894
@ -34,6 +37,7 @@
[#1905]: https://github.com/actix/actix-web/pull/1905 [#1905]: https://github.com/actix/actix-web/pull/1905
[#1912]: https://github.com/actix/actix-web/pull/1912 [#1912]: https://github.com/actix/actix-web/pull/1912
[#1957]: https://github.com/actix/actix-web/pull/1957 [#1957]: https://github.com/actix/actix-web/pull/1957
[#1969]: https://github.com/actix/actix-web/pull/1969
## 3.0.0-beta.1 - 2021-01-07 ## 3.0.0-beta.1 - 2021-01-07

View File

@ -36,8 +36,8 @@ compress = ["flate2", "brotli2"]
# support for secure cookies # support for secure cookies
secure-cookies = ["cookie/secure"] secure-cookies = ["cookie/secure"]
# support for actix Actor messages # trust-dns as client dns resolver
actors = ["actix"] trust-dns = ["trust-dns-resolver"]
[dependencies] [dependencies]
actix-service = "2.0.0-beta.4" actix-service = "2.0.0-beta.4"
@ -45,7 +45,6 @@ actix-codec = "0.4.0-beta.1"
actix-utils = "3.0.0-beta.2" actix-utils = "3.0.0-beta.2"
actix-rt = "2" actix-rt = "2"
actix-tls = "3.0.0-beta.2" actix-tls = "3.0.0-beta.2"
actix = { version = "0.11.0-beta.2", default-features = false, optional = true }
base64 = "0.13" base64 = "0.13"
bitflags = "1.2" bitflags = "1.2"
@ -84,6 +83,8 @@ time = { version = "0.2.23", default-features = false, features = ["std"] }
brotli2 = { version="0.3.2", optional = true } brotli2 = { version="0.3.2", optional = true }
flate2 = { version = "1.0.13", optional = true } flate2 = { version = "1.0.13", optional = true }
trust-dns-resolver = { version = "0.20.0", optional = true }
[dev-dependencies] [dev-dependencies]
actix-server = "2.0.0-beta.3" actix-server = "2.0.0-beta.3"
actix-http-test = { version = "3.0.0-beta.1", features = ["openssl"] } actix-http-test = { version = "3.0.0-beta.1", features = ["openssl"] }

View File

@ -6,7 +6,7 @@ use actix_codec::{AsyncRead, AsyncWrite};
use actix_rt::net::TcpStream; use actix_rt::net::TcpStream;
use actix_service::{apply_fn, Service, ServiceExt}; use actix_service::{apply_fn, Service, ServiceExt};
use actix_tls::connect::{ use actix_tls::connect::{
default_connector, Connect as TcpConnect, Connection as TcpConnection, new_connector, Connect as TcpConnect, Connection as TcpConnection, Resolver,
}; };
use actix_utils::timeout::{TimeoutError, TimeoutService}; use actix_utils::timeout::{TimeoutError, TimeoutService};
use http::Uri; use http::Uri;
@ -19,7 +19,6 @@ use super::Connect;
#[cfg(feature = "openssl")] #[cfg(feature = "openssl")]
use actix_tls::connect::ssl::openssl::SslConnector as OpensslConnector; use actix_tls::connect::ssl::openssl::SslConnector as OpensslConnector;
#[cfg(feature = "rustls")] #[cfg(feature = "rustls")]
use actix_tls::connect::ssl::rustls::ClientConfig; use actix_tls::connect::ssl::rustls::ClientConfig;
#[cfg(feature = "rustls")] #[cfg(feature = "rustls")]
@ -70,7 +69,7 @@ impl Connector<(), ()> {
> { > {
Connector { Connector {
ssl: Self::build_ssl(vec![b"h2".to_vec(), b"http/1.1".to_vec()]), ssl: Self::build_ssl(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
connector: default_connector(), connector: new_connector(resolver::resolver()),
config: ConnectorConfig::default(), config: ConnectorConfig::default(),
_phantom: PhantomData, _phantom: PhantomData,
} }
@ -532,3 +531,82 @@ mod connect_impl {
} }
} }
} }
#[cfg(not(feature = "trust-dns"))]
mod resolver {
use super::*;
pub(super) fn resolver() -> Resolver {
Resolver::Default
}
}
#[cfg(feature = "trust-dns")]
mod resolver {
use std::{cell::RefCell, net::SocketAddr};
use actix_tls::connect::Resolve;
use futures_core::future::LocalBoxFuture;
use trust_dns_resolver::{
config::{ResolverConfig, ResolverOpts},
system_conf::read_system_conf,
TokioAsyncResolver,
};
use super::*;
pub(super) fn resolver() -> Resolver {
// new type for impl Resolve trait for TokioAsyncResolver.
struct TrustDnsResolver(TokioAsyncResolver);
impl Resolve for TrustDnsResolver {
fn lookup<'a>(
&'a self,
host: &'a str,
port: u16,
) -> LocalBoxFuture<'a, Result<Vec<SocketAddr>, Box<dyn std::error::Error>>>
{
Box::pin(async move {
let res = self
.0
.lookup_ip(host)
.await?
.iter()
.map(|ip| SocketAddr::new(ip, port))
.collect();
Ok(res)
})
}
}
// dns struct is cached in thread local.
// so new client constructor can reuse the existing dns resolver.
thread_local! {
static TRUST_DNS_RESOLVER: RefCell<Option<Resolver>> = RefCell::new(None);
}
// get from thread local or construct a new trust-dns resolver.
TRUST_DNS_RESOLVER.with(|local| {
let resolver = local.borrow().as_ref().map(Clone::clone);
match resolver {
Some(resolver) => resolver,
None => {
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 = TokioAsyncResolver::tokio(cfg, opts).unwrap();
// box trust dns resolver and put it in thread local.
let resolver = Resolver::new_custom(TrustDnsResolver(resolver));
*local.borrow_mut() = Some(resolver.clone());
resolver
}
}
})
}
}

View File

@ -968,12 +968,6 @@ where
InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into() InternalError::new(err, StatusCode::NETWORK_AUTHENTICATION_REQUIRED).into()
} }
#[cfg(feature = "actors")]
/// Returns [`StatusCode::INTERNAL_SERVER_ERROR`] for [`actix::MailboxError`].
///
/// This is only supported when the feature `actors` is enabled.
impl ResponseError for actix::MailboxError {}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -4,6 +4,7 @@
### Added ### Added
* `ClientRequest::insert_header` method which allows using typed headers. [#1869] * `ClientRequest::insert_header` method which allows using typed headers. [#1869]
* `ClientRequest::append_header` method which allows using typed headers. [#1869] * `ClientRequest::append_header` method which allows using typed headers. [#1869]
* `trust-dns` optional feature to enable `trust-dns-resolver` as client dns resolver. [#1969]
### Changed ### Changed
* Relax default timeout for `Connector` to 5 seconds(original 1 second). [#1905] * Relax default timeout for `Connector` to 5 seconds(original 1 second). [#1905]
@ -16,6 +17,7 @@
[#1869]: https://github.com/actix/actix-web/pull/1869 [#1869]: https://github.com/actix/actix-web/pull/1869
[#1905]: https://github.com/actix/actix-web/pull/1905 [#1905]: https://github.com/actix/actix-web/pull/1905
[#1969]: https://github.com/actix/actix-web/pull/1969
## 3.0.0-beta.1 - 2021-01-07 ## 3.0.0-beta.1 - 2021-01-07

View File

@ -36,6 +36,9 @@ rustls = ["tls-rustls", "actix-http/rustls"]
# content-encoding support # content-encoding support
compress = ["actix-http/compress"] compress = ["actix-http/compress"]
# trust-dns as dns resolver
trust-dns = ["actix-http/trust-dns"]
[dependencies] [dependencies]
actix-codec = "0.4.0-beta.1" actix-codec = "0.4.0-beta.1"
actix-service = "2.0.0-beta.4" actix-service = "2.0.0-beta.4"

View File

@ -1277,8 +1277,10 @@ mod tests {
async fn actor_handler( async fn actor_handler(
addr: Data<Addr<MyActor>>, addr: Data<Addr<MyActor>>,
) -> Result<impl Responder, Error> { ) -> Result<impl Responder, Error> {
// `?` operator tests "actors" feature flag on actix-http let res = addr
let res = addr.send(Num(1)).await?; .send(Num(1))
.await
.map_err(crate::error::ErrorInternalServerError)?;
if res == 1 { if res == 1 {
Ok(HttpResponse::Ok()) Ok(HttpResponse::Ok())