mirror of https://github.com/fafhrd91/actix-web
move actix_http::client to awc
This commit is contained in:
parent
4d688ae921
commit
2cb2a30949
|
@ -47,10 +47,10 @@ compress = ["actix-http/compress", "awc/compress"]
|
||||||
secure-cookies = ["actix-http/secure-cookies"]
|
secure-cookies = ["actix-http/secure-cookies"]
|
||||||
|
|
||||||
# openssl
|
# 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
|
||||||
rustls = ["actix-tls/accept", "actix-tls/rustls", "awc/rustls", "rust-tls"]
|
rustls = ["actix-http/rustls", "awc/rustls", "actix-tls/accept", "rust-tls"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "basic"
|
name = "basic"
|
||||||
|
|
|
@ -44,7 +44,7 @@ actix-service = "2.0.0-beta.3"
|
||||||
actix-codec = "0.4.0-beta.1"
|
actix-codec = "0.4.0-beta.1"
|
||||||
actix-utils = "3.0.0-beta.1"
|
actix-utils = "3.0.0-beta.1"
|
||||||
actix-rt = "2.0.0-beta.2"
|
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 }
|
actix = { version = "0.11.0-beta.1", optional = true }
|
||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
@ -55,9 +55,9 @@ cookie = { version = "0.14.1", features = ["percent-encode"] }
|
||||||
derive_more = "0.99.5"
|
derive_more = "0.99.5"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
encoding_rs = "0.8"
|
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-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"
|
ahash = "0.6"
|
||||||
h2 = "0.3.0"
|
h2 = "0.3.0"
|
||||||
http = "0.2.2"
|
http = "0.2.2"
|
||||||
|
|
|
@ -18,7 +18,6 @@ mod macros;
|
||||||
|
|
||||||
pub mod body;
|
pub mod body;
|
||||||
mod builder;
|
mod builder;
|
||||||
pub mod client;
|
|
||||||
mod config;
|
mod config;
|
||||||
#[cfg(feature = "compress")]
|
#[cfg(feature = "compress")]
|
||||||
pub mod encoding;
|
pub mod encoding;
|
||||||
|
@ -45,6 +44,7 @@ pub use self::builder::HttpServiceBuilder;
|
||||||
pub use self::config::{KeepAlive, ServiceConfig};
|
pub use self::config::{KeepAlive, ServiceConfig};
|
||||||
pub use self::error::{Error, ResponseError, Result};
|
pub use self::error::{Error, ResponseError, Result};
|
||||||
pub use self::extensions::Extensions;
|
pub use self::extensions::Extensions;
|
||||||
|
pub use self::header::HeaderMap;
|
||||||
pub use self::httpmessage::HttpMessage;
|
pub use self::httpmessage::HttpMessage;
|
||||||
pub use self::message::{Message, RequestHead, RequestHeadType, ResponseHead};
|
pub use self::message::{Message, RequestHead, RequestHeadType, ResponseHead};
|
||||||
pub use self::payload::{Payload, PayloadStream};
|
pub use self::payload::{Payload, PayloadStream};
|
||||||
|
|
|
@ -28,10 +28,10 @@ features = ["openssl", "rustls", "compress"]
|
||||||
default = ["compress"]
|
default = ["compress"]
|
||||||
|
|
||||||
# openssl
|
# openssl
|
||||||
openssl = ["open-ssl", "actix-http/openssl"]
|
openssl = ["open-ssl", "actix-tls/openssl"]
|
||||||
|
|
||||||
# rustls
|
# rustls
|
||||||
rustls = ["rust-tls", "actix-http/rustls"]
|
rustls = ["rust-tls", "actix-tls/rustls"]
|
||||||
|
|
||||||
# content-encoding support
|
# content-encoding support
|
||||||
compress = ["actix-http/compress"]
|
compress = ["actix-http/compress"]
|
||||||
|
@ -44,15 +44,19 @@ actix-codec = "0.4.0-beta.1"
|
||||||
actix-service = "2.0.0-beta.3"
|
actix-service = "2.0.0-beta.3"
|
||||||
actix-http = "3.0.0-beta.1"
|
actix-http = "3.0.0-beta.1"
|
||||||
actix-rt = "2.0.0-beta.2"
|
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
|
ahash = "0.6"
|
||||||
actix-tls = { version = "3.0.0-beta.2", default-features = false, features = ["connect"] }
|
|
||||||
|
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
cfg-if = "1.0"
|
cfg-if = "1.0"
|
||||||
derive_more = "0.99.5"
|
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"
|
log =" 0.4"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
|
@ -60,8 +64,11 @@ rand = "0.8"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_urlencoded = "0.7"
|
serde_urlencoded = "0.7"
|
||||||
|
slab = "0.4"
|
||||||
open-ssl = { version = "0.10", package = "openssl", optional = true }
|
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"] }
|
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 }
|
trust-dns-resolver = { version = "0.20.0", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -4,10 +4,10 @@ use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
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_http::http::{self, header, Error as HttpError, HeaderMap, HeaderName};
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
|
|
||||||
|
use crate::client::{Connect as HttpConnect, ConnectError, Connection, Connector};
|
||||||
use crate::connect::{Connect, ConnectorWrapper};
|
use crate::connect::{Connect, ConnectorWrapper};
|
||||||
use crate::{Client, ClientConfig};
|
use crate::{Client, ClientConfig};
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ use futures_util::future::{err, Either, FutureExt, LocalBoxFuture, Ready};
|
||||||
use h2::client::SendRequest;
|
use h2::client::SendRequest;
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
|
|
||||||
use crate::body::MessageBody;
|
use actix_http::body::MessageBody;
|
||||||
use crate::h1::ClientCodec;
|
use actix_http::h1::ClientCodec;
|
||||||
use crate::message::{RequestHeadType, ResponseHead};
|
use actix_http::Payload;
|
||||||
use crate::payload::Payload;
|
use actix_http::{RequestHeadType, ResponseHead};
|
||||||
|
|
||||||
use super::error::SendRequestError;
|
use super::error::SendRequestError;
|
||||||
use super::pool::{Acquired, Protocol};
|
use super::pool::{Acquired, Protocol};
|
|
@ -1,13 +1,9 @@
|
||||||
use std::fmt;
|
use std::{fmt, marker::PhantomData, time::Duration};
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
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::{Connect as TcpConnect, Connection as TcpConnection};
|
||||||
default_connector, Connect as TcpConnect, Connection as TcpConnection,
|
|
||||||
};
|
|
||||||
use actix_utils::timeout::{TimeoutError, TimeoutService};
|
use actix_utils::timeout::{TimeoutError, TimeoutService};
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
|
|
||||||
|
@ -22,15 +18,13 @@ 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")]
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
#[cfg(any(feature = "openssl", feature = "rustls"))]
|
||||||
enum SslConnector {
|
enum SslConnector {
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
Openssl(OpensslConnector),
|
Openssl(OpensslConnector),
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
Rustls(Arc<ClientConfig>),
|
Rustls(std::sync::Arc<ClientConfig>),
|
||||||
}
|
}
|
||||||
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
|
#[cfg(not(any(feature = "openssl", feature = "rustls")))]
|
||||||
type SslConnector = ();
|
type SslConnector = ();
|
||||||
|
@ -70,7 +64,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: connector_impl::default_connector(),
|
||||||
config: ConnectorConfig::default(),
|
config: ConnectorConfig::default(),
|
||||||
_phantom: PhantomData,
|
_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
|
@ -91,7 +85,7 @@ impl Connector<(), ()> {
|
||||||
let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap();
|
let mut ssl = OpensslConnector::builder(SslMethod::tls()).unwrap();
|
||||||
let _ = ssl
|
let _ = ssl
|
||||||
.set_alpn_protos(&alpn)
|
.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())
|
SslConnector::Openssl(ssl.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +97,7 @@ impl Connector<(), ()> {
|
||||||
config
|
config
|
||||||
.root_store
|
.root_store
|
||||||
.add_server_trust_anchors(&actix_tls::accept::rustls::TLS_SERVER_ROOTS);
|
.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
|
// ssl turned off, provides empty ssl connector
|
||||||
|
@ -156,7 +150,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rustls")]
|
#[cfg(feature = "rustls")]
|
||||||
pub fn rustls(mut self, connector: Arc<ClientConfig>) -> Self {
|
pub fn rustls(mut self, connector: std::sync::Arc<ClientConfig>) -> Self {
|
||||||
self.ssl = SslConnector::Rustls(connector);
|
self.ssl = SslConnector::Rustls(connector);
|
||||||
self
|
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::<TokioAsyncResolver>() {
|
||||||
|
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<Vec<SocketAddr>, Box<dyn std::error::Error>>>
|
||||||
|
{
|
||||||
|
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<T: Address + 'static>(
|
||||||
|
) -> impl Service<Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
|
||||||
|
+ Clone {
|
||||||
|
actix_tls::connect::new_connector(Resolver::new_custom(TrustDnsResolver::new()))
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,8 +5,8 @@ use derive_more::{Display, From};
|
||||||
#[cfg(feature = "openssl")]
|
#[cfg(feature = "openssl")]
|
||||||
use actix_tls::accept::openssl::SslError;
|
use actix_tls::accept::openssl::SslError;
|
||||||
|
|
||||||
use crate::error::{Error, ParseError, ResponseError};
|
use actix_http::error::{Error, ParseError, ResponseError};
|
||||||
use crate::http::{Error as HttpError, StatusCode};
|
use actix_http::http::{Error as HttpError, StatusCode};
|
||||||
|
|
||||||
/// A set of errors that can occur while connecting to an HTTP host
|
/// A set of errors that can occur while connecting to an HTTP host
|
||||||
#[derive(Debug, Display, From)]
|
#[derive(Debug, Display, From)]
|
|
@ -10,17 +10,17 @@ use futures_core::Stream;
|
||||||
use futures_util::future::poll_fn;
|
use futures_util::future::poll_fn;
|
||||||
use futures_util::{pin_mut, SinkExt, StreamExt};
|
use futures_util::{pin_mut, SinkExt, StreamExt};
|
||||||
|
|
||||||
use crate::error::PayloadError;
|
use actix_http::body::{BodySize, MessageBody};
|
||||||
use crate::h1;
|
use actix_http::error::PayloadError;
|
||||||
use crate::header::HeaderMap;
|
use actix_http::h1;
|
||||||
use crate::http::header::{IntoHeaderValue, HOST};
|
use actix_http::http::header::{IntoHeaderValue, HOST};
|
||||||
use crate::message::{RequestHeadType, ResponseHead};
|
use actix_http::HeaderMap;
|
||||||
use crate::payload::{Payload, PayloadStream};
|
use actix_http::{Payload, PayloadStream};
|
||||||
|
use actix_http::{RequestHeadType, ResponseHead};
|
||||||
|
|
||||||
use super::connection::{ConnectionLifetime, ConnectionType, IoConnection};
|
use super::connection::{ConnectionLifetime, ConnectionType, IoConnection};
|
||||||
use super::error::{ConnectError, SendRequestError};
|
use super::error::{ConnectError, SendRequestError};
|
||||||
use super::pool::Acquired;
|
use super::pool::Acquired;
|
||||||
use crate::body::{BodySize, MessageBody};
|
|
||||||
|
|
||||||
pub(crate) async fn send_request<T, B>(
|
pub(crate) async fn send_request<T, B>(
|
||||||
io: T,
|
io: T,
|
|
@ -13,10 +13,10 @@ use h2::{
|
||||||
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
|
use http::header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING};
|
||||||
use http::{request::Request, Method, Version};
|
use http::{request::Request, Method, Version};
|
||||||
|
|
||||||
use crate::body::{BodySize, MessageBody};
|
use actix_http::body::{BodySize, MessageBody};
|
||||||
use crate::header::HeaderMap;
|
use actix_http::HeaderMap;
|
||||||
use crate::message::{RequestHeadType, ResponseHead};
|
use actix_http::Payload;
|
||||||
use crate::payload::Payload;
|
use actix_http::{RequestHeadType, ResponseHead};
|
||||||
|
|
||||||
use super::config::ConnectorConfig;
|
use super::config::ConnectorConfig;
|
||||||
use super::connection::{ConnectionType, IoConnection};
|
use super::connection::{ConnectionType, IoConnection};
|
||||||
|
@ -34,7 +34,7 @@ where
|
||||||
T: AsyncRead + AsyncWrite + Unpin + 'static,
|
T: AsyncRead + AsyncWrite + Unpin + 'static,
|
||||||
B: MessageBody,
|
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 head_req = head.as_ref().method == Method::HEAD;
|
||||||
let length = body.size();
|
let length = body.size();
|
||||||
let eof = matches!(
|
let eof = matches!(
|
|
@ -12,13 +12,13 @@ use actix_service::Service;
|
||||||
use actix_utils::task::LocalWaker;
|
use actix_utils::task::LocalWaker;
|
||||||
use ahash::AHashMap;
|
use ahash::AHashMap;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures_channel::oneshot;
|
|
||||||
use futures_util::future::{poll_fn, FutureExt, LocalBoxFuture};
|
use futures_util::future::{poll_fn, FutureExt, LocalBoxFuture};
|
||||||
use h2::client::{Connection, SendRequest};
|
use h2::client::{Connection, SendRequest};
|
||||||
use http::uri::Authority;
|
use http::uri::Authority;
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
use super::config::ConnectorConfig;
|
use super::config::ConnectorConfig;
|
||||||
use super::connection::{ConnectionType, IoConnection};
|
use super::connection::{ConnectionType, IoConnection};
|
|
@ -6,14 +6,14 @@ use std::{fmt, io, net};
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf};
|
use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf};
|
||||||
use actix_http::body::Body;
|
use actix_http::body::Body;
|
||||||
use actix_http::client::{
|
|
||||||
Connect as ClientConnect, ConnectError, Connection, SendRequestError,
|
|
||||||
};
|
|
||||||
use actix_http::h1::ClientCodec;
|
use actix_http::h1::ClientCodec;
|
||||||
use actix_http::http::HeaderMap;
|
use actix_http::http::HeaderMap;
|
||||||
use actix_http::{RequestHead, RequestHeadType, ResponseHead};
|
use actix_http::{RequestHead, RequestHeadType, ResponseHead};
|
||||||
use actix_service::Service;
|
use actix_service::Service;
|
||||||
|
|
||||||
|
use crate::client::{
|
||||||
|
Connect as ClientConnect, ConnectError, Connection, SendRequestError,
|
||||||
|
};
|
||||||
use crate::response::ClientResponse;
|
use crate::response::ClientResponse;
|
||||||
|
|
||||||
pub(crate) struct ConnectorWrapper<T>(pub T);
|
pub(crate) struct ConnectorWrapper<T>(pub T);
|
||||||
|
|
|
@ -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::<TokioAsyncResolver>() {
|
|
||||||
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<Vec<SocketAddr>, Box<dyn std::error::Error>>>
|
|
||||||
{
|
|
||||||
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<T: Address + 'static>(
|
|
||||||
) -> impl Service<Connect<T>, Response = Connection<T, TcpStream>, Error = ConnectError>
|
|
||||||
+ Clone {
|
|
||||||
actix_tls::connect::new_connector(Resolver::new_custom(TrustDnsResolver::new()))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
//! Http client errors
|
//! Http client errors
|
||||||
pub use actix_http::client::{
|
pub use crate::client::{
|
||||||
ConnectError, FreezeRequestError, InvalidUrl, SendRequestError,
|
ConnectError, FreezeRequestError, InvalidUrl, SendRequestError,
|
||||||
};
|
};
|
||||||
pub use actix_http::error::PayloadError;
|
pub use actix_http::error::PayloadError;
|
||||||
|
|
|
@ -98,14 +98,15 @@ use std::convert::TryFrom;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::time::Duration;
|
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::http::{Error as HttpError, HeaderMap, Method, Uri};
|
||||||
use actix_http::RequestHead;
|
use actix_http::RequestHead;
|
||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
|
mod client;
|
||||||
mod connect;
|
mod connect;
|
||||||
pub mod connector;
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod frozen;
|
mod frozen;
|
||||||
mod request;
|
mod request;
|
||||||
|
@ -155,9 +156,7 @@ impl Default for Client {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Client(Rc::new(ClientConfig {
|
Client(Rc::new(ClientConfig {
|
||||||
connector: RefCell::new(Box::new(ConnectorWrapper(
|
connector: RefCell::new(Box::new(ConnectorWrapper(
|
||||||
Connector::new()
|
Connector::new().finish(),
|
||||||
.connector(connector::default_connector())
|
|
||||||
.finish(),
|
|
||||||
))),
|
))),
|
||||||
headers: HeaderMap::new(),
|
headers: HeaderMap::new(),
|
||||||
timeout: Some(Duration::from_secs(5)),
|
timeout: Some(Duration::from_secs(5)),
|
||||||
|
|
|
@ -120,7 +120,6 @@ async fn test_timeout() {
|
||||||
});
|
});
|
||||||
|
|
||||||
let connector = awc::Connector::new()
|
let connector = awc::Connector::new()
|
||||||
.connector(awc::connector::default_connector())
|
|
||||||
.timeout(Duration::from_secs(15))
|
.timeout(Duration::from_secs(15))
|
||||||
.finish();
|
.finish();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue