Merge branch 'master' into header-from-request

This commit is contained in:
Ibraheem Ahmed 2021-03-29 09:29:46 -04:00 committed by GitHub
commit 5eb3c1c7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 210 additions and 255 deletions

View File

@ -23,6 +23,9 @@ jobs:
name: ${{ matrix.target.name }} / ${{ matrix.version }}
runs-on: ${{ matrix.target.os }}
env:
VCPKGRS_DYNAMIC: 1
steps:
- uses: actions/checkout@v2
@ -65,7 +68,13 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: hack
args: --clean-per-run check --workspace --no-default-features --tests
args: check --workspace --no-default-features
- name: check minimal + tests
uses: actions-rs/cargo@v1
with:
command: hack
args: check --workspace --no-default-features --tests --examples
- name: check full
uses: actions-rs/cargo@v1

View File

@ -80,11 +80,11 @@ required-features = ["rustls"]
actix-codec = "0.4.0-beta.1"
actix-macros = "0.2.0"
actix-router = "0.2.7"
actix-rt = "2.1"
actix-rt = "2.2"
actix-server = "2.0.0-beta.3"
actix-service = "2.0.0-beta.4"
actix-utils = "3.0.0-beta.2"
actix-tls = { version = "3.0.0-beta.4", default-features = false, optional = true }
actix-tls = { version = "3.0.0-beta.5", default-features = false, optional = true }
actix-web-codegen = "0.5.0-beta.2"
actix-http = "3.0.0-beta.4"

View File

@ -33,5 +33,5 @@ mime_guess = "2.0.1"
percent-encoding = "2.1"
[dev-dependencies]
actix-rt = "2.1"
actix-rt = "2.2"
actix-web = "4.0.0-beta.4"

View File

@ -31,9 +31,9 @@ openssl = ["tls-openssl", "awc/openssl"]
[dependencies]
actix-service = "2.0.0-beta.4"
actix-codec = "0.4.0-beta.1"
actix-tls = "3.0.0-beta.4"
actix-tls = "3.0.0-beta.5"
actix-utils = "3.0.0-beta.2"
actix-rt = "2.1"
actix-rt = "2.2"
actix-server = "2.0.0-beta.3"
awc = { version = "3.0.0-beta.3", default-features = false }

View File

@ -47,15 +47,14 @@ trust-dns = ["trust-dns-resolver"]
actix-service = "2.0.0-beta.4"
actix-codec = "0.4.0-beta.1"
actix-utils = "3.0.0-beta.2"
actix-rt = "2.1"
actix-tls = "3.0.0-beta.4"
actix-rt = "2.2"
actix-tls = "3.0.0-beta.5"
ahash = "0.7"
base64 = "0.13"
bitflags = "1.2"
bytes = "1"
bytestring = "1"
cfg-if = "1"
cookie = { version = "0.14.1", features = ["percent-encode"], optional = true }
derive_more = "0.99.5"
encoding_rs = "0.8"
@ -89,7 +88,7 @@ trust-dns-resolver = { version = "0.20.0", optional = true }
[dev-dependencies]
actix-server = "2.0.0-beta.3"
actix-http-test = { version = "3.0.0-beta.3", features = ["openssl"] }
actix-tls = { version = "3.0.0-beta.4", features = ["openssl"] }
actix-tls = { version = "3.0.0-beta.5", features = ["openssl"] }
criterion = "0.3"
env_logger = "0.8"
rcgen = "0.8"

View File

@ -174,7 +174,13 @@ impl H2ConnectionInner {
/// Cancel spawned connection task on drop.
impl Drop for H2ConnectionInner {
fn drop(&mut self) {
self.handle.abort();
if self
.sender
.send_request(http::Request::new(()), true)
.is_err()
{
self.handle.abort();
}
}
}
@ -398,9 +404,18 @@ where
#[cfg(test)]
mod test {
use std::net;
use std::{
future::Future,
net,
pin::Pin,
task::{Context, Poll},
time::{Duration, Instant},
};
use actix_rt::net::TcpStream;
use actix_rt::{
net::TcpStream,
time::{interval, Interval},
};
use super::*;
@ -424,9 +439,36 @@ mod test {
drop(conn);
match sender.ready().await {
Ok(_) => panic!("connection should be gone and can not be ready"),
Err(e) => assert!(e.is_io()),
};
struct DropCheck {
sender: h2::client::SendRequest<Bytes>,
interval: Interval,
start_from: Instant,
}
impl Future for DropCheck {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
match futures_core::ready!(this.sender.poll_ready(cx)) {
Ok(()) => {
if this.start_from.elapsed() > Duration::from_secs(10) {
panic!("connection should be gone and can not be ready");
} else {
let _ = this.interval.poll_tick(cx);
Poll::Pending
}
}
Err(_) => Poll::Ready(()),
}
}
}
DropCheck {
sender,
interval: interval(Duration::from_millis(100)),
start_from: Instant::now(),
}
.await;
}
}

