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"]
|
||||
|
||||
# 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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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};
|
|
@ -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<ClientConfig>),
|
||||
Rustls(std::sync::Arc<ClientConfig>),
|
||||
}
|
||||
#[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<ClientConfig>) -> Self {
|
||||
pub fn rustls(mut self, connector: std::sync::Arc<ClientConfig>) -> 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::<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")]
|
||||
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)]
|
|
@ -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<T, B>(
|
||||
io: T,
|
|
@ -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!(
|
|
@ -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};
|
|
@ -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<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
|
||||
pub use actix_http::client::{
|
||||
pub use crate::client::{
|
||||
ConnectError, FreezeRequestError, InvalidUrl, SendRequestError,
|
||||
};
|
||||
pub use actix_http::error::PayloadError;
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -120,7 +120,6 @@ async fn test_timeout() {
|
|||
});
|
||||
|
||||
let connector = awc::Connector::new()
|
||||
.connector(awc::connector::default_connector())
|
||||
.timeout(Duration::from_secs(15))
|
||||
.finish();
|
||||
|
||||
|
|
Loading…
Reference in New Issue