From 2cb2a30949d5c6d9013b0dc2d8e0036ebbb08142 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Wed, 20 Jan 2021 04:05:11 +0800 Subject: [PATCH] move actix_http::client to awc --- Cargo.toml | 4 +- actix-http/Cargo.toml | 6 +- actix-http/src/lib.rs | 2 +- awc/Cargo.toml | 19 ++-- awc/src/builder.rs | 2 +- {actix-http => awc}/src/client/config.rs | 0 {actix-http => awc}/src/client/connection.rs | 8 +- {actix-http => awc}/src/client/connector.rs | 98 +++++++++++++++++--- {actix-http => awc}/src/client/error.rs | 4 +- {actix-http => awc}/src/client/h1proto.rs | 14 +-- {actix-http => awc}/src/client/h2proto.rs | 10 +- {actix-http => awc}/src/client/mod.rs | 0 {actix-http => awc}/src/client/pool.rs | 2 +- awc/src/connect.rs | 6 +- awc/src/connector.rs | 82 ---------------- awc/src/error.rs | 2 +- awc/src/lib.rs | 9 +- awc/tests/test_client.rs | 1 - 18 files changed, 132 insertions(+), 137 deletions(-) rename {actix-http => awc}/src/client/config.rs (100%) rename {actix-http => awc}/src/client/connection.rs (98%) rename {actix-http => awc}/src/client/connector.rs (86%) rename {actix-http => awc}/src/client/error.rs (97%) rename {actix-http => awc}/src/client/h1proto.rs (96%) rename {actix-http => awc}/src/client/h2proto.rs (96%) rename {actix-http => awc}/src/client/mod.rs (100%) rename {actix-http => awc}/src/client/pool.rs (99%) delete mode 100644 awc/src/connector.rs diff --git a/Cargo.toml b/Cargo.toml index be08a3c39..063d007b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,10 +47,10 @@ compress = ["actix-http/compress", "awc/compress"] secure-cookies = ["actix-http/secure-cookies"] # openssl -openssl = ["actix-tls/accept", "actix-tls/openssl", "awc/openssl", "open-ssl"] +openssl = ["actix-http/openssl", "awc/openssl", "actix-tls/accept", "open-ssl"] # rustls -rustls = ["actix-tls/accept", "actix-tls/rustls", "awc/rustls", "rust-tls"] +rustls = ["actix-http/rustls", "awc/rustls", "actix-tls/accept", "rust-tls"] [[example]] name = "basic" diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index af6209248..fa258748c 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -44,7 +44,7 @@ actix-service = "2.0.0-beta.3" actix-codec = "0.4.0-beta.1" actix-utils = "3.0.0-beta.1" actix-rt = "2.0.0-beta.2" -actix-tls = "3.0.0-beta.2" +actix-tls = { version = "3.0.0-beta.2", default-features = false, features = ["accept", "uri"] } actix = { version = "0.11.0-beta.1", optional = true } base64 = "0.13" @@ -55,9 +55,9 @@ cookie = { version = "0.14.1", features = ["percent-encode"] } derive_more = "0.99.5" either = "1.5.3" encoding_rs = "0.8" -futures-channel = { version = "0.3.7", default-features = false } +futures-channel = { version = "0.3.7", default-features = false, features = ["alloc"] } futures-core = { version = "0.3.7", default-features = false } -futures-util = { version = "0.3.7", default-features = false, features = ["sink"] } +futures-util = { version = "0.3.7", default-features = false, features = ["alloc", "sink"] } ahash = "0.6" h2 = "0.3.0" http = "0.2.2" diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs index cc99130eb..fa204418d 100644 --- a/actix-http/src/lib.rs +++ b/actix-http/src/lib.rs @@ -18,7 +18,6 @@ mod macros; pub mod body; mod builder; -pub mod client; mod config; #[cfg(feature = "compress")] pub mod encoding; @@ -45,6 +44,7 @@ pub use self::builder::HttpServiceBuilder; pub use self::config::{KeepAlive, ServiceConfig}; pub use self::error::{Error, ResponseError, Result}; pub use self::extensions::Extensions; +pub use self::header::HeaderMap; pub use self::httpmessage::HttpMessage; pub use self::message::{Message, RequestHead, RequestHeadType, ResponseHead}; pub use self::payload::{Payload, PayloadStream}; diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 920e24a34..920e55d56 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -28,10 +28,10 @@ features = ["openssl", "rustls", "compress"] default = ["compress"] # openssl -openssl = ["open-ssl", "actix-http/openssl"] +openssl = ["open-ssl", "actix-tls/openssl"] # rustls -rustls = ["rust-tls", "actix-http/rustls"] +rustls = ["rust-tls", "actix-tls/rustls"] # content-encoding support compress = ["actix-http/compress"] @@ -44,15 +44,19 @@ actix-codec = "0.4.0-beta.1" actix-service = "2.0.0-beta.3" actix-http = "3.0.0-beta.1" actix-rt = "2.0.0-beta.2" +actix-tls = { version = "3.0.0-beta.2", default-features = false, features = ["connect", "uri"] } +actix-utils = "3.0.0-beta.1" -# TODO: temporary import actix-tls to bypass some actix-http mods -actix-tls = { version = "3.0.0-beta.2", default-features = false, features = ["connect"] } - +ahash = "0.6" base64 = "0.13" bytes = "1" cfg-if = "1.0" derive_more = "0.99.5" -futures-core = { version = "0.3.7", default-features = false } +futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } +futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } +h2 = "0.3" +http = "0.2.3" +indexmap = "1.6" log =" 0.4" mime = "0.3" percent-encoding = "2.1" @@ -60,8 +64,11 @@ rand = "0.8" serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" +slab = "0.4" open-ssl = { version = "0.10", package = "openssl", optional = true } +pin-project = "1" rust-tls = { version = "0.19.0", package = "rustls", optional = true, features = ["dangerous_configuration"] } +tokio = { version = "1", features = ["sync"] } trust-dns-resolver = { version = "0.20.0", default-features = false, optional = true } [dev-dependencies] diff --git a/awc/src/builder.rs b/awc/src/builder.rs index 351a493af..6cb87b0a5 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -4,10 +4,10 @@ use std::fmt; use std::rc::Rc; use std::time::Duration; -use actix_http::client::{Connect as HttpConnect, ConnectError, Connection, Connector}; use actix_http::http::{self, header, Error as HttpError, HeaderMap, HeaderName}; use actix_service::Service; +use crate::client::{Connect as HttpConnect, ConnectError, Connection, Connector}; use crate::connect::{Connect, ConnectorWrapper}; use crate::{Client, ClientConfig}; diff --git a/actix-http/src/client/config.rs b/awc/src/client/config.rs similarity index 100% rename from actix-http/src/client/config.rs rename to awc/src/client/config.rs diff --git a/actix-http/src/client/connection.rs b/awc/src/client/connection.rs similarity index 98% rename from actix-http/src/client/connection.rs rename to awc/src/client/connection.rs index d22f2c7ac..b071888e3 100644 --- a/actix-http/src/client/connection.rs +++ b/awc/src/client/connection.rs @@ -9,10 +9,10 @@ use futures_util::future::{err, Either, FutureExt, LocalBoxFuture, Ready}; use h2::client::SendRequest; use pin_project::pin_project; -use crate::body::MessageBody; -use crate::h1::ClientCodec; -use crate::message::{RequestHeadType, ResponseHead}; -use crate::payload::Payload; +use actix_http::body::MessageBody; +use actix_http::h1::ClientCodec; +use actix_http::Payload; +use actix_http::{RequestHeadType, ResponseHead}; use super::error::SendRequestError; use super::pool::{Acquired, Protocol}; diff --git a/actix-http/src/client/connector.rs b/awc/src/client/connector.rs similarity index 86% rename from actix-http/src/client/connector.rs rename to awc/src/client/connector.rs index 326a2fc60..ba9ab1b1d 100644 --- a/actix-http/src/client/connector.rs +++ b/awc/src/client/connector.rs @@ -1,13 +1,9 @@ -use std::fmt; -use std::marker::PhantomData; -use std::time::Duration; +use std::{fmt, marker::PhantomData, time::Duration}; use actix_codec::{AsyncRead, AsyncWrite}; use actix_rt::net::TcpStream; use actix_service::{apply_fn, Service, ServiceExt}; -use actix_tls::connect::{ - default_connector, Connect as TcpConnect, Connection as TcpConnection, -}; +use actix_tls::connect::{Connect as TcpConnect, Connection as TcpConnection}; use actix_utils::timeout::{TimeoutError, TimeoutService}; use http::Uri; @@ -22,15 +18,13 @@ use actix_tls::connect::ssl::openssl::SslConnector as OpensslConnector; #[cfg(feature = "rustls")] use actix_tls::connect::ssl::rustls::ClientConfig; -#[cfg(feature = "rustls")] -use std::sync::Arc; #[cfg(any(feature = "openssl", feature = "rustls"))] enum SslConnector { #[cfg(feature = "openssl")] Openssl(OpensslConnector), #[cfg(feature = "rustls")] - Rustls(Arc), + Rustls(std::sync::Arc), } #[cfg(not(any(feature = "openssl", feature = "rustls")))] type SslConnector = (); @@ -70,7 +64,7 @@ impl Connector<(), ()> { > { Connector { ssl: Self::build_ssl(vec![b"h2".to_vec(), b"http/1.1".to_vec()]), - connector: default_connector(), + connector: connector_impl::default_connector(), config: ConnectorConfig::default(), _phantom: PhantomData, } @@ -91,7 +85,7 @@ impl Connector<(), ()> { let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap(); let _ = ssl .set_alpn_protos(&alpn) - .map_err(|e| error!("Can not set alpn protocol: {:?}", e)); + .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e)); SslConnector::Openssl(ssl.build()) } @@ -103,7 +97,7 @@ impl Connector<(), ()> { config .root_store .add_server_trust_anchors(&actix_tls::accept::rustls::TLS_SERVER_ROOTS); - SslConnector::Rustls(Arc::new(config)) + SslConnector::Rustls(std::sync::Arc::new(config)) } // ssl turned off, provides empty ssl connector @@ -156,7 +150,7 @@ where } #[cfg(feature = "rustls")] - pub fn rustls(mut self, connector: Arc) -> Self { + pub fn rustls(mut self, connector: std::sync::Arc) -> Self { self.ssl = SslConnector::Rustls(connector); self } @@ -532,3 +526,81 @@ mod connect_impl { } } } + +#[cfg(not(feature = "trust-dns"))] +mod connector_impl { + pub use actix_tls::connect::default_connector; +} + +// resolver implementation using trust-dns crate. +#[cfg(feature = "trust-dns")] +mod connector_impl { + use std::net::SocketAddr; + + use actix_rt::{net::TcpStream, Arbiter}; + use actix_service::Service; + use actix_tls::connect::{ + Address, Connect, ConnectError, Connection, Resolve, Resolver, + }; + use futures_core::future::LocalBoxFuture; + use trust_dns_resolver::{ + config::{ResolverConfig, ResolverOpts}, + system_conf::read_system_conf, + TokioAsyncResolver, + }; + + pub struct TrustDnsResolver { + resolver: TokioAsyncResolver, + } + + impl TrustDnsResolver { + fn new() -> Self { + // dns struct is cached in Arbiter thread local map. + // so new client constructor can reuse the dns resolver on local thread. + + if Arbiter::contains_item::() { + Arbiter::get_item(|item: &TokioAsyncResolver| TrustDnsResolver { + resolver: item.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 = TokioAsyncResolver::tokio(cfg, opts).unwrap(); + Arbiter::set_item(resolver.clone()); + TrustDnsResolver { resolver } + } + } + } + + impl Resolve for TrustDnsResolver { + fn lookup<'a>( + &'a self, + host: &'a str, + port: u16, + ) -> LocalBoxFuture<'a, Result, Box>> + { + Box::pin(async move { + let res = self + .resolver + .lookup_ip(host) + .await? + .iter() + .map(|ip| SocketAddr::new(ip, port)) + .collect(); + Ok(res) + }) + } + } + + pub fn default_connector( + ) -> impl Service, Response = Connection, Error = ConnectError> + + Clone { + actix_tls::connect::new_connector(Resolver::new_custom(TrustDnsResolver::new())) + } +} diff --git a/actix-http/src/client/error.rs b/awc/src/client/error.rs similarity index 97% rename from actix-http/src/client/error.rs rename to awc/src/client/error.rs index 8d609f546..217f89e7d 100644 --- a/actix-http/src/client/error.rs +++ b/awc/src/client/error.rs @@ -5,8 +5,8 @@ use derive_more::{Display, From}; #[cfg(feature = "openssl")] use actix_tls::accept::openssl::SslError; -use crate::error::{Error, ParseError, ResponseError}; -use crate::http::{Error as HttpError, StatusCode}; +use actix_http::error::{Error, ParseError, ResponseError}; +use actix_http::http::{Error as HttpError, StatusCode}; /// A set of errors that can occur while connecting to an HTTP host #[derive(Debug, Display, From)] diff --git a/actix-http/src/client/h1proto.rs b/awc/src/client/h1proto.rs similarity index 96% rename from actix-http/src/client/h1proto.rs rename to awc/src/client/h1proto.rs index 24f4207e8..ff5b8e4cc 100644 --- a/actix-http/src/client/h1proto.rs +++ b/awc/src/client/h1proto.rs @@ -10,17 +10,17 @@ use futures_core::Stream; use futures_util::future::poll_fn; use futures_util::{pin_mut, SinkExt, StreamExt}; -use crate::error::PayloadError; -use crate::h1; -use crate::header::HeaderMap; -use crate::http::header::{IntoHeaderValue, HOST}; -use crate::message::{RequestHeadType, ResponseHead}; -use crate::payload::{Payload, PayloadStream}; +use actix_http::body::{BodySize, MessageBody}; +use actix_http::error::PayloadError; +use actix_http::h1; +use actix_http::http::header::{IntoHeaderValue, HOST}; +use actix_http::HeaderMap; +use actix_http::{Payload, PayloadStream}; +use actix_http::{RequestHeadType, ResponseHead}; use super::connection::{ConnectionLifetime, ConnectionType, IoConnection}; use super::error::{ConnectError, SendRequestError}; use super::pool::Acquired; -use crate::body::{BodySize, MessageBody}; pub(crate) async fn send_request( io: T, diff --git a/actix-http/src/client/h2proto.rs b/awc/src/client/h2proto.rs similarity index 96% rename from actix-http/src/client/h2proto.rs rename to awc/src/client/h2proto.rs index 76915f214..939665b2c 100644 --- a/actix-http/src/client/h2proto.rs +++ b/awc/src/client/h2proto.rs @@ -13,10 +13,10 @@ use h2::{ use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING}; use http::{request::Request, Method, Version}; -use crate::body::{BodySize, MessageBody}; -use crate::header::HeaderMap; -use crate::message::{RequestHeadType, ResponseHead}; -use crate::payload::Payload; +use actix_http::body::{BodySize, MessageBody}; +use actix_http::HeaderMap; +use actix_http::Payload; +use actix_http::{RequestHeadType, ResponseHead}; use super::config::ConnectorConfig; use super::connection::{ConnectionType, IoConnection}; @@ -34,7 +34,7 @@ where T: AsyncRead + AsyncWrite + Unpin + 'static, B: MessageBody, { - trace!("Sending client request: {:?} {:?}", head, body.size()); + log::trace!("Sending client request: {:?} {:?}", head, body.size()); let head_req = head.as_ref().method == Method::HEAD; let length = body.size(); let eof = matches!( diff --git a/actix-http/src/client/mod.rs b/awc/src/client/mod.rs similarity index 100% rename from actix-http/src/client/mod.rs rename to awc/src/client/mod.rs diff --git a/actix-http/src/client/pool.rs b/awc/src/client/pool.rs similarity index 99% rename from actix-http/src/client/pool.rs rename to awc/src/client/pool.rs index af862cdd7..41579a541 100644 --- a/actix-http/src/client/pool.rs +++ b/awc/src/client/pool.rs @@ -12,13 +12,13 @@ use actix_service::Service; use actix_utils::task::LocalWaker; use ahash::AHashMap; use bytes::Bytes; -use futures_channel::oneshot; use futures_util::future::{poll_fn, FutureExt, LocalBoxFuture}; use h2::client::{Connection, SendRequest}; use http::uri::Authority; use indexmap::IndexSet; use pin_project::pin_project; use slab::Slab; +use tokio::sync::oneshot; use super::config::ConnectorConfig; use super::connection::{ConnectionType, IoConnection}; diff --git a/awc/src/connect.rs b/awc/src/connect.rs index 8ee239f76..aa04ab864 100644 --- a/awc/src/connect.rs +++ b/awc/src/connect.rs @@ -6,14 +6,14 @@ use std::{fmt, io, net}; use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf}; use actix_http::body::Body; -use actix_http::client::{ - Connect as ClientConnect, ConnectError, Connection, SendRequestError, -}; use actix_http::h1::ClientCodec; use actix_http::http::HeaderMap; use actix_http::{RequestHead, RequestHeadType, ResponseHead}; use actix_service::Service; +use crate::client::{ + Connect as ClientConnect, ConnectError, Connection, SendRequestError, +}; use crate::response::ClientResponse; pub(crate) struct ConnectorWrapper(pub T); diff --git a/awc/src/connector.rs b/awc/src/connector.rs deleted file mode 100644 index aad41d938..000000000 --- a/awc/src/connector.rs +++ /dev/null @@ -1,82 +0,0 @@ -// TODO: this mod bypass actix-http and use actix_tls::connect directly. -// Future refactor should change this mod if actix-http still used as upstream dep of awc. - -pub use connector_impl::*; - -#[cfg(not(feature = "trust-dns"))] -mod connector_impl { - pub use actix_tls::connect::default_connector; -} - -#[cfg(feature = "trust-dns")] -mod connector_impl { - // resolver implementation using trust-dns crate. - use std::net::SocketAddr; - - use actix_rt::{net::TcpStream, Arbiter}; - use actix_service::Service; - use actix_tls::connect::{ - Address, Connect, ConnectError, Connection, Resolve, Resolver, - }; - use futures_core::future::LocalBoxFuture; - use trust_dns_resolver::{ - config::{ResolverConfig, ResolverOpts}, - system_conf::read_system_conf, - TokioAsyncResolver, - }; - - pub struct TrustDnsResolver { - resolver: TokioAsyncResolver, - } - - impl TrustDnsResolver { - fn new() -> Self { - // dns struct is cached in Arbiter thread local map. - // so new client constructor can reuse the dns resolver on local thread. - - if Arbiter::contains_item::() { - Arbiter::get_item(|item: &TokioAsyncResolver| TrustDnsResolver { - resolver: item.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 = TokioAsyncResolver::tokio(cfg, opts).unwrap(); - Arbiter::set_item(resolver.clone()); - TrustDnsResolver { resolver } - } - } - } - - impl Resolve for TrustDnsResolver { - fn lookup<'a>( - &'a self, - host: &'a str, - port: u16, - ) -> LocalBoxFuture<'a, Result, Box>> - { - Box::pin(async move { - let res = self - .resolver - .lookup_ip(host) - .await? - .iter() - .map(|ip| SocketAddr::new(ip, port)) - .collect(); - Ok(res) - }) - } - } - - pub fn default_connector( - ) -> impl Service, Response = Connection, Error = ConnectError> - + Clone { - actix_tls::connect::new_connector(Resolver::new_custom(TrustDnsResolver::new())) - } -} diff --git a/awc/src/error.rs b/awc/src/error.rs index d008166d9..73ec66a86 100644 --- a/awc/src/error.rs +++ b/awc/src/error.rs @@ -1,5 +1,5 @@ //! Http client errors -pub use actix_http::client::{ +pub use crate::client::{ ConnectError, FreezeRequestError, InvalidUrl, SendRequestError, }; pub use actix_http::error::PayloadError; diff --git a/awc/src/lib.rs b/awc/src/lib.rs index 31569e32e..fc9e23da4 100644 --- a/awc/src/lib.rs +++ b/awc/src/lib.rs @@ -98,14 +98,15 @@ use std::convert::TryFrom; use std::rc::Rc; use std::time::Duration; -pub use actix_http::{client::Connector, cookie, http}; +pub use crate::client::Connector; +pub use actix_http::{cookie, http}; use actix_http::http::{Error as HttpError, HeaderMap, Method, Uri}; use actix_http::RequestHead; mod builder; +mod client; mod connect; -pub mod connector; pub mod error; mod frozen; mod request; @@ -155,9 +156,7 @@ impl Default for Client { fn default() -> Self { Client(Rc::new(ClientConfig { connector: RefCell::new(Box::new(ConnectorWrapper( - Connector::new() - .connector(connector::default_connector()) - .finish(), + Connector::new().finish(), ))), headers: HeaderMap::new(), timeout: Some(Duration::from_secs(5)), diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index e2bcb079c..efcf0f591 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -120,7 +120,6 @@ async fn test_timeout() { }); let connector = awc::Connector::new() - .connector(awc::connector::default_connector()) .timeout(Duration::from_secs(15)) .finish();