View File

@ -9,7 +9,7 @@ use std::{
};
use actix_rt::{
net::TcpStream,
net::{ActixStream, TcpStream},
time::{sleep, Sleep},
};
use actix_service::Service;
@ -119,7 +119,7 @@ impl<S> Connector<S> {
/// Use custom connector.
pub fn connector<S1, Io1>(self, connector: S1) -> Connector<S1>
where
Io1: ConnectionIo + fmt::Debug,
Io1: ActixStream + fmt::Debug + 'static,
S1: Service<
TcpConnect<Uri>,
Response = TcpConnection<Uri, Io1>,
@ -136,7 +136,14 @@ impl<S> Connector<S> {
impl<S, Io> Connector<S>
where
Io: ConnectionIo + fmt::Debug,
// Note:
// Input Io type is bound to ActixStream trait but internally in client module they
// are bound to ConnectionIo trait alias. And latter is the trait exposed to public
// in the form of Box<dyn ConnectionIo> type.
//
// This remap is to hide ActixStream's trait methods. They are not meant to be called
// from user code.
Io: ActixStream + fmt::Debug + 'static,
S: Service<
TcpConnect<Uri>,
Response = TcpConnection<Uri, Io>,
@ -407,16 +414,14 @@ struct TlsConnectorService<S, St> {
timeout: Duration,
}
impl<S, St, Io, Res> Service<Connect> for TlsConnectorService<S, St>
impl<S, St, Io> Service<Connect> for TlsConnectorService<S, St>
where
S: Service<Connect, Response = TcpConnection<Uri, Io>, Error = ConnectError>
+ Clone
+ 'static,
St: Service<TcpConnection<Uri, Io>, Response = Res, Error = std::io::Error>
+ Clone
+ 'static,
St: Service<TcpConnection<Uri, Io>, Error = std::io::Error> + Clone + 'static,
Io: ConnectionIo,
Res: IntoConnectionIo,
St::Response: IntoConnectionIo,
{
type Response = (Box<dyn ConnectionIo>, Protocol);
type Error = ConnectError;
@ -471,10 +476,10 @@ where
Error = std::io::Error,
Future = Fut2,
>,
S::Response: IntoConnectionIo,
Fut1: Future<Output = Result<TcpConnection<Uri, Io>, ConnectError>>,
Fut2: Future<Output = Result<S::Response, S::Error>>,
Io: ConnectionIo,
Res: IntoConnectionIo,
{
type Output = Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>;

View File

@ -1,6 +1,4 @@
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll};
use std::{fmt, net};
@ -8,7 +6,7 @@ use std::{fmt, net};
use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_rt::net::TcpStream;
use actix_service::{pipeline_factory, IntoServiceFactory, Service, ServiceFactory};
use futures_core::ready;
use futures_core::{future::LocalBoxFuture, ready};
use futures_util::future::ready;
use crate::body::MessageBody;
@ -60,14 +58,17 @@ where
impl<S, B, X, U> H1Service<TcpStream, S, B, X, U>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
B: MessageBody,
X: ServiceFactory<Request, Config = (), Response = Request>,
X::Future: 'static,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<(Request, Framed<TcpStream, Codec>), Config = (), Response = ()>,
U::Future: 'static,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
@ -94,17 +95,21 @@ mod openssl {
use super::*;
use actix_service::ServiceFactoryExt;
use actix_tls::accept::openssl::{Acceptor, SslAcceptor, SslError, TlsStream};
use actix_tls::accept::TlsError;
use actix_tls::accept::{
openssl::{Acceptor, SslAcceptor, SslError, TlsStream},
TlsError,
};
impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
B: MessageBody,
X: ServiceFactory<Request, Config = (), Response = Request>,
X::Future: 'static,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<
@ -112,6 +117,7 @@ mod openssl {
Config = (),
Response = (),
>,
U::Future: 'static,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
@ -143,19 +149,25 @@ mod openssl {
#[cfg(feature = "rustls")]
mod rustls {
use super::*;
use std::io;
use actix_service::ServiceFactoryExt;
use actix_tls::accept::rustls::{Acceptor, ServerConfig, TlsStream};
use actix_tls::accept::TlsError;
use std::{fmt, io};
use actix_tls::accept::{
rustls::{Acceptor, ServerConfig, TlsStream},
TlsError,
};
impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>>,
B: MessageBody,
X: ServiceFactory<Request, Config = (), Response = Request>,
X::Future: 'static,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<
@ -163,6 +175,7 @@ mod rustls {
Config = (),
Response = (),
>,
U::Future: 'static,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
@ -241,16 +254,19 @@ where
impl<T, S, B, X, U> ServiceFactory<(T, Option<net::SocketAddr>)>
for H1Service<T, S, B, X, U>
where
T: AsyncRead + AsyncWrite + Unpin,
T: AsyncRead + AsyncWrite + Unpin + 'static,
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error>,
S::Response: Into<Response<B>>,
S::InitError: fmt::Debug,
B: MessageBody,
X: ServiceFactory<Request, Config = (), Response = Request>,
X::Future: 'static,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>,
U::Future: 'static,
U::Error: fmt::Display + Into<Error>,
U::InitError: fmt::Debug,
{
@ -259,103 +275,42 @@ where
type Config = ();
type Service = H1ServiceHandler<T, S::Service, B, X::Service, U::Service>;
type InitError = ();
type Future = H1ServiceResponse<T, S, B, X, U>;
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
fn new_service(&self, _: ()) -> Self::Future {
H1ServiceResponse {
fut: self.srv.new_service(()),
fut_ex: Some(self.expect.new_service(())),
fut_upg: self.upgrade.as_ref().map(|f| f.new_service(())),
expect: None,
upgrade: None,
on_connect_ext: self.on_connect_ext.clone(),
cfg: Some(self.cfg.clone()),
_phantom: PhantomData,
}
}
}
let service = self.srv.new_service(());
let expect = self.expect.new_service(());
let upgrade = self.upgrade.as_ref().map(|s| s.new_service(()));
let on_connect_ext = self.on_connect_ext.clone();
let cfg = self.cfg.clone();
#[doc(hidden)]
#[pin_project::pin_project]
pub struct H1ServiceResponse<T, S, B, X, U>
where
S: ServiceFactory<Request>,
S::Error: Into<Error>,
S::InitError: fmt::Debug,
X: ServiceFactory<Request, Response = Request>,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<(Request, Framed<T, Codec>), Response = ()>,
U::Error: fmt::Display,
U::InitError: fmt::Debug,
{
#[pin]
fut: S::Future,
#[pin]
fut_ex: Option<X::Future>,
#[pin]
fut_upg: Option<U::Future>,
expect: Option<X::Service>,
upgrade: Option<U::Service>,
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
cfg: Option<ServiceConfig>,
_phantom: PhantomData<B>,
}
Box::pin(async move {
let expect = expect
.await
.map_err(|e| log::error!("Init http expect service error: {:?}", e))?;
impl<T, S, B, X, U> Future for H1ServiceResponse<T, S, B, X, U>
where
T: AsyncRead + AsyncWrite + Unpin,
S: ServiceFactory<Request>,
S::Error: Into<Error>,
S::Response: Into<Response<B>>,
S::InitError: fmt::Debug,
B: MessageBody,
X: ServiceFactory<Request, Response = Request>,
X::Error: Into<Error>,
X::InitError: fmt::Debug,
U: ServiceFactory<(Request, Framed<T, Codec>), Response = ()>,
U::Error: fmt::Display,
U::InitError: fmt::Debug,
{
type Output = Result<H1ServiceHandler<T, S::Service, B, X::Service, U::Service>, ()>;
let upgrade = match upgrade {
Some(upgrade) => {
let upgrade = upgrade.await.map_err(|e| {
log::error!("Init http upgrade service error: {:?}", e)
})?;
Some(upgrade)
}
None => None,
};
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut this = self.as_mut().project();
let service = service
.await
.map_err(|e| log::error!("Init http service error: {:?}", e))?;
if let Some(fut) = this.fut_ex.as_pin_mut() {
let expect = ready!(fut
.poll(cx)
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
this = self.as_mut().project();
*this.expect = Some(expect);
this.fut_ex.set(None);
}
if let Some(fut) = this.fut_upg.as_pin_mut() {
let upgrade = ready!(fut
.poll(cx)
.map_err(|e| log::error!("Init http service error: {:?}", e)))?;
this = self.as_mut().project();
*this.upgrade = Some(upgrade);
this.fut_upg.set(None);
}
let result = ready!(this
.fut
.poll(cx)
.map_err(|e| log::error!("Init http service error: {:?}", e)));
Poll::Ready(result.map(|service| {
let this = self.as_mut().project();
H1ServiceHandler::new(
this.cfg.take().unwrap(),
Ok(H1ServiceHandler::new(
cfg,
service,
this.expect.take().unwrap(),
this.upgrade.take(),
this.on_connect_ext.clone(),
)
}))
expect,
upgrade,
on_connect_ext,
))
})
}
}
@ -417,47 +372,27 @@ where
type Future = Dispatcher<T, S, B, X, U>;
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let ready = self
.flow
.expect
.poll_ready(cx)
.map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
DispatchError::Service(e)
})?
.is_ready();
ready!(self.flow.expect.poll_ready(cx)).map_err(|e| {
let e = e.into();
log::error!("Http expect service readiness error: {:?}", e);
DispatchError::Service(e)
})?;
let ready = self
.flow
.service
.poll_ready(cx)
.map_err(|e| {
if let Some(ref upg) = self.flow.upgrade {
ready!(upg.poll_ready(cx)).map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
log::error!("Http upgrade service readiness error: {:?}", e);
DispatchError::Service(e)
})?
.is_ready()
&& ready;
let ready = if let Some(ref upg) = self.flow.upgrade {
upg.poll_ready(cx)
.map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
DispatchError::Service(e)
})?
.is_ready()
&& ready
} else {
ready
})?;
};
if ready {
Poll::Ready(Ok(()))
} else {
Poll::Pending
}
ready!(self.flow.service.poll_ready(cx)).map_err(|e| {
let e = e.into();
log::error!("Http service readiness error: {:?}", e);
DispatchError::Service(e)
})?;
Poll::Ready(Ok(()))
}
fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {

View File

@ -11,8 +11,8 @@ use actix_service::{
ServiceFactory,
};
use bytes::Bytes;
use futures_core::ready;
use futures_util::future::ok;
use futures_core::{future::LocalBoxFuture, ready};
use futures_util::future::ready;
use h2::server::{handshake, Handshake};
use log::error;
@ -65,6 +65,7 @@ where
impl<S, B> H2Service<TcpStream, S, B>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error> + 'static,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static,
@ -80,11 +81,11 @@ where
Error = DispatchError,
InitError = S::InitError,
> {
pipeline_factory(fn_factory(|| async {
Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
pipeline_factory(fn_factory(|| {
ready(Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
let peer_addr = io.peer_addr().ok();
ok::<_, DispatchError>((io, peer_addr))
}))
ready(Ok::<_, DispatchError>((io, peer_addr)))
})))
}))
.and_then(self)
}
@ -101,6 +102,7 @@ mod openssl {
impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error> + 'static,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static,
@ -123,10 +125,12 @@ mod openssl {
.map_init_err(|_| panic!()),
)
.and_then(fn_factory(|| {
ok::<_, S::InitError>(fn_service(|io: TlsStream<TcpStream>| {
let peer_addr = io.get_ref().peer_addr().ok();
ok((io, peer_addr))
}))
ready(Ok::<_, S::InitError>(fn_service(
|io: TlsStream<TcpStream>| {
let peer_addr = io.get_ref().peer_addr().ok();
ready(Ok((io, peer_addr)))
},
)))
}))
.and_then(self.map_err(TlsError::Service))
}
@ -144,6 +148,7 @@ mod rustls {
impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error> + 'static,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static,
@ -169,10 +174,12 @@ mod rustls {
.map_init_err(|_| panic!()),
)
.and_then(fn_factory(|| {
ok::<_, S::InitError>(fn_service(|io: TlsStream<TcpStream>| {
let peer_addr = io.get_ref().0.peer_addr().ok();
ok((io, peer_addr))
}))
ready(Ok::<_, S::InitError>(fn_service(
|io: TlsStream<TcpStream>| {
let peer_addr = io.get_ref().0.peer_addr().ok();
ready(Ok((io, peer_addr)))
},
)))
}))
.and_then(self.map_err(TlsError::Service))
}
@ -181,8 +188,9 @@ mod rustls {
impl<T, S, B> ServiceFactory<(T, Option<net::SocketAddr>)> for H2Service<T, S, B>
where
T: AsyncRead + AsyncWrite + Unpin,
T: AsyncRead + AsyncWrite + Unpin + 'static,
S: ServiceFactory<Request, Config = ()>,
S::Future: 'static,
S::Error: Into<Error> + 'static,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static,
@ -193,52 +201,16 @@ where
type Config = ();
type Service = H2ServiceHandler<T, S::Service, B>;
type InitError = S::InitError;
type Future = H2ServiceResponse<T, S, B>;
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
fn new_service(&self, _: ()) -> Self::Future {
H2ServiceResponse {
fut: self.srv.new_service(()),
cfg: Some(self.cfg.clone()),
on_connect_ext: self.on_connect_ext.clone(),
_phantom: PhantomData,
}
}
}
let service = self.srv.new_service(());
let cfg = self.cfg.clone();
let on_connect_ext = self.on_connect_ext.clone();
#[doc(hidden)]
#[pin_project::pin_project]
pub struct H2ServiceResponse<T, S, B>
where
S: ServiceFactory<Request>,
{
#[pin]
fut: S::Future,
cfg: Option<ServiceConfig>,
on_connect_ext: Option<Rc<ConnectCallback<T>>>,
_phantom: PhantomData<B>,
}
impl<T, S, B> Future for H2ServiceResponse<T, S, B>
where
T: AsyncRead + AsyncWrite + Unpin,
S: ServiceFactory<Request, Config = ()>,
S::Error: Into<Error> + 'static,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service<Request>>::Future: 'static,
B: MessageBody + 'static,
{
type Output = Result<H2ServiceHandler<T, S::Service, B>, S::InitError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.as_mut().project();
this.fut.poll(cx).map_ok(|service| {
let this = self.as_mut().project();
H2ServiceHandler::new(
this.cfg.take().unwrap(),
this.on_connect_ext.clone(),
service,
)
Box::pin(async move {
let service = service.await?;
Ok(H2ServiceHandler::new(cfg, on_connect_ext, service))
})
}
}

View File

@ -3,6 +3,7 @@ use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll};
use actix_codec::{AsyncRead, AsyncWrite, Framed};
use actix_http::{body, h1, ws, Error, HttpService, Request, Response};
@ -11,7 +12,6 @@ use actix_service::{fn_factory, Service};
use actix_utils::dispatcher::Dispatcher;
use bytes::Bytes;
use futures_util::future;
use futures_util::task::{Context, Poll};
use futures_util::{SinkExt as _, StreamExt as _};
struct WsService<T>(Arc<Mutex<(PhantomData<T>, Cell<bool>)>>);

View File

@ -28,7 +28,7 @@ mime = "0.3"
twoway = "0.2"
[dev-dependencies]
actix-rt = "2.1"
actix-rt = "2.2"
actix-http = "3.0.0-beta.4"
tokio = { version = "1", features = ["sync"] }
tokio-stream = "0.1"

View File

@ -28,6 +28,6 @@ pin-project = "1.0.0"
tokio = { version = "1", features = ["sync"] }
[dev-dependencies]
actix-rt = "2.1"
actix-rt = "2.2"
env_logger = "0.8"
futures-util = { version = "0.3.7", default-features = false }

View File

@ -19,7 +19,7 @@ syn = { version = "1", features = ["full", "parsing"] }
proc-macro2 = "1"
[dev-dependencies]
actix-rt = "2.1"
actix-rt = "2.2"
actix-web = "4.0.0-beta.4"
futures-util = { version = "0.3.7", default-features = false }
trybuild = "1"

View File

@ -2,9 +2,11 @@
## Unreleased - 2021-xx-xx
### Changed
* `ConnectorService` type is renamed to `BoxConnectorService` [#2081]
* `ConnectorService` type is renamed to `BoxConnectorService`. [#2081]
* Fix http/https encoding when enabling `compress` feature. [#2116]
[#2081]: https://github.com/actix/actix-web/pull/2081
[#2116]: https://github.com/actix/actix-web/pull/2116
## 3.0.0-beta.3 - 2021-03-08

View File

@ -51,7 +51,6 @@ actix-rt = { version = "2.1", default-features = false }
base64 = "0.13"
bytes = "1"
cfg-if = "1.0"
derive_more = "0.99.5"
futures-core = { version = "0.3.7", default-features = false }
itoa = "0.4"
@ -72,7 +71,7 @@ actix-http = { version = "3.0.0-beta.4", features = ["openssl"] }
actix-http-test = { version = "3.0.0-beta.3", features = ["openssl"] }
actix-utils = "3.0.0-beta.1"
actix-server = "2.0.0-beta.3"
actix-tls = { version = "3.0.0-beta.4", features = ["openssl", "rustls"] }
actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] }
brotli2 = "0.3.2"
env_logger = "0.8"

View File

@ -4,12 +4,11 @@ use std::net::IpAddr;
use std::rc::Rc;
use std::time::Duration;
use actix_codec::{AsyncRead, AsyncWrite};
use actix_http::{
client::{Connector, ConnectorService, TcpConnect, TcpConnectError, TcpConnection},
http::{self, header, Error as HttpError, HeaderMap, HeaderName, Uri},
};
use actix_rt::net::TcpStream;
use actix_rt::net::{ActixStream, TcpStream};
use actix_service::{boxed, Service};
use crate::connect::DefaultConnector;
@ -64,7 +63,7 @@ where
S: Service<TcpConnect<Uri>, Response = TcpConnection<Uri, Io>, Error = TcpConnectError>
+ Clone
+ 'static,
Io: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static,
Io: ActixStream + fmt::Debug + 'static,
{
/// Use custom connector service.
pub fn connector<S1, Io1>(self, connector: Connector<S1>) -> ClientBuilder<S1, M>
@ -75,7 +74,7 @@ where
Error = TcpConnectError,
> + Clone
+ 'static,
Io1: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static,
Io1: ActixStream + fmt::Debug + 'static,
{
ClientBuilder {
middleware: self.middleware,

View File

@ -21,15 +21,10 @@ use crate::frozen::FrozenClientRequest;
use crate::sender::{PrepForSendingError, RequestSender, SendClientRequest};
use crate::ClientConfig;
cfg_if::cfg_if! {
if #[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))] {
const HTTPS_ENCODING: &str = "br, gzip, deflate";
} else if #[cfg(feature = "compress")] {
const HTTPS_ENCODING: &str = "br";
} else {
const HTTPS_ENCODING: &str = "identity";
}
}
#[cfg(feature = "compress")]
const HTTPS_ENCODING: &str = "br, gzip, deflate";
#[cfg(not(feature = "compress"))]
const HTTPS_ENCODING: &str = "br";
/// An HTTP Client request builder
///
@ -521,11 +516,11 @@ impl ClientRequest {
.unwrap_or(true);
if https {
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, HTTPS_ENCODING))
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, HTTPS_ENCODING));
} else {
#[cfg(any(feature = "flate2-zlib", feature = "flate2-rust"))]
#[cfg(feature = "compress")]
{
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, "gzip, deflate"))
slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, "gzip, deflate"));
}
};
}

View File

@ -1,21 +1,19 @@
digraph {
subgraph cluster_net {
label="actix/actix-net";
"actix-codec"
"actix-macros"
"actix-rt"
"actix-server"
"actix-service"
"actix-threadpool"
"actix-tls"
"actix-tracing"
"actix-utils"
"actix-router"
"actix-codec" "actix-macros" "actix-rt" "actix-server" "actix-service"
"actix-tls" "actix-tracing" "actix-utils" "actix-router"
"local-channel" "local-waker"
}
"actix-utils" -> { "actix-service" "actix-rt" "actix-codec" }
"actix-codec" -> { "actix-rt" "actix-service" "local-channel" "tokio" }
"actix-utils" -> { "actix-rt" "actix-service" "local-waker" }
"actix-tracing" -> { "actix-service" }
"actix-tls" -> { "actix-service" "actix-codec" "actix-utils" "actix-rt" }
"actix-server" -> { "actix-service" "actix-rt" "actix-codec" "actix-utils" }
"actix-rt" -> { "actix-macros" "actix-threadpool" }
"actix-server" -> { "actix-service" "actix-rt" "actix-codec" "actix-utils" "tokio" }
"actix-rt" -> { "actix-macros" "tokio" }
"local-channel" -> { "local-waker" }
"tokio" [fontcolor = darkgreen]
}