From 32de9f8840a39d42f070a1a87b26ed3d32a80fb5 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Mon, 4 Jan 2021 07:47:04 +0800 Subject: [PATCH] Tokio 1.0 (#1813) Co-authored-by: Rob Ede --- CHANGES.md | 7 +- Cargo.toml | 32 ++-- actix-files/CHANGES.md | 3 + actix-files/Cargo.toml | 6 +- actix-files/src/files.rs | 9 +- actix-files/src/service.rs | 3 +- actix-http-test/CHANGES.md | 3 + actix-http-test/Cargo.toml | 19 ++- actix-http-test/src/lib.rs | 15 +- actix-http/CHANGES.md | 14 +- actix-http/Cargo.toml | 36 ++--- actix-http/src/builder.rs | 48 +++--- actix-http/src/client/connection.rs | 34 +--- actix-http/src/client/connector.rs | 87 +++++----- actix-http/src/client/error.rs | 30 ++-- actix-http/src/client/h1proto.rs | 17 +- actix-http/src/client/pool.rs | 32 ++-- actix-http/src/cloneable.rs | 11 +- actix-http/src/config.rs | 12 +- actix-http/src/error.rs | 11 +- actix-http/src/h1/dispatcher.rs | 108 +++++++------ actix-http/src/h1/encoder.rs | 6 +- actix-http/src/h1/expect.rs | 8 +- actix-http/src/h1/service.rs | 107 +++++++------ actix-http/src/h1/upgrade.rs | 15 +- actix-http/src/h2/dispatcher.rs | 14 +- actix-http/src/h2/service.rs | 81 +++++----- actix-http/src/header/shared/httpdate.rs | 3 +- actix-http/src/request.rs | 8 +- actix-http/src/service.rs | 193 ++++++++++++----------- actix-http/src/test.rs | 22 ++- actix-http/src/ws/dispatcher.rs | 10 +- actix-http/tests/test_client.rs | 7 +- actix-http/tests/test_openssl.rs | 14 +- actix-http/tests/test_server.rs | 4 +- actix-http/tests/test_ws.rs | 8 +- actix-multipart/CHANGES.md | 3 + actix-multipart/Cargo.toml | 10 +- actix-web-actors/CHANGES.md | 4 +- actix-web-actors/Cargo.toml | 17 +- actix-web-actors/src/context.rs | 2 +- actix-web-actors/src/ws.rs | 2 +- actix-web-codegen/Cargo.toml | 4 +- actix-web-codegen/tests/test_macro.rs | 12 +- awc/CHANGES.md | 6 +- awc/Cargo.toml | 24 +-- awc/src/builder.rs | 2 +- awc/src/connect.rs | 17 +- awc/src/sender.rs | 7 +- awc/tests/test_client.rs | 8 +- awc/tests/test_connector.rs | 2 +- awc/tests/test_rustls_client.rs | 2 +- awc/tests/test_ssl_client.rs | 2 +- benches/server.rs | 14 +- benches/service.rs | 25 +-- src/app.rs | 21 +-- src/app_service.rs | 33 ++-- src/config.rs | 4 +- src/handler.rs | 10 +- src/middleware/compress.rs | 16 +- src/middleware/condition.rs | 18 +-- src/middleware/defaultheaders.rs | 14 +- src/middleware/errhandlers.rs | 12 +- src/middleware/logger.rs | 16 +- src/middleware/normalize.rs | 12 +- src/resource.rs | 38 +++-- src/route.rs | 38 ++--- src/scope.rs | 30 ++-- src/server.rs | 31 ++-- src/service.rs | 6 +- src/test.rs | 54 +++---- src/types/json.rs | 2 +- src/web.rs | 1 - tests/test_httpserver.rs | 51 +++--- tests/test_server.rs | 7 +- 75 files changed, 788 insertions(+), 826 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2e886e0f5..32f444ec1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,10 +2,15 @@ ## Unreleased - 2021-xx-xx ### Changed -* Bumped `rand` to `0.8` +* Update `actix-*` dependencies to tokio `1.0` based versions. [#1813] +* Bumped `rand` to `0.8`. +* Update `rust-tls` to `0.19`. [#1813] * Rename `Handler` to `HandlerService` and rename `Factory` to `Handler`. [#1852] * MSRV is now 1.46.0. +[#1813]: https://github.com/actix/actix-web/pull/1813 + + ### Fixed * added the actual parsing error to `test::read_body_json` [#1812] diff --git a/Cargo.toml b/Cargo.toml index e33ff844b..165004447 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/openssl", "awc/openssl", "open-ssl"] +openssl = ["actix-tls/accept", "actix-tls/openssl", "awc/openssl", "open-ssl"] # rustls -rustls = ["actix-tls/rustls", "awc/rustls", "rust-tls"] +rustls = ["actix-tls/accept", "actix-tls/rustls", "awc/rustls", "rust-tls"] [[example]] name = "basic" @@ -73,27 +73,25 @@ name = "client" required-features = ["rustls"] [dependencies] -actix-codec = "0.3.0" -actix-service = "1.0.6" -actix-utils = "2.0.0" -actix-router = "0.2.4" -actix-rt = "1.1.1" -actix-server = "1.0.0" -actix-testing = "1.0.0" +actix-codec = "0.4.0-beta.1" actix-macros = "0.1.0" +actix-router = "0.2.4" +actix-rt = "2.0.0-beta.1" +actix-server = "2.0.0-beta.2" +actix-service = "2.0.0-beta.2" +actix-utils = "3.0.0-beta.1" actix-threadpool = "0.3.1" -actix-tls = "2.0.0" +actix-tls = { version = "3.0.0-beta.2", default-features = false, optional = true } actix-web-codegen = "0.4.0" actix-http = "2.2.0" awc = { version = "2.0.3", default-features = false } -bytes = "0.5.3" +bytes = "1" derive_more = "0.99.5" encoding_rs = "0.8" -futures-channel = { version = "0.3.5", default-features = false } -futures-core = { version = "0.3.5", default-features = false } -futures-util = { version = "0.3.5", default-features = false } +futures-core = { version = "0.3.7", default-features = false } +futures-util = { version = "0.3.7", default-features = false } fxhash = "0.2.1" log = "0.4" mime = "0.3" @@ -106,12 +104,12 @@ serde_urlencoded = "0.7" time = { version = "0.2.7", default-features = false, features = ["std"] } url = "2.1" open-ssl = { package = "openssl", version = "0.10", optional = true } -rust-tls = { package = "rustls", version = "0.18.0", optional = true } +rust-tls = { package = "rustls", version = "0.19.0", optional = true } smallvec = "1.6" [dev-dependencies] -actix = "0.10.0" -actix-http = { version = "2.1.0", features = ["actors"] } +actix = "0.11.0-beta.1" +actix-http = { version = "2.2.0", features = ["actors"] } rand = "0.8" env_logger = "0.8" serde_derive = "1.0" diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md index f992e5fdb..6dcf4f66f 100644 --- a/actix-files/CHANGES.md +++ b/actix-files/CHANGES.md @@ -2,6 +2,9 @@ ## Unreleased - 2021-xx-xx * `HttpRange::parse` now has its own error type. +* Update `bytes` to `1.0`. [#1813] + +[#1813]: https://github.com/actix/actix-web/pull/1813 ## 0.5.0 - 2020-12-26 diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml index b67abb1c1..17e1a4888 100644 --- a/actix-files/Cargo.toml +++ b/actix-files/Cargo.toml @@ -18,9 +18,9 @@ path = "src/lib.rs" [dependencies] actix-web = { version = "3.0.0", default-features = false } -actix-service = "1.0.6" +actix-service = "2.0.0-beta.2" bitflags = "1" -bytes = "0.5.3" +bytes = "1" futures-core = { version = "0.3.7", default-features = false } futures-util = { version = "0.3.7", default-features = false } derive_more = "0.99.5" @@ -31,5 +31,5 @@ percent-encoding = "2.1" v_htmlescape = "0.12" [dev-dependencies] -actix-rt = "1.0.0" +actix-rt = "2.0.0-beta.1" actix-web = "3.0.0" diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index d0cac6aa4..98dd26880 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -1,6 +1,6 @@ use std::{cell::RefCell, fmt, io, path::PathBuf, rc::Rc}; -use actix_service::{boxed, IntoServiceFactory, ServiceFactory}; +use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt}; use actix_web::{ dev::{ AppService, HttpServiceFactory, ResourceDef, ServiceRequest, ServiceResponse, @@ -201,10 +201,10 @@ impl Files { /// Sets default handler which is used when no matched file could be found. pub fn default_handler(mut self, f: F) -> Self where - F: IntoServiceFactory, + F: IntoServiceFactory, U: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, > + 'static, @@ -241,8 +241,7 @@ impl HttpServiceFactory for Files { } } -impl ServiceFactory for Files { - type Request = ServiceRequest; +impl ServiceFactory for Files { type Response = ServiceResponse; type Error = Error; type Config = (); diff --git a/actix-files/src/service.rs b/actix-files/src/service.rs index dc4f2bd2c..1e3d64a0d 100644 --- a/actix-files/src/service.rs +++ b/actix-files/src/service.rs @@ -57,8 +57,7 @@ impl fmt::Debug for FilesService { } } -impl Service for FilesService { - type Request = ServiceRequest; +impl Service for FilesService { type Response = ServiceResponse; type Error = Error; type Future = FilesServiceFuture; diff --git a/actix-http-test/CHANGES.md b/actix-http-test/CHANGES.md index 535766373..6ed6a0603 100644 --- a/actix-http-test/CHANGES.md +++ b/actix-http-test/CHANGES.md @@ -1,6 +1,9 @@ # Changes ## Unreleased - 2021-xx-xx +* Update `bytes` to `1.0`. [#1813] + +[#1813]: https://github.com/actix/actix-web/pull/1813 ## 2.1.0 - 2020-11-25 diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml index 8b23bef1c..910fbab73 100644 --- a/actix-http-test/Cargo.toml +++ b/actix-http-test/Cargo.toml @@ -29,19 +29,18 @@ default = [] openssl = ["open-ssl", "awc/openssl"] [dependencies] -actix-service = "1.0.6" -actix-codec = "0.3.0" -actix-connect = "2.0.0" -actix-utils = "2.0.0" -actix-rt = "1.1.1" -actix-server = "1.0.0" -actix-testing = "1.0.0" +actix-service = "2.0.0-beta.2" +actix-codec = "0.4.0-beta.1" +actix-tls = "3.0.0-beta.2" +actix-utils = "3.0.0-beta.1" +actix-rt = "2.0.0-beta.1" +actix-server = "2.0.0-beta.2" awc = "2.0.0" base64 = "0.13" -bytes = "0.5.3" -futures-core = { version = "0.3.5", default-features = false } -http = "0.2.0" +bytes = "1" +futures-core = { version = "0.3.7", default-features = false } +http = "0.2.2" log = "0.4" socket2 = "0.3" serde = "1.0" diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs index 3ab3f8a0d..4fd74d6eb 100644 --- a/actix-http-test/src/lib.rs +++ b/actix-http-test/src/lib.rs @@ -16,8 +16,6 @@ use futures_core::stream::Stream; use http::Method; use socket2::{Domain, Protocol, Socket, Type}; -pub use actix_testing::*; - /// Start test server /// /// `TestServer` is very simple test server that simplify process of writing @@ -65,13 +63,16 @@ pub async fn test_server_with_addr>( let sys = System::new("actix-test-server"); let local_addr = tcp.local_addr().unwrap(); - Server::build() + let srv = Server::build() .listen("test", tcp, factory)? .workers(1) - .disable_signals() - .start(); + .disable_signals(); + + sys.block_on(async { + srv.start(); + tx.send((System::current(), local_addr)).unwrap(); + }); - tx.send((System::current(), local_addr)).unwrap(); sys.run() }); @@ -105,7 +106,7 @@ pub async fn test_server_with_addr>( Client::builder().connector(connector).finish() }; - actix_connect::start_default_resolver().await.unwrap(); + actix_tls::connect::start_default_resolver().await.unwrap(); TestServer { addr, diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 1d0cc3d31..147285ddf 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,13 +2,25 @@ ## Unreleased - 2021-xx-xx ### Changed -* Bumped `rand` to `0.8` +* Bumped `rand` to `0.8`. +* Update `actix-*` dependencies to tokio `1.0` based versions. [#1813] +* Update `bytes` to `1.0`. [#1813] +* Update `h2` to `0.3`. [#1813] + + +[#1813]: https://github.com/actix/actix-web/pull/1813 ### Removed * Deprecated `on_connect` methods have been removed. Prefer the new `on_connect_ext` technique. [#1857] +* Remove `ResponseError` impl for `actix::actors::resolver::ResolverError` + due to deprecate of resolver actor. [#1813] +* Remove `ConnectError::SslHandshakeError` and re-export of `HandshakeError`. + due to the removal of this type from `tokio-openssl` crate. openssl handshake + error would return as `ConnectError::SslError`. [#1813] +[#1813]: https://github.com/actix/actix-web/pull/1813 [#1857]: https://github.com/actix/actix-web/pull/1857 diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index 50690537a..e98bcf76d 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -25,10 +25,10 @@ path = "src/lib.rs" default = [] # openssl -openssl = ["actix-tls/openssl", "actix-connect/openssl"] +openssl = ["actix-tls/openssl"] # rustls support -rustls = ["actix-tls/rustls", "actix-connect/rustls"] +rustls = ["actix-tls/rustls"] # enable compressison support compress = ["flate2", "brotli2"] @@ -40,29 +40,28 @@ secure-cookies = ["cookie/secure"] actors = ["actix"] [dependencies] -actix-service = "1.0.6" -actix-codec = "0.3.0" -actix-connect = "2.0.0" -actix-utils = "2.0.0" -actix-rt = "1.0.0" +actix-service = "2.0.0-beta.2" +actix-codec = "0.4.0-beta.1" +actix-utils = "3.0.0-beta.1" +actix-rt = "2.0.0-beta.1" actix-threadpool = "0.3.1" -actix-tls = { version = "2.0.0", optional = true } -actix = { version = "0.10.0", optional = true } +actix-tls = "3.0.0-beta.2" +actix = { version = "0.11.0-beta.1", optional = true } base64 = "0.13" bitflags = "1.2" -bytes = "0.5.3" +bytes = "1" cookie = { version = "0.14.1", features = ["percent-encode"] } copyless = "0.1.4" derive_more = "0.99.2" either = "1.5.3" encoding_rs = "0.8" -futures-channel = { version = "0.3.5", default-features = false } -futures-core = { version = "0.3.5", default-features = false } -futures-util = { version = "0.3.5", default-features = false } +futures-channel = { 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"] } fxhash = "0.2.1" -h2 = "0.2.1" -http = "0.2.0" +h2 = "0.3.0" +http = "0.2.2" httparse = "1.3" indexmap = "1.3" itoa = "0.4" @@ -86,15 +85,14 @@ brotli2 = { version="0.3.2", optional = true } flate2 = { version = "1.0.13", optional = true } [dev-dependencies] -actix-server = "1.0.1" -actix-connect = { version = "2.0.0", features = ["openssl"] } +actix-server = "2.0.0-beta.2" actix-http-test = { version = "2.0.0", features = ["openssl"] } -actix-tls = { version = "2.0.0", features = ["openssl"] } +actix-tls = { version = "3.0.0-beta.2", features = ["openssl"] } criterion = "0.3" env_logger = "0.7" serde_derive = "1.0" open-ssl = { version="0.10", package = "openssl" } -rust-tls = { version="0.18", package = "rustls" } +rust-tls = { version="0.19", package = "rustls" } [[bench]] name = "write-camel-case" diff --git a/actix-http/src/builder.rs b/actix-http/src/builder.rs index df1b332c1..ecb4327df 100644 --- a/actix-http/src/builder.rs +++ b/actix-http/src/builder.rs @@ -19,7 +19,7 @@ use crate::{ConnectCallback, Extensions}; /// /// This type can be used to construct an instance of [`HttpService`] through a /// builder-like pattern. -pub struct HttpServiceBuilder> { +pub struct HttpServiceBuilder { keep_alive: KeepAlive, client_timeout: u64, client_disconnect: u64, @@ -28,15 +28,15 @@ pub struct HttpServiceBuilder> { expect: X, upgrade: Option, on_connect_ext: Option>>, - _t: PhantomData<(T, S)>, + _t: PhantomData, } -impl HttpServiceBuilder> +impl HttpServiceBuilder where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, { /// Create instance of `ServiceConfigBuilder` pub fn new() -> Self { @@ -56,18 +56,18 @@ where impl HttpServiceBuilder where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, - ::Future: 'static, - X: ServiceFactory, + >::Future: 'static, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, - U: ServiceFactory), Response = ()>, + >::Future: 'static, + U: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U::Error: fmt::Display, U::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { /// Set server keep-alive setting. /// @@ -123,11 +123,11 @@ where /// request will be forwarded to main service. pub fn expect(self, expect: F) -> HttpServiceBuilder where - F: IntoServiceFactory, - X1: ServiceFactory, + F: IntoServiceFactory, + X1: ServiceFactory, X1::Error: Into, X1::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, { HttpServiceBuilder { keep_alive: self.keep_alive, @@ -148,15 +148,11 @@ where /// and this service get called with original request and framed object. pub fn upgrade(self, upgrade: F) -> HttpServiceBuilder where - F: IntoServiceFactory, - U1: ServiceFactory< - Config = (), - Request = (Request, Framed), - Response = (), - >, + F: IntoServiceFactory)>, + U1: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U1::Error: fmt::Display, U1::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { HttpServiceBuilder { keep_alive: self.keep_alive, @@ -188,7 +184,7 @@ where pub fn h1(self, service: F) -> H1Service where B: MessageBody, - F: IntoServiceFactory, + F: IntoServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, @@ -211,11 +207,11 @@ where pub fn h2(self, service: F) -> H2Service where B: MessageBody + 'static, - F: IntoServiceFactory, + F: IntoServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, { let cfg = ServiceConfig::new( self.keep_alive, @@ -233,11 +229,11 @@ where pub fn finish(self, service: F) -> HttpService where B: MessageBody + 'static, - F: IntoServiceFactory, + F: IntoServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, { let cfg = ServiceConfig::new( self.keep_alive, diff --git a/actix-http/src/client/connection.rs b/actix-http/src/client/connection.rs index ec86dabb0..d22f2c7ac 100644 --- a/actix-http/src/client/connection.rs +++ b/actix-http/src/client/connection.rs @@ -1,10 +1,10 @@ use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; -use std::{fmt, io, mem, time}; +use std::{fmt, io, time}; -use actix_codec::{AsyncRead, AsyncWrite, Framed}; -use bytes::{Buf, Bytes}; +use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf}; +use bytes::Bytes; use futures_util::future::{err, Either, FutureExt, LocalBoxFuture, Ready}; use h2::client::SendRequest; use pin_project::pin_project; @@ -223,23 +223,13 @@ where fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { + buf: &mut ReadBuf<'_>, + ) -> Poll> { match self.project() { EitherIoProj::A(val) => val.poll_read(cx, buf), EitherIoProj::B(val) => val.poll_read(cx, buf), } } - - unsafe fn prepare_uninitialized_buffer( - &self, - buf: &mut [mem::MaybeUninit], - ) -> bool { - match self { - EitherIo::A(ref val) => val.prepare_uninitialized_buffer(buf), - EitherIo::B(ref val) => val.prepare_uninitialized_buffer(buf), - } - } } impl AsyncWrite for EitherIo @@ -274,18 +264,4 @@ where EitherIoProj::B(val) => val.poll_shutdown(cx), } } - - fn poll_write_buf( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut U, - ) -> Poll> - where - Self: Sized, - { - match self.project() { - EitherIoProj::A(val) => val.poll_write_buf(cx, buf), - EitherIoProj::B(val) => val.poll_write_buf(cx, buf), - } - } } diff --git a/actix-http/src/client/connector.rs b/actix-http/src/client/connector.rs index e1aed6382..b638336f7 100644 --- a/actix-http/src/client/connector.rs +++ b/actix-http/src/client/connector.rs @@ -3,11 +3,11 @@ use std::marker::PhantomData; use std::time::Duration; use actix_codec::{AsyncRead, AsyncWrite}; -use actix_connect::{ +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_rt::net::TcpStream; -use actix_service::{apply_fn, Service}; use actix_utils::timeout::{TimeoutError, TimeoutService}; use http::Uri; @@ -18,10 +18,10 @@ use super::pool::{ConnectionPool, Protocol}; use super::Connect; #[cfg(feature = "openssl")] -use actix_connect::ssl::openssl::SslConnector as OpensslConnector; +use actix_tls::connect::ssl::openssl::SslConnector as OpensslConnector; #[cfg(feature = "rustls")] -use actix_connect::ssl::rustls::ClientConfig; +use actix_tls::connect::ssl::rustls::ClientConfig; #[cfg(feature = "rustls")] use std::sync::Arc; @@ -62,9 +62,9 @@ impl Connector<(), ()> { #[allow(clippy::new_ret_no_self, clippy::let_unit_value)] pub fn new() -> Connector< impl Service< - Request = TcpConnect, + TcpConnect, Response = TcpConnection, - Error = actix_connect::ConnectError, + Error = actix_tls::connect::ConnectError, > + Clone, TcpStream, > { @@ -79,7 +79,7 @@ impl Connector<(), ()> { // Build Ssl connector with openssl, based on supplied alpn protocols #[cfg(feature = "openssl")] fn build_ssl(protocols: Vec>) -> SslConnector { - use actix_connect::ssl::openssl::SslMethod; + use actix_tls::connect::ssl::openssl::SslMethod; use bytes::{BufMut, BytesMut}; let mut alpn = BytesMut::with_capacity(20); @@ -102,7 +102,7 @@ impl Connector<(), ()> { config.set_protocols(&protocols); config .root_store - .add_server_trust_anchors(&actix_tls::rustls::TLS_SERVER_ROOTS); + .add_server_trust_anchors(&actix_tls::accept::rustls::TLS_SERVER_ROOTS); SslConnector::Rustls(Arc::new(config)) } @@ -117,9 +117,9 @@ impl Connector { where U1: AsyncRead + AsyncWrite + Unpin + fmt::Debug, T1: Service< - Request = TcpConnect, + TcpConnect, Response = TcpConnection, - Error = actix_connect::ConnectError, + Error = actix_tls::connect::ConnectError, > + Clone, { Connector { @@ -135,9 +135,9 @@ impl Connector where U: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static, T: Service< - Request = TcpConnect, + TcpConnect, Response = TcpConnection, - Error = actix_connect::ConnectError, + Error = actix_tls::connect::ConnectError, > + Clone + 'static, { @@ -241,8 +241,8 @@ where /// its combinator chain. pub fn finish( self, - ) -> impl Service - + Clone { + ) -> impl Service + Clone + { #[cfg(not(any(feature = "openssl", feature = "rustls")))] { let connector = TimeoutService::new( @@ -268,11 +268,11 @@ where #[cfg(any(feature = "openssl", feature = "rustls"))] { const H2: &[u8] = b"h2"; - #[cfg(feature = "openssl")] - use actix_connect::ssl::openssl::OpensslConnector; - #[cfg(feature = "rustls")] - use actix_connect::ssl::rustls::{RustlsConnector, Session}; use actix_service::{boxed::service, pipeline}; + #[cfg(feature = "openssl")] + use actix_tls::connect::ssl::openssl::OpensslConnector; + #[cfg(feature = "rustls")] + use actix_tls::connect::ssl::rustls::{RustlsConnector, Session}; let ssl_service = TimeoutService::new( self.config.timeout, @@ -363,8 +363,7 @@ mod connect_impl { pub(crate) struct InnerConnector where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { pub(crate) tcp_pool: ConnectionPool, } @@ -372,8 +371,7 @@ mod connect_impl { impl Clone for InnerConnector where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { fn clone(&self) -> Self { InnerConnector { @@ -382,17 +380,15 @@ mod connect_impl { } } - impl Service for InnerConnector + impl Service for InnerConnector where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { - type Request = Connect; type Response = IoConnection; type Error = ConnectError; type Future = Either< - as Service>::Future, + as Service>::Future, Ready, ConnectError>>, >; @@ -428,8 +424,8 @@ mod connect_impl { where Io1: AsyncRead + AsyncWrite + Unpin + 'static, Io2: AsyncRead + AsyncWrite + Unpin + 'static, - T1: Service, - T2: Service, + T1: Service, + T2: Service, { pub(crate) tcp_pool: ConnectionPool, pub(crate) ssl_pool: ConnectionPool, @@ -439,10 +435,8 @@ mod connect_impl { where Io1: AsyncRead + AsyncWrite + Unpin + 'static, Io2: AsyncRead + AsyncWrite + Unpin + 'static, - T1: Service - + 'static, - T2: Service - + 'static, + T1: Service + 'static, + T2: Service + 'static, { fn clone(&self) -> Self { InnerConnector { @@ -452,16 +446,13 @@ mod connect_impl { } } - impl Service for InnerConnector + impl Service for InnerConnector where Io1: AsyncRead + AsyncWrite + Unpin + 'static, Io2: AsyncRead + AsyncWrite + Unpin + 'static, - T1: Service - + 'static, - T2: Service - + 'static, + T1: Service + 'static, + T2: Service + 'static, { - type Request = Connect; type Response = EitherConnection; type Error = ConnectError; type Future = Either< @@ -491,18 +482,16 @@ mod connect_impl { pub(crate) struct InnerConnectorResponseA where Io1: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { #[pin] - fut: as Service>::Future, + fut: as Service>::Future, _t: PhantomData, } impl Future for InnerConnectorResponseA where - T: Service - + 'static, + T: Service + 'static, Io1: AsyncRead + AsyncWrite + Unpin + 'static, Io2: AsyncRead + AsyncWrite + Unpin + 'static, { @@ -520,18 +509,16 @@ mod connect_impl { pub(crate) struct InnerConnectorResponseB where Io2: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { #[pin] - fut: as Service>::Future, + fut: as Service>::Future, _t: PhantomData, } impl Future for InnerConnectorResponseB where - T: Service - + 'static, + T: Service + 'static, Io1: AsyncRead + AsyncWrite + Unpin + 'static, Io2: AsyncRead + AsyncWrite + Unpin + 'static, { diff --git a/actix-http/src/client/error.rs b/actix-http/src/client/error.rs index ba697bca4..a5f1b2e8e 100644 --- a/actix-http/src/client/error.rs +++ b/actix-http/src/client/error.rs @@ -1,10 +1,10 @@ use std::io; -use actix_connect::resolver::ResolveError; +use actix_tls::connect::resolver::ResolveError; use derive_more::{Display, From}; #[cfg(feature = "openssl")] -use actix_connect::ssl::openssl::{HandshakeError, SslError}; +use actix_tls::accept::openssl::SslError; use crate::error::{Error, ParseError, ResponseError}; use crate::http::{Error as HttpError, StatusCode}; @@ -21,11 +21,6 @@ pub enum ConnectError { #[display(fmt = "{}", _0)] SslError(SslError), - /// SSL Handshake error - #[cfg(feature = "openssl")] - #[display(fmt = "{}", _0)] - SslHandshakeError(String), - /// Failed to resolve the hostname #[display(fmt = "Failed resolving hostname: {}", _0)] Resolver(ResolveError), @@ -57,25 +52,18 @@ pub enum ConnectError { impl std::error::Error for ConnectError {} -impl From for ConnectError { - fn from(err: actix_connect::ConnectError) -> ConnectError { +impl From for ConnectError { + fn from(err: actix_tls::connect::ConnectError) -> ConnectError { match err { - actix_connect::ConnectError::Resolver(e) => ConnectError::Resolver(e), - actix_connect::ConnectError::NoRecords => ConnectError::NoRecords, - actix_connect::ConnectError::InvalidInput => panic!(), - actix_connect::ConnectError::Unresolved => ConnectError::Unresolved, - actix_connect::ConnectError::Io(e) => ConnectError::Io(e), + actix_tls::connect::ConnectError::Resolver(e) => ConnectError::Resolver(e), + actix_tls::connect::ConnectError::NoRecords => ConnectError::NoRecords, + actix_tls::connect::ConnectError::InvalidInput => panic!(), + actix_tls::connect::ConnectError::Unresolved => ConnectError::Unresolved, + actix_tls::connect::ConnectError::Io(e) => ConnectError::Io(e), } } } -#[cfg(feature = "openssl")] -impl From> for ConnectError { - fn from(err: HandshakeError) -> ConnectError { - ConnectError::SslHandshakeError(format!("{:?}", err)) - } -} - #[derive(Debug, Display, From)] pub enum InvalidUrl { #[display(fmt = "Missing url scheme")] diff --git a/actix-http/src/client/h1proto.rs b/actix-http/src/client/h1proto.rs index 06cc05404..754c53968 100644 --- a/actix-http/src/client/h1proto.rs +++ b/actix-http/src/client/h1proto.rs @@ -1,10 +1,10 @@ use std::io::Write; use std::pin::Pin; use std::task::{Context, Poll}; -use std::{io, mem, time}; +use std::{io, time}; -use actix_codec::{AsyncRead, AsyncWrite, Framed}; -use bytes::buf::BufMutExt; +use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf}; +use bytes::buf::BufMut; use bytes::{Bytes, BytesMut}; use futures_core::Stream; use futures_util::future::poll_fn; @@ -204,18 +204,11 @@ where } impl AsyncRead for H1Connection { - unsafe fn prepare_uninitialized_buffer( - &self, - buf: &mut [mem::MaybeUninit], - ) -> bool { - self.io.as_ref().unwrap().prepare_uninitialized_buffer(buf) - } - fn poll_read( mut self: Pin<&mut Self>, cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { + buf: &mut ReadBuf<'_>, + ) -> Poll> { Pin::new(&mut self.io.as_mut().unwrap()).poll_read(cx, buf) } } diff --git a/actix-http/src/client/pool.rs b/actix-http/src/client/pool.rs index a8687dbeb..f9973a850 100644 --- a/actix-http/src/client/pool.rs +++ b/actix-http/src/client/pool.rs @@ -6,8 +6,8 @@ use std::rc::Rc; use std::task::{Context, Poll}; use std::time::{Duration, Instant}; -use actix_codec::{AsyncRead, AsyncWrite}; -use actix_rt::time::{delay_for, Delay}; +use actix_codec::{AsyncRead, AsyncWrite, ReadBuf}; +use actix_rt::time::{sleep, Sleep}; use actix_service::Service; use actix_utils::task::LocalWaker; use bytes::Bytes; @@ -50,8 +50,7 @@ pub(crate) struct ConnectionPool(Rc>, Rc ConnectionPool where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { pub(crate) fn new(connector: T, config: ConnectorConfig) -> Self { let connector_rc = Rc::new(RefCell::new(connector)); @@ -90,13 +89,11 @@ impl Drop for ConnectionPool { } } -impl Service for ConnectionPool +impl Service for ConnectionPool where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service - + 'static, + T: Service + 'static, { - type Request = Connect; type Response = IoConnection; type Error = ConnectError; type Future = LocalBoxFuture<'static, Result, ConnectError>>; @@ -334,10 +331,11 @@ where } else { let mut io = conn.io; let mut buf = [0; 2]; + let mut read_buf = ReadBuf::new(&mut buf); if let ConnectionType::H1(ref mut s) = io { - match Pin::new(s).poll_read(cx, &mut buf) { + match Pin::new(s).poll_read(cx, &mut read_buf) { Poll::Pending => (), - Poll::Ready(Ok(n)) if n > 0 => { + Poll::Ready(Ok(())) if !read_buf.filled().is_empty() => { if let Some(timeout) = self.config.disconnect_timeout { if let ConnectionType::H1(io) = io { actix_rt::spawn(CloseConnection::new( @@ -387,9 +385,11 @@ where } } +#[pin_project::pin_project] struct CloseConnection { io: T, - timeout: Delay, + #[pin] + timeout: Sleep, } impl CloseConnection @@ -399,7 +399,7 @@ where fn new(io: T, timeout: Duration) -> Self { CloseConnection { io, - timeout: delay_for(timeout), + timeout: sleep(timeout), } } } @@ -411,11 +411,11 @@ where type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { - let this = self.get_mut(); + let this = self.project(); - match Pin::new(&mut this.timeout).poll(cx) { + match this.timeout.poll(cx) { Poll::Ready(_) => Poll::Ready(()), - Poll::Pending => match Pin::new(&mut this.io).poll_shutdown(cx) { + Poll::Pending => match Pin::new(this.io).poll_shutdown(cx) { Poll::Ready(_) => Poll::Ready(()), Poll::Pending => Poll::Pending, }, @@ -435,7 +435,7 @@ where impl Future for ConnectorPoolSupport where Io: AsyncRead + AsyncWrite + Unpin + 'static, - T: Service, + T: Service, T::Future: 'static, { type Output = (); diff --git a/actix-http/src/cloneable.rs b/actix-http/src/cloneable.rs index 0e77c455c..5f0b1ea28 100644 --- a/actix-http/src/cloneable.rs +++ b/actix-http/src/cloneable.rs @@ -10,22 +10,21 @@ use actix_service::Service; /// CloneableService might panic with some creative use of thread local storage. /// See https://github.com/actix/actix-web/issues/1295 for example #[doc(hidden)] -pub(crate) struct CloneableService(Rc>); +pub(crate) struct CloneableService(Rc>); -impl CloneableService { +impl CloneableService { pub(crate) fn new(service: T) -> Self { Self(Rc::new(RefCell::new(service))) } } -impl Clone for CloneableService { +impl Clone for CloneableService { fn clone(&self) -> Self { Self(self.0.clone()) } } -impl Service for CloneableService { - type Request = T::Request; +impl, Req> Service for CloneableService { type Response = T::Response; type Error = T::Error; type Future = T::Future; @@ -34,7 +33,7 @@ impl Service for CloneableService { self.0.borrow_mut().poll_ready(cx) } - fn call(&mut self, req: T::Request) -> Self::Future { + fn call(&mut self, req: Req) -> Self::Future { self.0.borrow_mut().call(req) } } diff --git a/actix-http/src/config.rs b/actix-http/src/config.rs index b314d4c99..1cd7e4aea 100644 --- a/actix-http/src/config.rs +++ b/actix-http/src/config.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use std::time::Duration; use std::{fmt, net}; -use actix_rt::time::{delay_for, delay_until, Delay, Instant}; +use actix_rt::time::{sleep, sleep_until, Instant, Sleep}; use bytes::BytesMut; use futures_util::{future, FutureExt}; use time::OffsetDateTime; @@ -121,10 +121,10 @@ impl ServiceConfig { #[inline] /// Client timeout for first request. - pub fn client_timer(&self) -> Option { + pub fn client_timer(&self) -> Option { let delay_time = self.0.client_timeout; if delay_time != 0 { - Some(delay_until( + Some(sleep_until( self.0.timer.now() + Duration::from_millis(delay_time), )) } else { @@ -154,9 +154,9 @@ impl ServiceConfig { #[inline] /// Return keep-alive timer delay is configured. - pub fn keep_alive_timer(&self) -> Option { + pub fn keep_alive_timer(&self) -> Option { if let Some(ka) = self.0.keep_alive { - Some(delay_until(self.0.timer.now() + ka)) + Some(sleep_until(self.0.timer.now() + ka)) } else { None } @@ -266,7 +266,7 @@ impl DateService { // periodic date update let s = self.clone(); - actix_rt::spawn(delay_for(Duration::from_millis(500)).then(move |_| { + actix_rt::spawn(sleep(Duration::from_millis(500)).then(move |_| { s.0.reset(); future::ready(()) })); diff --git a/actix-http/src/error.rs b/actix-http/src/error.rs index 0ebd4c05c..03e5467c5 100644 --- a/actix-http/src/error.rs +++ b/actix-http/src/error.rs @@ -178,11 +178,7 @@ impl ResponseError for FormError {} #[cfg(feature = "openssl")] /// `InternalServerError` for `openssl::ssl::Error` -impl ResponseError for actix_connect::ssl::openssl::SslError {} - -#[cfg(feature = "openssl")] -/// `InternalServerError` for `openssl::ssl::HandshakeError` -impl ResponseError for actix_tls::openssl::HandshakeError {} +impl ResponseError for actix_tls::accept::openssl::SslError {} /// Return `BAD_REQUEST` for `de::value::Error` impl ResponseError for DeError { @@ -956,11 +952,6 @@ where /// This is supported on feature=`actors` only impl ResponseError for actix::MailboxError {} -#[cfg(feature = "actors")] -/// `InternalServerError` for `actix::ResolverError` -/// This is supported on feature=`actors` only -impl ResponseError for actix::actors::resolver::ResolverError {} - #[cfg(test)] mod tests { use super::*; diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 91e208aac..41caea902 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -8,7 +8,7 @@ use std::{ }; use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed, FramedParts}; -use actix_rt::time::{delay_until, Delay, Instant}; +use actix_rt::time::{sleep_until, Instant, Sleep}; use actix_service::Service; use bitflags::bitflags; use bytes::{Buf, BytesMut}; @@ -51,12 +51,12 @@ bitflags! { /// Dispatcher for HTTP/1.1 protocol pub struct Dispatcher where - S: Service, + S: Service, S::Error: Into, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { #[pin] @@ -69,12 +69,12 @@ where #[pin_project(project = DispatcherStateProj)] enum DispatcherState where - S: Service, + S: Service, S::Error: Into, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { Normal(#[pin] InnerDispatcher), @@ -84,12 +84,12 @@ where #[pin_project(project = InnerDispatcherProj)] struct InnerDispatcher where - S: Service, + S: Service, S::Error: Into, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { service: CloneableService, @@ -106,7 +106,8 @@ where messages: VecDeque, ka_expire: Instant, - ka_timer: Option, + #[pin] + ka_timer: Option, io: Option, read_buf: BytesMut, @@ -123,8 +124,8 @@ enum DispatcherMessage { #[pin_project(project = StateProj)] enum State where - S: Service, - X: Service, + S: Service, + X: Service, B: MessageBody, { None, @@ -135,8 +136,8 @@ where impl State where - S: Service, - X: Service, + S: Service, + X: Service, B: MessageBody, { fn is_empty(&self) -> bool { @@ -166,13 +167,13 @@ impl PartialEq for PollResponse { impl Dispatcher where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into, S::Response: Into>, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { /// Create HTTP/1 dispatcher. @@ -205,7 +206,7 @@ where codec: Codec, config: ServiceConfig, read_buf: BytesMut, - timeout: Option, + timeout: Option, service: CloneableService, expect: CloneableService, upgrade: Option>, @@ -257,13 +258,13 @@ where impl InnerDispatcher where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into, S::Response: Into>, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { fn can_read(&self, cx: &mut Context<'_>) -> bool { @@ -660,7 +661,7 @@ where // shutdown timeout if this.flags.contains(Flags::SHUTDOWN) { if let Some(interval) = this.codec.config().client_disconnect_timer() { - *this.ka_timer = Some(delay_until(interval)); + this.ka_timer.set(Some(sleep_until(interval))); } else { this.flags.insert(Flags::READ_DISCONNECT); if let Some(mut payload) = this.payload.take() { @@ -673,12 +674,14 @@ where } } - match Pin::new(&mut this.ka_timer.as_mut().unwrap()).poll(cx) { + match this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx) { Poll::Ready(()) => { // if we get timeout during shutdown, drop connection if this.flags.contains(Flags::SHUTDOWN) { return Err(DispatchError::DisconnectTimeout); - } else if this.ka_timer.as_mut().unwrap().deadline() >= *this.ka_expire { + } else if this.ka_timer.as_mut().as_pin_mut().unwrap().deadline() + >= *this.ka_expire + { // check for any outstanding tasks if this.state.is_empty() && this.write_buf.is_empty() { if this.flags.contains(Flags::STARTED) { @@ -689,9 +692,15 @@ where if let Some(deadline) = this.codec.config().client_disconnect_timer() { - if let Some(mut timer) = this.ka_timer.as_mut() { + if let Some(timer) = this.ka_timer.as_mut().as_pin_mut() + { timer.reset(deadline); - let _ = Pin::new(&mut timer).poll(cx); + let _ = this + .ka_timer + .as_mut() + .as_pin_mut() + .unwrap() + .poll(cx); } } else { // no shutdown timeout, drop socket @@ -716,14 +725,15 @@ where } else if let Some(deadline) = this.codec.config().keep_alive_expire() { - if let Some(mut timer) = this.ka_timer.as_mut() { + if let Some(timer) = this.ka_timer.as_mut().as_pin_mut() { timer.reset(deadline); - let _ = Pin::new(&mut timer).poll(cx); + let _ = + this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx); } } - } else if let Some(mut timer) = this.ka_timer.as_mut() { + } else if let Some(timer) = this.ka_timer.as_mut().as_pin_mut() { timer.reset(*this.ka_expire); - let _ = Pin::new(&mut timer).poll(cx); + let _ = this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx); } } Poll::Pending => (), @@ -736,13 +746,13 @@ where impl Future for Dispatcher where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into, S::Response: Into>, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { type Output = Result<(), DispatchError>; @@ -951,12 +961,12 @@ fn read( where T: AsyncRead + Unpin, { - Pin::new(io).poll_read_buf(cx, buf) + actix_codec::poll_read_buf(Pin::new(io), cx, buf) } #[cfg(test)] mod tests { - use std::{marker::PhantomData, str}; + use std::str; use actix_service::fn_service; use futures_util::future::{lazy, ready}; @@ -985,21 +995,19 @@ mod tests { } } - fn ok_service() -> impl Service - { + fn ok_service() -> impl Service { fn_service(|_req: Request| ready(Ok::<_, Error>(Response::Ok().finish()))) } - fn echo_path_service( - ) -> impl Service { + fn echo_path_service() -> impl Service { fn_service(|req: Request| { let path = req.path().as_bytes(); ready(Ok::<_, Error>(Response::Ok().body(Body::from_slice(path)))) }) } - fn echo_payload_service( - ) -> impl Service { + fn echo_payload_service() -> impl Service + { fn_service(|mut req: Request| { Box::pin(async move { use futures_util::stream::StreamExt as _; @@ -1007,7 +1015,7 @@ mod tests { let mut pl = req.take_payload(); let mut body = BytesMut::new(); while let Some(chunk) = pl.next().await { - body.extend_from_slice(chunk.unwrap().bytes()) + body.extend_from_slice(chunk.unwrap().chunk()) } Ok::<_, Error>(Response::Ok().body(body)) @@ -1020,7 +1028,7 @@ mod tests { lazy(|cx| { let buf = TestBuffer::new("GET /test HTTP/1\r\n\r\n"); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf, ServiceConfig::default(), CloneableService::new(ok_service()), @@ -1060,7 +1068,7 @@ mod tests { let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf, cfg, CloneableService::new(echo_path_service()), @@ -1114,7 +1122,7 @@ mod tests { let cfg = ServiceConfig::new(KeepAlive::Disabled, 1, 1, false, None); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf, cfg, CloneableService::new(echo_path_service()), @@ -1163,7 +1171,7 @@ mod tests { lazy(|cx| { let mut buf = TestSeqBuffer::empty(); let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler<_>>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf.clone(), cfg, CloneableService::new(echo_payload_service()), @@ -1234,7 +1242,7 @@ mod tests { lazy(|cx| { let mut buf = TestSeqBuffer::empty(); let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler<_>>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf.clone(), cfg, CloneableService::new(echo_path_service()), @@ -1293,12 +1301,12 @@ mod tests { lazy(|cx| { let mut buf = TestSeqBuffer::empty(); let cfg = ServiceConfig::new(KeepAlive::Disabled, 0, 0, false, None); - let h1 = Dispatcher::<_, _, _, _, UpgradeHandler<_>>::new( + let h1 = Dispatcher::<_, _, _, _, UpgradeHandler>::new( buf.clone(), cfg, CloneableService::new(ok_service()), CloneableService::new(ExpectHandler), - Some(CloneableService::new(UpgradeHandler(PhantomData))), + Some(CloneableService::new(UpgradeHandler)), Extensions::new(), None, ); diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs index 2ec4899a7..4fadbb518 100644 --- a/actix-http/src/h1/encoder.rs +++ b/actix-http/src/h1/encoder.rs @@ -135,7 +135,7 @@ pub(crate) trait MessageType: Sized { let mut has_date = false; - let mut buf = dst.bytes_mut().as_mut_ptr() as *mut u8; + let mut buf = dst.chunk_mut().as_mut_ptr() as *mut u8; let mut remaining = dst.capacity() - dst.len(); // tracks bytes written since last buffer resize @@ -177,7 +177,7 @@ pub(crate) trait MessageType: Sized { // re-assign buf raw pointer since it's possible that the buffer was // reallocated and/or resized - buf = dst.bytes_mut().as_mut_ptr() as *mut u8; + buf = dst.chunk_mut().as_mut_ptr() as *mut u8; } // SAFETY: on each write, it is enough to ensure that the advancement of the @@ -224,7 +224,7 @@ pub(crate) trait MessageType: Sized { // re-assign buf raw pointer since it's possible that the buffer was // reallocated and/or resized - buf = dst.bytes_mut().as_mut_ptr() as *mut u8; + buf = dst.chunk_mut().as_mut_ptr() as *mut u8; } // SAFETY: on each write, it is enough to ensure that the advancement of diff --git a/actix-http/src/h1/expect.rs b/actix-http/src/h1/expect.rs index b89c7ff74..c3e4ccdaa 100644 --- a/actix-http/src/h1/expect.rs +++ b/actix-http/src/h1/expect.rs @@ -8,11 +8,10 @@ use crate::request::Request; pub struct ExpectHandler; -impl ServiceFactory for ExpectHandler { - type Config = (); - type Request = Request; +impl ServiceFactory for ExpectHandler { type Response = Request; type Error = Error; + type Config = (); type Service = ExpectHandler; type InitError = Error; type Future = Ready>; @@ -22,8 +21,7 @@ impl ServiceFactory for ExpectHandler { } } -impl Service for ExpectHandler { - type Request = Request; +impl Service for ExpectHandler { type Response = Request; type Error = Error; type Future = Ready>; diff --git a/actix-http/src/h1/service.rs b/actix-http/src/h1/service.rs index 919a5d932..67f1127c7 100644 --- a/actix-http/src/h1/service.rs +++ b/actix-http/src/h1/service.rs @@ -24,25 +24,25 @@ use super::dispatcher::Dispatcher; use super::{ExpectHandler, UpgradeHandler}; /// `ServiceFactory` implementation for HTTP1 transport -pub struct H1Service> { +pub struct H1Service { srv: S, cfg: ServiceConfig, expect: X, upgrade: Option, on_connect_ext: Option>>, - _t: PhantomData<(T, B)>, + _t: PhantomData, } impl H1Service where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, B: MessageBody, { /// Create new `HttpService` instance with config. - pub(crate) fn with_config>( + pub(crate) fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -59,19 +59,15 @@ where impl H1Service where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, B: MessageBody, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - U: ServiceFactory< - Config = (), - Request = (Request, Framed), - Response = (), - >, + U: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, { @@ -79,8 +75,8 @@ where pub fn tcp( self, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = DispatchError, InitError = (), @@ -97,22 +93,23 @@ where mod openssl { use super::*; - use actix_tls::openssl::{Acceptor, SslAcceptor, SslStream}; - use actix_tls::{openssl::HandshakeError, TlsError}; + use actix_service::ServiceFactoryExt; + use actix_tls::accept::openssl::{Acceptor, SslAcceptor, SslError, SslStream}; + use actix_tls::accept::TlsError; impl H1Service, S, B, X, U> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, B: MessageBody, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, U: ServiceFactory< + (Request, Framed, Codec>), Config = (), - Request = (Request, Framed, Codec>), Response = (), >, U::Error: fmt::Display + Into, @@ -123,10 +120,10 @@ mod openssl { self, acceptor: SslAcceptor, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), - Error = TlsError, DispatchError>, + Error = TlsError, InitError = (), > { pipeline_factory( @@ -146,23 +143,24 @@ mod openssl { #[cfg(feature = "rustls")] mod rustls { use super::*; - use actix_tls::rustls::{Acceptor, ServerConfig, TlsStream}; - use actix_tls::TlsError; + use actix_service::ServiceFactoryExt; + use actix_tls::accept::rustls::{Acceptor, ServerConfig, TlsStream}; + use actix_tls::accept::TlsError; use std::{fmt, io}; impl H1Service, S, B, X, U> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, B: MessageBody, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, U: ServiceFactory< + (Request, Framed, Codec>), Config = (), - Request = (Request, Framed, Codec>), Response = (), >, U::Error: fmt::Display + Into, @@ -173,8 +171,8 @@ mod rustls { self, config: ServerConfig, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = TlsError, InitError = (), @@ -195,7 +193,7 @@ mod rustls { impl H1Service where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::Response: Into>, S::InitError: fmt::Debug, @@ -203,7 +201,7 @@ where { pub fn expect(self, expect: X1) -> H1Service where - X1: ServiceFactory, + X1: ServiceFactory, X1::Error: Into, X1::InitError: fmt::Debug, { @@ -219,7 +217,7 @@ where pub fn upgrade(self, upgrade: Option) -> H1Service where - U1: ServiceFactory), Response = ()>, + U1: ServiceFactory<(Request, Framed), Response = ()>, U1::Error: fmt::Display, U1::InitError: fmt::Debug, { @@ -240,27 +238,27 @@ where } } -impl ServiceFactory for H1Service +impl ServiceFactory<(T, Option)> + for H1Service where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::Response: Into>, S::InitError: fmt::Debug, B: MessageBody, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - U: ServiceFactory), Response = ()>, + U: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, { - type Config = (); - type Request = (T, Option); type Response = (); type Error = DispatchError; - type InitError = (); + type Config = (); type Service = H1ServiceHandler; + type InitError = (); type Future = H1ServiceResponse; fn new_service(&self, _: ()) -> Self::Future { @@ -281,13 +279,13 @@ where #[pin_project::pin_project] pub struct H1ServiceResponse where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - U: ServiceFactory), Response = ()>, + U: ServiceFactory<(Request, Framed), Response = ()>, U::Error: fmt::Display, U::InitError: fmt::Debug, { @@ -307,15 +305,15 @@ where impl Future for H1ServiceResponse where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into, S::Response: Into>, S::InitError: fmt::Debug, B: MessageBody, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - U: ServiceFactory), Response = ()>, + U: ServiceFactory<(Request, Framed), Response = ()>, U::Error: fmt::Display, U::InitError: fmt::Debug, { @@ -362,24 +360,29 @@ where } /// `Service` implementation for HTTP/1 transport -pub struct H1ServiceHandler { +pub struct H1ServiceHandler +where + S: Service, + X: Service, + U: Service<(Request, Framed)>, +{ srv: CloneableService, expect: CloneableService, upgrade: Option>, on_connect_ext: Option>>, cfg: ServiceConfig, - _t: PhantomData<(T, B)>, + _t: PhantomData, } impl H1ServiceHandler where - S: Service, + S: Service, S::Error: Into, S::Response: Into>, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { fn new( @@ -400,19 +403,19 @@ where } } -impl Service for H1ServiceHandler +impl Service<(T, Option)> + for H1ServiceHandler where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into, S::Response: Into>, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display + Into, { - type Request = (T, Option); type Response = (); type Error = DispatchError; type Future = Dispatcher; @@ -459,7 +462,7 @@ where } } - fn call(&mut self, (io, addr): Self::Request) -> Self::Future { + fn call(&mut self, (io, addr): (T, Option)) -> Self::Future { let mut connect_extensions = Extensions::new(); if let Some(ref handler) = self.on_connect_ext { // run on_connect_ext callback, populating connect extensions diff --git a/actix-http/src/h1/upgrade.rs b/actix-http/src/h1/upgrade.rs index 8615f27a8..007aff1bf 100644 --- a/actix-http/src/h1/upgrade.rs +++ b/actix-http/src/h1/upgrade.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use std::task::{Context, Poll}; use actix_codec::Framed; @@ -9,14 +8,13 @@ use crate::error::Error; use crate::h1::Codec; use crate::request::Request; -pub struct UpgradeHandler(pub(crate) PhantomData); +pub struct UpgradeHandler; -impl ServiceFactory for UpgradeHandler { - type Config = (); - type Request = (Request, Framed); +impl ServiceFactory<(Request, Framed)> for UpgradeHandler { type Response = (); type Error = Error; - type Service = UpgradeHandler; + type Config = (); + type Service = UpgradeHandler; type InitError = Error; type Future = Ready>; @@ -25,8 +23,7 @@ impl ServiceFactory for UpgradeHandler { } } -impl Service for UpgradeHandler { - type Request = (Request, Framed); +impl Service<(Request, Framed)> for UpgradeHandler { type Response = (); type Error = Error; type Future = Ready>; @@ -35,7 +32,7 @@ impl Service for UpgradeHandler { Poll::Ready(Ok(())) } - fn call(&mut self, _: Self::Request) -> Self::Future { + fn call(&mut self, _: (Request, Framed)) -> Self::Future { ready(Ok(())) } } diff --git a/actix-http/src/h2/dispatcher.rs b/actix-http/src/h2/dispatcher.rs index 7a0be9492..4aeda942a 100644 --- a/actix-http/src/h2/dispatcher.rs +++ b/actix-http/src/h2/dispatcher.rs @@ -6,7 +6,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use actix_codec::{AsyncRead, AsyncWrite}; -use actix_rt::time::{Delay, Instant}; +use actix_rt::time::{Instant, Sleep}; use actix_service::Service; use bytes::{Bytes, BytesMut}; use h2::server::{Connection, SendResponse}; @@ -29,9 +29,11 @@ const CHUNK_SIZE: usize = 16_384; /// Dispatcher for HTTP/2 protocol #[pin_project::pin_project] -pub struct Dispatcher, B: MessageBody> +pub struct Dispatcher where T: AsyncRead + AsyncWrite + Unpin, + S: Service, + B: MessageBody, { service: CloneableService, connection: Connection, @@ -39,14 +41,14 @@ where config: ServiceConfig, peer_addr: Option, ka_expire: Instant, - ka_timer: Option, + ka_timer: Option, _t: PhantomData, } impl Dispatcher where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into, // S::Future: 'static, S::Response: Into>, @@ -57,7 +59,7 @@ where connection: Connection, on_connect_data: Extensions, config: ServiceConfig, - timeout: Option, + timeout: Option, peer_addr: Option, ) -> Self { // let keepalive = config.keep_alive_enabled(); @@ -92,7 +94,7 @@ where impl Future for Dispatcher where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, diff --git a/actix-http/src/h2/service.rs b/actix-http/src/h2/service.rs index b1fb9a634..719f3622c 100644 --- a/actix-http/src/h2/service.rs +++ b/actix-http/src/h2/service.rs @@ -36,14 +36,14 @@ pub struct H2Service { impl H2Service where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create new `HttpService` instance with config. - pub(crate) fn with_config>( + pub(crate) fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -64,18 +64,18 @@ where impl H2Service where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create simple tcp based service pub fn tcp( self, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = DispatchError, InitError = S::InitError, @@ -92,18 +92,18 @@ where #[cfg(feature = "openssl")] mod openssl { - use actix_service::{fn_factory, fn_service}; - use actix_tls::openssl::{Acceptor, SslAcceptor, SslStream}; - use actix_tls::{openssl::HandshakeError, TlsError}; + use actix_service::{fn_factory, fn_service, ServiceFactoryExt}; + use actix_tls::accept::openssl::{Acceptor, SslAcceptor, SslError, SslStream}; + use actix_tls::accept::TlsError; use super::*; impl H2Service, S, B> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create ssl based service @@ -111,10 +111,10 @@ mod openssl { self, acceptor: SslAcceptor, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), - Error = TlsError, DispatchError>, + Error = TlsError, InitError = S::InitError, > { pipeline_factory( @@ -136,16 +136,17 @@ mod openssl { #[cfg(feature = "rustls")] mod rustls { use super::*; - use actix_tls::rustls::{Acceptor, ServerConfig, TlsStream}; - use actix_tls::TlsError; + use actix_service::ServiceFactoryExt; + use actix_tls::accept::rustls::{Acceptor, ServerConfig, TlsStream}; + use actix_tls::accept::TlsError; use std::io; impl H2Service, S, B> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create openssl based service @@ -153,8 +154,8 @@ mod rustls { self, mut config: ServerConfig, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = TlsError, InitError = S::InitError, @@ -178,21 +179,20 @@ mod rustls { } } -impl ServiceFactory for H2Service +impl ServiceFactory<(T, Option)> for H2Service where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { - type Config = (); - type Request = (T, Option); type Response = (); type Error = DispatchError; - type InitError = S::InitError; + type Config = (); type Service = H2ServiceHandler; + type InitError = S::InitError; type Future = H2ServiceResponse; fn new_service(&self, _: ()) -> Self::Future { @@ -207,21 +207,24 @@ where #[doc(hidden)] #[pin_project::pin_project] -pub struct H2ServiceResponse { +pub struct H2ServiceResponse +where + S: ServiceFactory, +{ #[pin] fut: S::Future, cfg: Option, on_connect_ext: Option>>, - _t: PhantomData<(T, B)>, + _t: PhantomData, } impl Future for H2ServiceResponse where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { type Output = Result, S::InitError>; @@ -241,16 +244,19 @@ where } /// `Service` implementation for http/2 transport -pub struct H2ServiceHandler { +pub struct H2ServiceHandler +where + S: Service, +{ srv: CloneableService, cfg: ServiceConfig, on_connect_ext: Option>>, - _t: PhantomData<(T, B)>, + _t: PhantomData, } impl H2ServiceHandler where - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, @@ -270,16 +276,15 @@ where } } -impl Service for H2ServiceHandler +impl Service<(T, Option)> for H2ServiceHandler where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, B: MessageBody + 'static, { - type Request = (T, Option); type Response = (); type Error = DispatchError; type Future = H2ServiceHandlerResponse; @@ -292,7 +297,7 @@ where }) } - fn call(&mut self, (io, addr): Self::Request) -> Self::Future { + fn call(&mut self, (io, addr): (T, Option)) -> Self::Future { let mut connect_extensions = Extensions::new(); if let Some(ref handler) = self.on_connect_ext { // run on_connect_ext callback, populating connect extensions @@ -311,7 +316,7 @@ where } } -enum State, B: MessageBody> +enum State, B: MessageBody> where T: AsyncRead + AsyncWrite + Unpin, S::Future: 'static, @@ -329,7 +334,7 @@ where pub struct H2ServiceHandlerResponse where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, @@ -341,7 +346,7 @@ where impl Future for H2ServiceHandlerResponse where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, diff --git a/actix-http/src/header/shared/httpdate.rs b/actix-http/src/header/shared/httpdate.rs index 81caf6d53..d6b9d8001 100644 --- a/actix-http/src/header/shared/httpdate.rs +++ b/actix-http/src/header/shared/httpdate.rs @@ -3,7 +3,8 @@ use std::io::Write; use std::str::FromStr; use std::time::{SystemTime, UNIX_EPOCH}; -use bytes::{buf::BufMutExt, BytesMut}; +use bytes::buf::BufMut; +use bytes::BytesMut; use http::header::{HeaderValue, InvalidHeaderValue}; use time::{offset, OffsetDateTime, PrimitiveDateTime}; diff --git a/actix-http/src/request.rs b/actix-http/src/request.rs index 64e302441..0bc84a44e 100644 --- a/actix-http/src/request.rs +++ b/actix-http/src/request.rs @@ -23,6 +23,10 @@ impl

HttpMessage for Request

{ &self.head().headers } + fn take_payload(&mut self) -> Payload

{ + std::mem::replace(&mut self.payload, Payload::None) + } + /// Request extensions #[inline] fn extensions(&self) -> Ref<'_, Extensions> { @@ -34,10 +38,6 @@ impl

HttpMessage for Request

{ fn extensions_mut(&self) -> RefMut<'_, Extensions> { self.head.extensions_mut() } - - fn take_payload(&mut self) -> Payload

{ - std::mem::replace(&mut self.payload, Payload::None) - } } impl From> for Request { diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs index 527ed3833..f23115cd5 100644 --- a/actix-http/src/service.rs +++ b/actix-http/src/service.rs @@ -22,22 +22,22 @@ use crate::response::Response; use crate::{h1, h2::Dispatcher, ConnectCallback, Extensions, Protocol}; /// A `ServiceFactory` for HTTP/1.1 or HTTP/2 protocol. -pub struct HttpService> { +pub struct HttpService { srv: S, cfg: ServiceConfig, expect: X, upgrade: Option, on_connect_ext: Option>>, - _t: PhantomData<(T, B)>, + _t: PhantomData, } impl HttpService where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create builder for `HttpService` instance. @@ -48,15 +48,15 @@ where impl HttpService where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { /// Create new `HttpService` instance. - pub fn new>(service: F) -> Self { + pub fn new>(service: F) -> Self { let cfg = ServiceConfig::new(KeepAlive::Timeout(5), 5000, 0, false, None); HttpService { @@ -70,7 +70,7 @@ where } /// Create new `HttpService` instance with config. - pub(crate) fn with_config>( + pub(crate) fn with_config>( cfg: ServiceConfig, service: F, ) -> Self { @@ -87,11 +87,11 @@ where impl HttpService where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody, { /// Provide service for `EXPECT: 100-Continue` support. @@ -101,10 +101,10 @@ where /// request will be forwarded to main service. pub fn expect(self, expect: X1) -> HttpService where - X1: ServiceFactory, + X1: ServiceFactory, X1::Error: Into, X1::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, { HttpService { expect, @@ -122,14 +122,10 @@ where /// and this service get called with original request and framed object. pub fn upgrade(self, upgrade: Option) -> HttpService where - U1: ServiceFactory< - Config = (), - Request = (Request, Framed), - Response = (), - >, + U1: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U1::Error: fmt::Display, U1::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { HttpService { upgrade, @@ -150,31 +146,31 @@ where impl HttpService where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, U: ServiceFactory< + (Request, Framed), Config = (), - Request = (Request, Framed), Response = (), >, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { /// Create simple tcp stream service pub fn tcp( self, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = DispatchError, InitError = (), @@ -190,39 +186,40 @@ where #[cfg(feature = "openssl")] mod openssl { use super::*; - use actix_tls::openssl::{Acceptor, SslAcceptor, SslStream}; - use actix_tls::{openssl::HandshakeError, TlsError}; + use actix_service::ServiceFactoryExt; + use actix_tls::accept::openssl::{Acceptor, SslAcceptor, SslError, SslStream}; + use actix_tls::accept::TlsError; impl HttpService, S, B, X, U> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, U: ServiceFactory< + (Request, Framed, h1::Codec>), Config = (), - Request = (Request, Framed, h1::Codec>), Response = (), >, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, - ::Future: 'static, + , h1::Codec>)>>::Future: 'static, { /// Create openssl based service pub fn openssl( self, acceptor: SslAcceptor, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), - Error = TlsError, DispatchError>, + Error = TlsError, InitError = (), > { pipeline_factory( @@ -250,39 +247,42 @@ mod openssl { #[cfg(feature = "rustls")] mod rustls { - use super::*; - use actix_tls::rustls::{Acceptor, ServerConfig, Session, TlsStream}; - use actix_tls::TlsError; use std::io; + use actix_tls::accept::rustls::{Acceptor, ServerConfig, Session, TlsStream}; + use actix_tls::accept::TlsError; + + use super::*; + use actix_service::ServiceFactoryExt; + impl HttpService, S, B, X, U> where - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, + >::Future: 'static, U: ServiceFactory< + (Request, Framed, h1::Codec>), Config = (), - Request = (Request, Framed, h1::Codec>), Response = (), >, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, - ::Future: 'static, + , h1::Codec>)>>::Future: 'static, { /// Create openssl based service pub fn rustls( self, mut config: ServerConfig, ) -> impl ServiceFactory< + TcpStream, Config = (), - Request = TcpStream, Response = (), Error = TlsError, InitError = (), @@ -313,34 +313,30 @@ mod rustls { } } -impl ServiceFactory for HttpService +impl ServiceFactory<(T, Protocol, Option)> + for HttpService where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, - U: ServiceFactory< - Config = (), - Request = (Request, Framed), - Response = (), - >, + >::Future: 'static, + U: ServiceFactory<(Request, Framed), Config = (), Response = ()>, U::Error: fmt::Display + Into, U::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { - type Config = (); - type Request = (T, Protocol, Option); type Response = (); type Error = DispatchError; - type InitError = (); + type Config = (); type Service = HttpServiceHandler; + type InitError = (); type Future = HttpServiceResponse; fn new_service(&self, _: ()) -> Self::Future { @@ -359,13 +355,12 @@ where #[doc(hidden)] #[pin_project] -pub struct HttpServiceResponse< - T, - S: ServiceFactory, - B, - X: ServiceFactory, - U: ServiceFactory, -> { +pub struct HttpServiceResponse +where + S: ServiceFactory, + X: ServiceFactory, + U: ServiceFactory<(Request, Framed)>, +{ #[pin] fut: S::Future, #[pin] @@ -382,20 +377,20 @@ pub struct HttpServiceResponse< impl Future for HttpServiceResponse where T: AsyncRead + AsyncWrite + Unpin, - S: ServiceFactory, + S: ServiceFactory, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, - X: ServiceFactory, + X: ServiceFactory, X::Error: Into, X::InitError: fmt::Debug, - ::Future: 'static, - U: ServiceFactory), Response = ()>, + >::Future: 'static, + U: ServiceFactory<(Request, Framed), Response = ()>, U::Error: fmt::Display, U::InitError: fmt::Debug, - ::Future: 'static, + )>>::Future: 'static, { type Output = Result, ()>; @@ -440,25 +435,30 @@ where } /// `Service` implementation for http transport -pub struct HttpServiceHandler { +pub struct HttpServiceHandler +where + S: Service, + X: Service, + U: Service<(Request, Framed)>, +{ srv: CloneableService, expect: CloneableService, upgrade: Option>, cfg: ServiceConfig, on_connect_ext: Option>>, - _t: PhantomData<(T, B, X)>, + _t: PhantomData, } impl HttpServiceHandler where - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, B: MessageBody + 'static, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { fn new( @@ -479,20 +479,20 @@ where } } -impl Service for HttpServiceHandler +impl Service<(T, Protocol, Option)> + for HttpServiceHandler where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, B: MessageBody + 'static, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display + Into, { - type Request = (T, Protocol, Option); type Response = (); type Error = DispatchError; type Future = HttpServiceHandlerResponse; @@ -539,7 +539,10 @@ where } } - fn call(&mut self, (io, proto, peer_addr): Self::Request) -> Self::Future { + fn call( + &mut self, + (io, proto, peer_addr): (T, Protocol, Option), + ) -> Self::Future { let mut connect_extensions = Extensions::new(); if let Some(ref handler) = self.on_connect_ext { @@ -575,14 +578,14 @@ where #[pin_project(project = StateProj)] enum State where - S: Service, + S: Service, S::Future: 'static, S::Error: Into, T: AsyncRead + AsyncWrite + Unpin, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { H1(#[pin] h1::Dispatcher), @@ -602,14 +605,14 @@ where pub struct HttpServiceHandlerResponse where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, B: MessageBody + 'static, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { #[pin] @@ -619,14 +622,14 @@ where impl Future for HttpServiceHandlerResponse where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Future: 'static, S::Response: Into> + 'static, B: MessageBody, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { type Output = Result<(), DispatchError>; @@ -639,13 +642,13 @@ where impl State where T: AsyncRead + AsyncWrite + Unpin, - S: Service, + S: Service, S::Error: Into + 'static, S::Response: Into> + 'static, B: MessageBody + 'static, - X: Service, + X: Service, X::Error: Into, - U: Service), Response = ()>, + U: Service<(Request, Framed), Response = ()>, U::Error: fmt::Display, { fn poll( diff --git a/actix-http/src/test.rs b/actix-http/src/test.rs index 4512e72c2..3f08bb7ee 100644 --- a/actix-http/src/test.rs +++ b/actix-http/src/test.rs @@ -10,7 +10,7 @@ use std::{ task::{Context, Poll}, }; -use actix_codec::{AsyncRead, AsyncWrite}; +use actix_codec::{AsyncRead, AsyncWrite, ReadBuf}; use bytes::{Bytes, BytesMut}; use http::header::{self, HeaderName, HeaderValue}; use http::{Error as HttpError, Method, Uri, Version}; @@ -251,9 +251,11 @@ impl AsyncRead for TestBuffer { fn poll_read( self: Pin<&mut Self>, _: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - Poll::Ready(self.get_mut().read(buf)) + buf: &mut ReadBuf<'_>, + ) -> Poll> { + let dst = buf.initialize_unfilled(); + let res = self.get_mut().read(dst).map(|n| buf.advance(n)); + Poll::Ready(res) } } @@ -356,11 +358,15 @@ impl AsyncRead for TestSeqBuffer { fn poll_read( self: Pin<&mut Self>, _: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - let r = self.get_mut().read(buf); + buf: &mut ReadBuf<'_>, + ) -> Poll> { + let dst = buf.initialize_unfilled(); + let r = self.get_mut().read(dst); match r { - Ok(n) => Poll::Ready(Ok(n)), + Ok(n) => { + buf.advance(n); + Poll::Ready(Ok(())) + } Err(err) if err.kind() == io::ErrorKind::WouldBlock => Poll::Pending, Err(err) => Poll::Ready(Err(err)), } diff --git a/actix-http/src/ws/dispatcher.rs b/actix-http/src/ws/dispatcher.rs index b114217a0..7be7cf637 100644 --- a/actix-http/src/ws/dispatcher.rs +++ b/actix-http/src/ws/dispatcher.rs @@ -11,7 +11,7 @@ use super::{Codec, Frame, Message}; #[pin_project::pin_project] pub struct Dispatcher where - S: Service + 'static, + S: Service + 'static, T: AsyncRead + AsyncWrite, { #[pin] @@ -21,17 +21,17 @@ where impl Dispatcher where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Future: 'static, S::Error: 'static, { - pub fn new>(io: T, service: F) -> Self { + pub fn new>(io: T, service: F) -> Self { Dispatcher { inner: InnerDispatcher::new(Framed::new(io, Codec::new()), service), } } - pub fn with>(framed: Framed, service: F) -> Self { + pub fn with>(framed: Framed, service: F) -> Self { Dispatcher { inner: InnerDispatcher::new(framed, service), } @@ -41,7 +41,7 @@ where impl Future for Dispatcher where T: AsyncRead + AsyncWrite, - S: Service, + S: Service, S::Future: 'static, S::Error: 'static, { diff --git a/actix-http/tests/test_client.rs b/actix-http/tests/test_client.rs index 07104decc..f78636b9a 100644 --- a/actix-http/tests/test_client.rs +++ b/actix-http/tests/test_client.rs @@ -1,9 +1,8 @@ -use actix_service::ServiceFactory; -use bytes::Bytes; -use futures_util::future::{self, ok}; - use actix_http::{http, HttpService, Request, Response}; use actix_http_test::test_server; +use actix_service::ServiceFactoryExt; +use bytes::Bytes; +use futures_util::future::{self, ok}; const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ Hello World Hello World Hello World Hello World Hello World \ diff --git a/actix-http/tests/test_openssl.rs b/actix-http/tests/test_openssl.rs index 6b80bad0a..bb4732281 100644 --- a/actix-http/tests/test_openssl.rs +++ b/actix-http/tests/test_openssl.rs @@ -1,19 +1,17 @@ #![cfg(feature = "openssl")] use std::io; -use actix_http_test::test_server; -use actix_service::{fn_service, ServiceFactory}; - -use bytes::{Bytes, BytesMut}; -use futures_util::future::{err, ok, ready}; -use futures_util::stream::{once, Stream, StreamExt}; -use open_ssl::ssl::{AlpnError, SslAcceptor, SslFiletype, SslMethod}; - use actix_http::error::{ErrorBadRequest, PayloadError}; use actix_http::http::header::{self, HeaderName, HeaderValue}; use actix_http::http::{Method, StatusCode, Version}; use actix_http::httpmessage::HttpMessage; use actix_http::{body, Error, HttpService, Request, Response}; +use actix_http_test::test_server; +use actix_service::{fn_service, ServiceFactoryExt}; +use bytes::{Bytes, BytesMut}; +use futures_util::future::{err, ok, ready}; +use futures_util::stream::{once, Stream, StreamExt}; +use open_ssl::ssl::{AlpnError, SslAcceptor, SslFiletype, SslMethod}; async fn load_body(stream: S) -> Result where diff --git a/actix-http/tests/test_server.rs b/actix-http/tests/test_server.rs index 44794e199..fa1aeb695 100644 --- a/actix-http/tests/test_server.rs +++ b/actix-http/tests/test_server.rs @@ -3,7 +3,7 @@ use std::time::Duration; use std::{net, thread}; use actix_http_test::test_server; -use actix_rt::time::delay_for; +use actix_rt::time::sleep; use actix_service::fn_service; use bytes::Bytes; use futures_util::future::{self, err, ok, ready, FutureExt}; @@ -88,7 +88,7 @@ async fn test_expect_continue_h1() { let srv = test_server(|| { HttpService::build() .expect(fn_service(|req: Request| { - delay_for(Duration::from_millis(20)).then(move |_| { + sleep(Duration::from_millis(20)).then(move |_| { if req.head().uri.query() == Some("yes=") { ok(req) } else { diff --git a/actix-http/tests/test_ws.rs b/actix-http/tests/test_ws.rs index 5d86605f4..e31f2745c 100644 --- a/actix-http/tests/test_ws.rs +++ b/actix-http/tests/test_ws.rs @@ -36,11 +36,10 @@ impl Clone for WsService { } } -impl Service for WsService +impl Service<(Request, Framed)> for WsService where T: AsyncRead + AsyncWrite + Unpin + 'static, { - type Request = (Request, Framed); type Response = (); type Error = Error; type Future = Pin>>>; @@ -50,7 +49,10 @@ where Poll::Ready(Ok(())) } - fn call(&mut self, (req, mut framed): Self::Request) -> Self::Future { + fn call( + &mut self, + (req, mut framed): (Request, Framed), + ) -> Self::Future { let fut = async move { let res = ws::handshake(req.head()).unwrap().message_body(()); diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md index 0d13d5015..4c6f01d29 100644 --- a/actix-multipart/CHANGES.md +++ b/actix-multipart/CHANGES.md @@ -2,6 +2,9 @@ ## Unreleased - 2021-xx-xx * Fix multipart consuming payload before header checks #1513 +* Update `bytes` to `1.0`. [#1813] + +[#1813]: https://github.com/actix/actix-web/pull/1813 ## 3.0.0 - 2020-09-11 diff --git a/actix-multipart/Cargo.toml b/actix-multipart/Cargo.toml index e2e9dbf14..ed572a700 100644 --- a/actix-multipart/Cargo.toml +++ b/actix-multipart/Cargo.toml @@ -17,16 +17,16 @@ path = "src/lib.rs" [dependencies] actix-web = { version = "3.0.0", default-features = false } -actix-service = "1.0.6" -actix-utils = "2.0.0" -bytes = "0.5.3" +actix-utils = "3.0.0-beta.1" + +bytes = "1" derive_more = "0.99.2" httparse = "1.3" -futures-util = { version = "0.3.5", default-features = false } +futures-util = { version = "0.3.7", default-features = false } log = "0.4" mime = "0.3" twoway = "0.2" [dev-dependencies] -actix-rt = "1.0.0" +actix-rt = "2.0.0-beta.1" actix-http = "2.0.0" diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md index 0d830fe64..e47f09135 100644 --- a/actix-web-actors/CHANGES.md +++ b/actix-web-actors/CHANGES.md @@ -1,8 +1,10 @@ # Changes ## Unreleased - 2021-xx-xx -* Upgrade `pin-project` to `1.0`. +* Update `pin-project` to `1.0`. +* Update `bytes` to `1.0`. [#1813] +[#1813]: https://github.com/actix/actix-web/pull/1813 ## 3.0.0 - 2020-09-11 * No significant changes from `3.0.0-beta.2`. diff --git a/actix-web-actors/Cargo.toml b/actix-web-actors/Cargo.toml index 920940c40..28b9d6fa2 100644 --- a/actix-web-actors/Cargo.toml +++ b/actix-web-actors/Cargo.toml @@ -16,16 +16,17 @@ name = "actix_web_actors" path = "src/lib.rs" [dependencies] -actix = "0.10.0" -actix-web = { version = "3.0.0", default-features = false } +actix = "0.11.0-beta.1" +actix-codec = "0.4.0-beta.1" actix-http = "2.0.0" -actix-codec = "0.3.0" -bytes = "0.5.2" -futures-channel = { version = "0.3.5", default-features = false } -futures-core = { version = "0.3.5", default-features = false } +actix-web = { version = "3.0.0", default-features = false } + +bytes = "1" +futures-core = { version = "0.3.7", default-features = false } pin-project = "1.0.0" +tokio = { version = "1", features = ["sync"] } [dev-dependencies] -actix-rt = "1.1.1" +actix-rt = "2.0.0-beta.1" env_logger = "0.7" -futures-util = { version = "0.3.5", default-features = false } +futures-util = { version = "0.3.7", default-features = false } diff --git a/actix-web-actors/src/context.rs b/actix-web-actors/src/context.rs index 0839a4288..2dd93c727 100644 --- a/actix-web-actors/src/context.rs +++ b/actix-web-actors/src/context.rs @@ -12,8 +12,8 @@ use actix::{ }; use actix_web::error::Error; use bytes::Bytes; -use futures_channel::oneshot::Sender; use futures_core::Stream; +use tokio::sync::oneshot::Sender; /// Execution context for http actors pub struct HttpContext diff --git a/actix-web-actors/src/ws.rs b/actix-web-actors/src/ws.rs index 8fd03f6a1..9dd7bf500 100644 --- a/actix-web-actors/src/ws.rs +++ b/actix-web-actors/src/ws.rs @@ -24,8 +24,8 @@ use actix_web::error::{Error, PayloadError}; use actix_web::http::{header, Method, StatusCode}; use actix_web::{HttpRequest, HttpResponse}; use bytes::{Bytes, BytesMut}; -use futures_channel::oneshot::Sender; use futures_core::Stream; +use tokio::sync::oneshot::Sender; /// Do websocket handshake and start ws actor. pub fn start(actor: A, req: &HttpRequest, stream: T) -> Result diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml index fd99a8376..3fc4ae1be 100644 --- a/actix-web-codegen/Cargo.toml +++ b/actix-web-codegen/Cargo.toml @@ -19,8 +19,8 @@ syn = { version = "1", features = ["full", "parsing"] } proc-macro2 = "1" [dev-dependencies] -actix-rt = "1.1.1" +actix-rt = "2.0.0-beta.1" actix-web = "3.0.0" -futures-util = { version = "0.3.5", default-features = false } +futures-util = { version = "0.3.7", default-features = false } trybuild = "1" rustversion = "1" diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs index dd2bccd7f..389d09c82 100644 --- a/actix-web-codegen/tests/test_macro.rs +++ b/actix-web-codegen/tests/test_macro.rs @@ -88,17 +88,16 @@ async fn route_test() -> impl Responder { pub struct ChangeStatusCode; -impl Transform for ChangeStatusCode +impl Transform for ChangeStatusCode where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; - type InitError = (); type Transform = ChangeStatusCodeMiddleware; + type InitError = (); type Future = future::Ready>; fn new_transform(&self, service: S) -> Self::Future { @@ -110,13 +109,12 @@ pub struct ChangeStatusCodeMiddleware { service: S, } -impl Service for ChangeStatusCodeMiddleware +impl Service for ChangeStatusCodeMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; #[allow(clippy::type_complexity)] diff --git a/awc/CHANGES.md b/awc/CHANGES.md index ee795fccb..45a38259c 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,7 +2,11 @@ ## Unreleased - 2021-xx-xx ### Changed -* Bumped `rand` to `0.8` +* Update `rand` to `0.8` +* Update `bytes` to `1.0`. [#1813] +* Update `rust-tls` to `0.19`. [#1813] + +[#1813]: https://github.com/actix/actix-web/pull/1813 ## 2.0.3 - 2020-11-29 diff --git a/awc/Cargo.toml b/awc/Cargo.toml index 2e92526d2..b80f1ba6b 100644 --- a/awc/Cargo.toml +++ b/awc/Cargo.toml @@ -37,16 +37,16 @@ rustls = ["rust-tls", "actix-http/rustls"] compress = ["actix-http/compress"] [dependencies] -actix-codec = "0.3.0" -actix-service = "1.0.6" +actix-codec = "0.4.0-beta.1" +actix-service = "2.0.0-beta.2" actix-http = "2.2.0" -actix-rt = "1.0.0" +actix-rt = "2.0.0-beta.1" base64 = "0.13" -bytes = "0.5.3" +bytes = "1" cfg-if = "1.0" derive_more = "0.99.2" -futures-core = { version = "0.3.5", default-features = false } +futures-core = { version = "0.3.7", default-features = false } log =" 0.4" mime = "0.3" percent-encoding = "2.1" @@ -55,18 +55,20 @@ serde = "1.0" serde_json = "1.0" serde_urlencoded = "0.7" open-ssl = { version = "0.10", package = "openssl", optional = true } -rust-tls = { version = "0.18.0", package = "rustls", optional = true, features = ["dangerous_configuration"] } +rust-tls = { version = "0.19.0", package = "rustls", optional = true, features = ["dangerous_configuration"] } [dev-dependencies] -actix-connect = { version = "2.0.0", features = ["openssl"] } +# TODO: actix is temporary added as dev dep for actix-macro reason. +# Can be removed when it does not impact tests. +actix = "0.11.0-beta.1" actix-web = { version = "3.0.0", features = ["openssl"] } actix-http = { version = "2.0.0", features = ["openssl"] } actix-http-test = { version = "2.0.0", features = ["openssl"] } -actix-utils = "2.0.0" -actix-server = "1.0.0" -actix-tls = { version = "2.0.0", features = ["openssl", "rustls"] } +actix-utils = "3.0.0-beta.1" +actix-server = "2.0.0-beta.2" +actix-tls = { version = "3.0.0-beta.2", features = ["openssl", "rustls"] } brotli2 = "0.3.2" flate2 = "1.0.13" -futures-util = { version = "0.3.5", default-features = false } +futures-util = { version = "0.3.7", default-features = false } env_logger = "0.7" webpki = "0.21" diff --git a/awc/src/builder.rs b/awc/src/builder.rs index 7cd659c38..6be0112d8 100644 --- a/awc/src/builder.rs +++ b/awc/src/builder.rs @@ -51,7 +51,7 @@ impl ClientBuilder { /// Use custom connector service. pub fn connector(mut self, connector: T) -> Self where - T: Service + 'static, + T: Service + 'static, T::Response: Connection, ::Future: 'static, T::Future: 'static, diff --git a/awc/src/connect.rs b/awc/src/connect.rs index 7fbe1543a..8ee239f76 100644 --- a/awc/src/connect.rs +++ b/awc/src/connect.rs @@ -2,9 +2,9 @@ use std::future::Future; use std::pin::Pin; use std::rc::Rc; use std::task::{Context, Poll}; -use std::{fmt, io, mem, net}; +use std::{fmt, io, net}; -use actix_codec::{AsyncRead, AsyncWrite, Framed}; +use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf}; use actix_http::body::Body; use actix_http::client::{ Connect as ClientConnect, ConnectError, Connection, SendRequestError, @@ -70,7 +70,7 @@ pub(crate) trait Connect { impl Connect for ConnectorWrapper where - T: Service, + T: Service, T::Response: Connection, ::Io: 'static, ::Future: 'static, @@ -221,18 +221,11 @@ impl fmt::Debug for BoxedSocket { } impl AsyncRead for BoxedSocket { - unsafe fn prepare_uninitialized_buffer( - &self, - buf: &mut [mem::MaybeUninit], - ) -> bool { - self.0.as_read().prepare_uninitialized_buffer(buf) - } - fn poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { + buf: &mut ReadBuf<'_>, + ) -> Poll> { Pin::new(self.get_mut().0.as_read_mut()).poll_read(cx, buf) } } diff --git a/awc/src/sender.rs b/awc/src/sender.rs index 0bcdf4307..b5ff61da5 100644 --- a/awc/src/sender.rs +++ b/awc/src/sender.rs @@ -5,7 +5,7 @@ use std::rc::Rc; use std::task::{Context, Poll}; use std::time::Duration; -use actix_rt::time::{delay_for, Delay}; +use actix_rt::time::{sleep, Sleep}; use bytes::Bytes; use derive_more::From; use futures_core::Stream; @@ -56,7 +56,8 @@ impl Into for PrepForSendingError { pub enum SendClientRequest { Fut( Pin>>>, - Option, + // FIXME: use a pinned Sleep instead of box. + Option>>, bool, ), Err(Option), @@ -68,7 +69,7 @@ impl SendClientRequest { response_decompress: bool, timeout: Option, ) -> SendClientRequest { - let delay = timeout.map(delay_for); + let delay = timeout.map(|d| Box::pin(sleep(d))); SendClientRequest::Fut(send, delay, response_decompress) } } diff --git a/awc/tests/test_client.rs b/awc/tests/test_client.rs index 0024c6652..1b7413312 100644 --- a/awc/tests/test_client.rs +++ b/awc/tests/test_client.rs @@ -108,14 +108,14 @@ async fn test_form() { async fn test_timeout() { let srv = test::start(|| { App::new().service(web::resource("/").route(web::to(|| async { - actix_rt::time::delay_for(Duration::from_millis(200)).await; + actix_rt::time::sleep(Duration::from_millis(200)).await; Ok::<_, Error>(HttpResponse::Ok().body(STR)) }))) }); let connector = awc::Connector::new() - .connector(actix_connect::new_connector( - actix_connect::start_default_resolver().await.unwrap(), + .connector(actix_tls::connect::new_connector( + actix_tls::connect::start_default_resolver().await.unwrap(), )) .timeout(Duration::from_secs(15)) .finish(); @@ -136,7 +136,7 @@ async fn test_timeout() { async fn test_timeout_override() { let srv = test::start(|| { App::new().service(web::resource("/").route(web::to(|| async { - actix_rt::time::delay_for(Duration::from_millis(200)).await; + actix_rt::time::sleep(Duration::from_millis(200)).await; Ok::<_, Error>(HttpResponse::Ok().body(STR)) }))) }); diff --git a/awc/tests/test_connector.rs b/awc/tests/test_connector.rs index 888f7a900..e500801c4 100644 --- a/awc/tests/test_connector.rs +++ b/awc/tests/test_connector.rs @@ -1,7 +1,7 @@ #![cfg(feature = "openssl")] use actix_http::HttpService; use actix_http_test::test_server; -use actix_service::{map_config, ServiceFactory}; +use actix_service::{map_config, ServiceFactoryExt}; use actix_web::http::Version; use actix_web::{dev::AppConfig, web, App, HttpResponse}; use open_ssl::ssl::{SslAcceptor, SslConnector, SslFiletype, SslMethod, SslVerifyMode}; diff --git a/awc/tests/test_rustls_client.rs b/awc/tests/test_rustls_client.rs index 0df6b154c..3fa76d4a9 100644 --- a/awc/tests/test_rustls_client.rs +++ b/awc/tests/test_rustls_client.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use actix_http::HttpService; use actix_http_test::test_server; -use actix_service::{map_config, pipeline_factory, ServiceFactory}; +use actix_service::{map_config, pipeline_factory, ServiceFactoryExt}; use actix_web::http::Version; use actix_web::{dev::AppConfig, web, App, HttpResponse}; use futures_util::future::ok; diff --git a/awc/tests/test_ssl_client.rs b/awc/tests/test_ssl_client.rs index eced5f14b..de1514042 100644 --- a/awc/tests/test_ssl_client.rs +++ b/awc/tests/test_ssl_client.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use actix_http::HttpService; use actix_http_test::test_server; -use actix_service::{map_config, pipeline_factory, ServiceFactory}; +use actix_service::{map_config, pipeline_factory, ServiceFactoryExt}; use actix_web::http::Version; use actix_web::{dev::AppConfig, web, App, HttpResponse}; use futures_util::future::ok; diff --git a/benches/server.rs b/benches/server.rs index 041d0fa57..117b6136e 100644 --- a/benches/server.rs +++ b/benches/server.rs @@ -29,18 +29,22 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ fn bench_async_burst(c: &mut Criterion) { // We are using System here, since Runtime requires preinitialized tokio // Maybe add to actix_rt docs - let mut rt = actix_rt::System::new("test"); + let rt = actix_rt::System::new("test"); - let srv = test::start(|| { - App::new() - .service(web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR)))) + let srv = rt.block_on(async { + test::start(|| { + App::new().service( + web::resource("/").route(web::to(|| HttpResponse::Ok().body(STR))), + ) + }) }); let url = srv.url("/"); c.bench_function("get_body_async_burst", move |b| { b.iter_custom(|iters| { - let client = Client::new().get(url.clone()).freeze().unwrap(); + let client = + rt.block_on(async { Client::new().get(url.clone()).freeze().unwrap() }); let start = std::time::Instant::now(); // benchmark body diff --git a/benches/service.rs b/benches/service.rs index 8adbc8a0c..8ca6cbe28 100644 --- a/benches/service.rs +++ b/benches/service.rs @@ -23,10 +23,9 @@ use actix_web::test::{init_service, ok_service, TestRequest}; /// async_service_direct time: [1.0908 us 1.1656 us 1.2613 us] pub fn bench_async_service(c: &mut Criterion, srv: S, name: &str) where - S: Service - + 'static, + S: Service + 'static, { - let mut rt = actix_rt::System::new("test"); + let rt = actix_rt::System::new("test"); let srv = Rc::new(RefCell::new(srv)); let req = TestRequest::default().to_srv_request(); @@ -41,14 +40,15 @@ where b.iter_custom(|iters| { let srv = srv.clone(); // exclude request generation, it appears it takes significant time vs call (3us vs 1us) - let reqs: Vec<_> = (0..iters) + let futs = (0..iters) .map(|_| TestRequest::default().to_srv_request()) - .collect(); + .map(|req| srv.borrow_mut().call(req)); + let start = std::time::Instant::now(); // benchmark body rt.block_on(async move { - for req in reqs { - srv.borrow_mut().call(req).await.unwrap(); + for fut in futs { + fut.await.unwrap(); } }); let elapsed = start.elapsed(); @@ -67,7 +67,7 @@ async fn index(req: ServiceRequest) -> Result { // Sample results on MacBook Pro '14 // time: [2.0724 us 2.1345 us 2.2074 us] fn async_web_service(c: &mut Criterion) { - let mut rt = actix_rt::System::new("test"); + let rt = actix_rt::System::new("test"); let srv = Rc::new(RefCell::new(rt.block_on(init_service( App::new().service(web::service("/").finish(index)), )))); @@ -83,13 +83,14 @@ fn async_web_service(c: &mut Criterion) { c.bench_function("async_web_service_direct", move |b| { b.iter_custom(|iters| { let srv = srv.clone(); - let reqs = (0..iters).map(|_| TestRequest::get().uri("/").to_request()); - + let futs = (0..iters) + .map(|_| TestRequest::get().uri("/").to_request()) + .map(|req| srv.borrow_mut().call(req)); let start = std::time::Instant::now(); // benchmark body rt.block_on(async move { - for req in reqs { - srv.borrow_mut().call(req).await.unwrap(); + for fut in futs { + fut.await.unwrap(); } }); let elapsed = start.elapsed(); diff --git a/src/app.rs b/src/app.rs index 8dd86f7ec..d41d692ee 100644 --- a/src/app.rs +++ b/src/app.rs @@ -5,10 +5,11 @@ use std::marker::PhantomData; use std::rc::Rc; use actix_http::body::{Body, MessageBody}; -use actix_http::Extensions; +use actix_http::{Extensions, Request}; use actix_service::boxed::{self, BoxServiceFactory}; use actix_service::{ - apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, Transform, + apply, apply_fn_factory, IntoServiceFactory, ServiceFactory, ServiceFactoryExt, + Transform, }; use futures_util::future::FutureExt; @@ -63,8 +64,8 @@ impl App where B: MessageBody, T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -268,10 +269,10 @@ where /// ``` pub fn default_service(mut self, f: F) -> Self where - F: IntoServiceFactory, + F: IntoServiceFactory, U: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, > + 'static, @@ -353,8 +354,8 @@ where mw: M, ) -> App< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -364,7 +365,7 @@ where where M: Transform< T::Service, - Request = ServiceRequest, + ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -420,8 +421,8 @@ where mw: F, ) -> App< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -447,12 +448,12 @@ where } } -impl IntoServiceFactory> for App +impl IntoServiceFactory, Request> for App where B: MessageBody, T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), diff --git a/src/app_service.rs b/src/app_service.rs index 4452778df..f02bb831a 100644 --- a/src/app_service.rs +++ b/src/app_service.rs @@ -29,8 +29,8 @@ type BoxResponse = LocalBoxFuture<'static, Result>; pub struct AppInit where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -46,22 +46,21 @@ where pub(crate) external: RefCell>, } -impl ServiceFactory for AppInit +impl ServiceFactory for AppInit where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), >, { - type Config = AppConfig; - type Request = Request; type Response = ServiceResponse; type Error = T::Error; - type InitError = T::InitError; + type Config = AppConfig; type Service = AppInitService; + type InitError = T::InitError; type Future = AppInitResult; fn new_service(&self, config: AppConfig) -> Self::Future { @@ -132,7 +131,7 @@ where #[pin_project::pin_project] pub struct AppInitResult where - T: ServiceFactory, + T: ServiceFactory, { #[pin] endpoint_fut: T::Future, @@ -155,8 +154,8 @@ where impl Future for AppInitResult where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -214,7 +213,7 @@ where /// Service to convert `Request` to a `ServiceRequest` pub struct AppInitService where - T: Service, Error = Error>, + T: Service, Error = Error>, { service: T, rmap: Rc, @@ -223,11 +222,10 @@ where pool: &'static HttpRequestPool, } -impl Service for AppInitService +impl Service for AppInitService where - T: Service, Error = Error>, + T: Service, Error = Error>, { - type Request = Request; type Response = ServiceResponse; type Error = T::Error; type Future = T::Future; @@ -263,7 +261,7 @@ where impl Drop for AppInitService where - T: Service, Error = Error>, + T: Service, Error = Error>, { fn drop(&mut self) { self.pool.clear(); @@ -275,9 +273,8 @@ pub struct AppRoutingFactory { default: Rc, } -impl ServiceFactory for AppRoutingFactory { +impl ServiceFactory for AppRoutingFactory { type Config = (); - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -386,8 +383,7 @@ pub struct AppRouting { default: Option, } -impl Service for AppRouting { - type Request = ServiceRequest; +impl Service for AppRouting { type Response = ServiceResponse; type Error = Error; type Future = BoxResponse; @@ -434,9 +430,8 @@ impl AppEntry { } } -impl ServiceFactory for AppEntry { +impl ServiceFactory for AppEntry { type Config = (); - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); diff --git a/src/config.rs b/src/config.rs index 01959daa1..4ec36952a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -105,10 +105,10 @@ impl AppService { factory: F, nested: Option>, ) where - F: IntoServiceFactory, + F: IntoServiceFactory, S: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), diff --git a/src/handler.rs b/src/handler.rs index d4b755e57..14e8cb40b 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -82,14 +82,13 @@ where } } -impl ServiceFactory for HandlerService +impl ServiceFactory for HandlerService where F: Handler, T: FromRequest, R: Future, R::Output: Responder, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Config = (); @@ -102,15 +101,14 @@ where } } -// Handler is both it's ServiceHandler and Service Type. -impl Service for HandlerService +// HandlerService is both it's ServiceFactory and Service Type. +impl Service for HandlerService where F: Handler, T: FromRequest, R: Future, R::Output: Responder, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = HandlerServiceFuture; @@ -119,7 +117,7 @@ where Poll::Ready(Ok(())) } - fn call(&mut self, req: Self::Request) -> Self::Future { + fn call(&mut self, req: ServiceRequest) -> Self::Future { let (req, mut payload) = req.into_parts(); let fut = T::from_request(&req, &mut payload); HandlerServiceFuture::Extract(fut, Some(req), self.hnd.clone()) diff --git a/src/middleware/compress.rs b/src/middleware/compress.rs index 7575d7455..faff5003a 100644 --- a/src/middleware/compress.rs +++ b/src/middleware/compress.rs @@ -51,16 +51,15 @@ impl Default for Compress { } } -impl Transform for Compress +impl Transform for Compress where B: MessageBody, - S: Service, Error = Error>, + S: Service, Error = Error>, { - type Request = ServiceRequest; type Response = ServiceResponse>; type Error = Error; - type InitError = (); type Transform = CompressMiddleware; + type InitError = (); type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { @@ -76,12 +75,11 @@ pub struct CompressMiddleware { encoding: ContentEncoding, } -impl Service for CompressMiddleware +impl Service for CompressMiddleware where B: MessageBody, - S: Service, Error = Error>, + S: Service, Error = Error>, { - type Request = ServiceRequest; type Response = ServiceResponse>; type Error = Error; type Future = CompressResponse; @@ -115,7 +113,7 @@ where #[pin_project] pub struct CompressResponse where - S: Service, + S: Service, B: MessageBody, { #[pin] @@ -127,7 +125,7 @@ where impl Future for CompressResponse where B: MessageBody, - S: Service, Error = Error>, + S: Service, Error = Error>, { type Output = Result>, Error>; diff --git a/src/middleware/condition.rs b/src/middleware/condition.rs index 9061c7458..87323e325 100644 --- a/src/middleware/condition.rs +++ b/src/middleware/condition.rs @@ -31,19 +31,18 @@ impl Condition { } } -impl Transform for Condition +impl Transform for Condition where - S: Service + 'static, - T: Transform, + S: Service + 'static, + T: Transform, T::Future: 'static, T::InitError: 'static, T::Transform: 'static, { - type Request = S::Request; type Response = S::Response; type Error = S::Error; - type InitError = T::InitError; type Transform = ConditionMiddleware; + type InitError = T::InitError; type Future = LocalBoxFuture<'static, Result>; fn new_transform(&self, service: S) -> Self::Future { @@ -66,12 +65,11 @@ pub enum ConditionMiddleware { Disable(D), } -impl Service for ConditionMiddleware +impl Service for ConditionMiddleware where - E: Service, - D: Service, + E: Service, + D: Service, { - type Request = E::Request; type Response = E::Response; type Error = E::Error; type Future = Either; @@ -84,7 +82,7 @@ where } } - fn call(&mut self, req: E::Request) -> Self::Future { + fn call(&mut self, req: Req) -> Self::Future { use ConditionMiddleware::*; match self { Enable(service) => Either::Left(service.call(req)), diff --git a/src/middleware/defaultheaders.rs b/src/middleware/defaultheaders.rs index a6f1a4336..d648ad70f 100644 --- a/src/middleware/defaultheaders.rs +++ b/src/middleware/defaultheaders.rs @@ -93,12 +93,11 @@ impl DefaultHeaders { } } -impl Transform for DefaultHeaders +impl Transform for DefaultHeaders where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Transform = DefaultHeadersMiddleware; @@ -118,12 +117,11 @@ pub struct DefaultHeadersMiddleware { inner: Rc, } -impl Service for DefaultHeadersMiddleware +impl Service for DefaultHeadersMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = DefaultHeaderFuture; @@ -145,7 +143,7 @@ where } #[pin_project::pin_project] -pub struct DefaultHeaderFuture { +pub struct DefaultHeaderFuture, B> { #[pin] fut: S::Future, inner: Rc, @@ -154,7 +152,7 @@ pub struct DefaultHeaderFuture { impl Future for DefaultHeaderFuture where - S: Service, Error = Error>, + S: Service, Error = Error>, { type Output = ::Output; diff --git a/src/middleware/errhandlers.rs b/src/middleware/errhandlers.rs index d2d3b0d8c..9e78bb7d0 100644 --- a/src/middleware/errhandlers.rs +++ b/src/middleware/errhandlers.rs @@ -81,17 +81,16 @@ impl ErrorHandlers { } } -impl Transform for ErrorHandlers +impl Transform for ErrorHandlers where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; - type InitError = (); type Transform = ErrorHandlersMiddleware; + type InitError = (); type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { @@ -108,13 +107,12 @@ pub struct ErrorHandlersMiddleware { handlers: Rc>>>, } -impl Service for ErrorHandlersMiddleware +impl Service for ErrorHandlersMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, B: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; diff --git a/src/middleware/logger.rs b/src/middleware/logger.rs index 563cb6c32..2a543f66f 100644 --- a/src/middleware/logger.rs +++ b/src/middleware/logger.rs @@ -179,12 +179,11 @@ impl Default for Logger { } } -impl Transform for Logger +impl Transform for Logger where - S: Service, Error = Error>, + S: Service, Error = Error>, B: MessageBody, { - type Request = ServiceRequest; type Response = ServiceResponse>; type Error = Error; type InitError = (); @@ -216,12 +215,11 @@ pub struct LoggerMiddleware { service: S, } -impl Service for LoggerMiddleware +impl Service for LoggerMiddleware where - S: Service, Error = Error>, + S: Service, Error = Error>, B: MessageBody, { - type Request = ServiceRequest; type Response = ServiceResponse>; type Error = Error; type Future = LoggerResponse; @@ -262,19 +260,19 @@ where pub struct LoggerResponse where B: MessageBody, - S: Service, + S: Service, { #[pin] fut: S::Future, time: OffsetDateTime, format: Option, - _t: PhantomData<(B,)>, + _t: PhantomData, } impl Future for LoggerResponse where B: MessageBody, - S: Service, Error = Error>, + S: Service, Error = Error>, { type Output = Result>, Error>; diff --git a/src/middleware/normalize.rs b/src/middleware/normalize.rs index ad9f51079..4109364bf 100644 --- a/src/middleware/normalize.rs +++ b/src/middleware/normalize.rs @@ -91,16 +91,15 @@ impl NormalizePath { } } -impl Transform for NormalizePath +impl Transform for NormalizePath where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; - type InitError = (); type Transform = NormalizePathNormalization; + type InitError = (); type Future = Ready>; fn new_transform(&self, service: S) -> Self::Future { @@ -119,12 +118,11 @@ pub struct NormalizePathNormalization { trailing_slash_behavior: TrailingSlash, } -impl Service for NormalizePathNormalization +impl Service for NormalizePathNormalization where - S: Service, Error = Error>, + S: Service, Error = Error>, S::Future: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = S::Future; diff --git a/src/resource.rs b/src/resource.rs index 29a7daa78..7d53ef936 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -9,7 +9,8 @@ use actix_http::{Error, Extensions, Response}; use actix_router::IntoPattern; use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{ - apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform, + apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, + ServiceFactoryExt, Transform, }; use futures_core::future::LocalBoxFuture; @@ -78,8 +79,8 @@ impl Resource { impl Resource where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -250,8 +251,8 @@ where mw: M, ) -> Resource< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -260,7 +261,7 @@ where where M: Transform< T::Service, - Request = ServiceRequest, + ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -317,8 +318,8 @@ where mw: F, ) -> Resource< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -345,10 +346,10 @@ where /// default handler from `App` or `Scope`. pub fn default_service(mut self, f: F) -> Self where - F: IntoServiceFactory, + F: IntoServiceFactory, U: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, > + 'static, @@ -368,8 +369,8 @@ where impl HttpServiceFactory for Resource where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -398,11 +399,11 @@ where } } -impl IntoServiceFactory for Resource +impl IntoServiceFactory for Resource where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -425,13 +426,12 @@ pub struct ResourceFactory { default: Rc>>>, } -impl ServiceFactory for ResourceFactory { - type Config = (); - type Request = ServiceRequest; +impl ServiceFactory for ResourceFactory { type Response = ServiceResponse; type Error = Error; - type InitError = (); + type Config = (); type Service = ResourceService; + type InitError = (); type Future = CreateResourceService; fn new_service(&self, _: ()) -> Self::Future { @@ -520,8 +520,7 @@ pub struct ResourceService { default: Option, } -impl Service for ResourceService { - type Request = ServiceRequest; +impl Service for ResourceService { type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; @@ -567,9 +566,8 @@ impl ResourceEndpoint { } } -impl ServiceFactory for ResourceEndpoint { +impl ServiceFactory for ResourceEndpoint { type Config = (); - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -585,7 +583,7 @@ impl ServiceFactory for ResourceEndpoint { mod tests { use std::time::Duration; - use actix_rt::time::delay_for; + use actix_rt::time::sleep; use actix_service::Service; use futures_util::future::ok; @@ -653,7 +651,7 @@ mod tests { async fn test_to() { let mut srv = init_service(App::new().service(web::resource("/test").to(|| async { - delay_for(Duration::from_millis(100)).await; + sleep(Duration::from_millis(100)).await; Ok::<_, Error>(HttpResponse::Ok()) }))) .await; diff --git a/src/route.rs b/src/route.rs index 00d93fce9..8a3d1da9f 100644 --- a/src/route.rs +++ b/src/route.rs @@ -18,7 +18,7 @@ use crate::HttpResponse; type BoxedRouteService = Box< dyn Service< - Request = ServiceRequest, + ServiceRequest, Response = ServiceResponse, Error = Error, Future = LocalBoxFuture<'static, Result>, @@ -27,8 +27,8 @@ type BoxedRouteService = Box< type BoxedRouteNewService = Box< dyn ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -63,9 +63,8 @@ impl Route { } } -impl ServiceFactory for Route { +impl ServiceFactory for Route { type Config = (); - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -117,8 +116,7 @@ impl RouteService { } } -impl Service for RouteService { - type Request = ServiceRequest; +impl Service for RouteService { type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; @@ -233,7 +231,7 @@ impl Route { struct RouteNewService where - T: ServiceFactory, + T: ServiceFactory, { service: T, } @@ -241,33 +239,32 @@ where impl RouteNewService where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, >, T::Future: 'static, T::Service: 'static, - ::Future: 'static, + >::Future: 'static, { pub fn new(service: T) -> Self { RouteNewService { service } } } -impl ServiceFactory for RouteNewService +impl ServiceFactory for RouteNewService where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, >, T::Future: 'static, T::Service: 'static, - ::Future: 'static, + >::Future: 'static, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Config = (); @@ -289,16 +286,15 @@ where } } -struct RouteServiceWrapper { +struct RouteServiceWrapper> { service: T, } -impl Service for RouteServiceWrapper +impl Service for RouteServiceWrapper where T::Future: 'static, - T: Service, + T: Service, { - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; @@ -316,7 +312,7 @@ where mod tests { use std::time::Duration; - use actix_rt::time::delay_for; + use actix_rt::time::sleep; use bytes::Bytes; use serde_derive::Serialize; @@ -340,16 +336,16 @@ mod tests { Err::(error::ErrorBadRequest("err")) })) .route(web::post().to(|| async { - delay_for(Duration::from_millis(100)).await; + sleep(Duration::from_millis(100)).await; Ok::<_, ()>(HttpResponse::Created()) })) .route(web::delete().to(|| async { - delay_for(Duration::from_millis(100)).await; + sleep(Duration::from_millis(100)).await; Err::(error::ErrorBadRequest("err")) })), ) .service(web::resource("/json").route(web::get().to(|| async { - delay_for(Duration::from_millis(25)).await; + sleep(Duration::from_millis(25)).await; web::Json(MyObject { name: "test".to_string(), }) diff --git a/src/scope.rs b/src/scope.rs index ce8d94159..419e572aa 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -9,7 +9,8 @@ use actix_http::{Extensions, Response}; use actix_router::{ResourceDef, ResourceInfo, Router}; use actix_service::boxed::{self, BoxService, BoxServiceFactory}; use actix_service::{ - apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, Transform, + apply, apply_fn_factory, IntoServiceFactory, Service, ServiceFactory, + ServiceFactoryExt, Transform, }; use futures_core::future::LocalBoxFuture; @@ -88,8 +89,8 @@ impl Scope { impl Scope where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -284,10 +285,10 @@ where /// If default resource is not registered, app's default resource is being used. pub fn default_service(mut self, f: F) -> Self where - F: IntoServiceFactory, + F: IntoServiceFactory, U: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, > + 'static, @@ -317,8 +318,8 @@ where mw: M, ) -> Scope< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -327,7 +328,7 @@ where where M: Transform< T::Service, - Request = ServiceRequest, + ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -382,8 +383,8 @@ where mw: F, ) -> Scope< impl ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -409,8 +410,8 @@ where impl HttpServiceFactory for Scope where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -480,9 +481,8 @@ pub struct ScopeFactory { default: Rc>>>, } -impl ServiceFactory for ScopeFactory { +impl ServiceFactory for ScopeFactory { type Config = (); - type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); @@ -601,8 +601,7 @@ pub struct ScopeService { _ready: Option<(ServiceRequest, ResourceInfo)>, } -impl Service for ScopeService { - type Request = ServiceRequest; +impl Service for ScopeService { type Response = ServiceResponse; type Error = Error; type Future = LocalBoxFuture<'static, Result>; @@ -653,13 +652,12 @@ impl ScopeEndpoint { } } -impl ServiceFactory for ScopeEndpoint { - type Config = (); - type Request = ServiceRequest; +impl ServiceFactory for ScopeEndpoint { type Response = ServiceResponse; type Error = Error; - type InitError = (); + type Config = (); type Service = ScopeService; + type InitError = (); type Future = ScopeFactoryResponse; fn new_service(&self, _: ()) -> Self::Future { diff --git a/src/server.rs b/src/server.rs index be97e8a0d..fc80cbed8 100644 --- a/src/server.rs +++ b/src/server.rs @@ -20,9 +20,9 @@ use actix_service::pipeline_factory; use futures_util::future::ok; #[cfg(feature = "openssl")] -use actix_tls::openssl::{AlpnError, SslAcceptor, SslAcceptorBuilder}; +use actix_tls::accept::openssl::{AlpnError, SslAcceptor, SslAcceptorBuilder}; #[cfg(feature = "rustls")] -use actix_tls::rustls::ServerConfig as RustlsServerConfig; +use actix_tls::accept::rustls::ServerConfig as RustlsServerConfig; use crate::config::AppConfig; @@ -58,8 +58,8 @@ struct Config { pub struct HttpServer where F: Fn() -> I + Send + Clone + 'static, - I: IntoServiceFactory, - S: ServiceFactory, + I: IntoServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, @@ -67,7 +67,7 @@ where { pub(super) factory: F, config: Arc>, - backlog: i32, + backlog: u32, sockets: Vec, builder: ServerBuilder, on_connect_fn: Option>, @@ -77,12 +77,13 @@ where impl HttpServer where F: Fn() -> I + Send + Clone + 'static, - I: IntoServiceFactory, - S: ServiceFactory, + I: IntoServiceFactory, + S: ServiceFactory + 'static, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, + S::Service: 'static, B: MessageBody + 'static, { /// Create new http server with application factory @@ -147,7 +148,7 @@ where /// Generally set in the 64-2048 range. Default value is 2048. /// /// This method should be called before `bind()` method call. - pub fn backlog(mut self, backlog: i32) -> Self { + pub fn backlog(mut self, backlog: u32) -> Self { self.backlog = backlog; self.builder = self.builder.backlog(backlog); self @@ -170,8 +171,10 @@ where /// limit the global TLS CPU usage. /// /// By default max connections is set to a 256. + #[allow(unused_variables)] pub fn max_connection_rate(self, num: usize) -> Self { - actix_tls::max_concurrent_tls_connect(num); + #[cfg(any(feature = "rustls", feature = "openssl"))] + actix_tls::accept::max_concurrent_tls_connect(num); self } @@ -603,8 +606,8 @@ where impl HttpServer where F: Fn() -> I + Send + Clone + 'static, - I: IntoServiceFactory, - S: ServiceFactory, + I: IntoServiceFactory, + S: ServiceFactory, S::Error: Into, S::InitError: fmt::Debug, S::Response: Into>, @@ -639,7 +642,7 @@ where fn create_tcp_listener( addr: net::SocketAddr, - backlog: i32, + backlog: u32, ) -> io::Result { use socket2::{Domain, Protocol, Socket, Type}; let domain = match addr { @@ -649,6 +652,8 @@ fn create_tcp_listener( let socket = Socket::new(domain, Type::stream(), Some(Protocol::tcp()))?; socket.set_reuse_address(true)?; socket.bind(&addr.into())?; + // clamp backlog to max u32 that fits in i32 range + let backlog = backlog.min(i32::MAX as u32) as i32; socket.listen(backlog)?; Ok(socket.into_tcp_listener()) } diff --git a/src/service.rs b/src/service.rs index 189ba5554..85bc6123d 100644 --- a/src/service.rs +++ b/src/service.rs @@ -486,10 +486,10 @@ impl WebService { /// Set a service factory implementation and generate web service. pub fn finish(self, service: F) -> impl HttpServiceFactory where - F: IntoServiceFactory, + F: IntoServiceFactory, T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), @@ -514,8 +514,8 @@ struct WebServiceImpl { impl HttpServiceFactory for WebServiceImpl where T: ServiceFactory< + ServiceRequest, Config = (), - Request = ServiceRequest, Response = ServiceResponse, Error = Error, InitError = (), diff --git a/src/test.rs b/src/test.rs index cff6c3e51..a76bae6a6 100644 --- a/src/test.rs +++ b/src/test.rs @@ -11,7 +11,7 @@ use actix_http::http::{Error as HttpError, Method, StatusCode, Uri, Version}; use actix_http::test::TestRequest as HttpTestRequest; use actix_http::{cookie::Cookie, ws, Extensions, HttpService, Request}; use actix_router::{Path, ResourceDef, Url}; -use actix_rt::{time::delay_for, System}; +use actix_rt::{time::sleep, System}; use actix_service::{ map_config, IntoService, IntoServiceFactory, Service, ServiceFactory, }; @@ -37,16 +37,14 @@ use crate::{Error, HttpRequest, HttpResponse}; /// Create service that always responds with `HttpResponse::Ok()` pub fn ok_service( -) -> impl Service, Error = Error> -{ +) -> impl Service, Error = Error> { default_service(StatusCode::OK) } /// Create service that responds with response with specified status code pub fn default_service( status_code: StatusCode, -) -> impl Service, Error = Error> -{ +) -> impl Service, Error = Error> { (move |req: ServiceRequest| { ok(req.into_response(HttpResponse::build(status_code).finish())) }) @@ -77,12 +75,12 @@ pub fn default_service( /// ``` pub async fn init_service( app: R, -) -> impl Service, Error = E> +) -> impl Service, Error = E> where - R: IntoServiceFactory, + R: IntoServiceFactory, S: ServiceFactory< + Request, Config = AppConfig, - Request = Request, Response = ServiceResponse, Error = E, >, @@ -96,15 +94,12 @@ where /// Fallible version of init_service that allows testing data factory errors. pub(crate) async fn try_init_service( app: R, -) -> Result< - impl Service, Error = E>, - S::InitError, -> +) -> Result, Error = E>, S::InitError> where - R: IntoServiceFactory, + R: IntoServiceFactory, S: ServiceFactory< + Request, Config = AppConfig, - Request = Request, Response = ServiceResponse, Error = E, >, @@ -138,7 +133,7 @@ where /// ``` pub async fn call_service(app: &mut S, req: R) -> S::Response where - S: Service, Error = E>, + S: Service, Error = E>, E: std::fmt::Debug, { app.call(req).await.unwrap() @@ -171,7 +166,7 @@ where /// ``` pub async fn read_response(app: &mut S, req: Request) -> Bytes where - S: Service, Error = Error>, + S: Service, Error = Error>, B: MessageBody + Unpin, { let mut resp = app @@ -321,7 +316,7 @@ where /// ``` pub async fn read_response_json(app: &mut S, req: Request) -> T where - S: Service, Error = Error>, + S: Service, Error = Error>, B: MessageBody + Unpin, T: DeserializeOwned, { @@ -602,7 +597,7 @@ impl TestRequest { /// Complete request creation, calls service and waits for response future completion. pub async fn send_request(self, app: &mut S) -> S::Response where - S: Service, Error = E>, + S: Service, Error = E>, E: std::fmt::Debug, { let req = self.to_request(); @@ -639,12 +634,12 @@ impl TestRequest { pub fn start(factory: F) -> TestServer where F: Fn() -> I + Send + Clone + 'static, - I: IntoServiceFactory, - S: ServiceFactory + 'static, + I: IntoServiceFactory, + S: ServiceFactory + 'static, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { start_with(TestServerConfig::default(), factory) @@ -678,12 +673,12 @@ where pub fn start_with(cfg: TestServerConfig, factory: F) -> TestServer where F: Fn() -> I + Send + Clone + 'static, - I: IntoServiceFactory, - S: ServiceFactory + 'static, + I: IntoServiceFactory, + S: ServiceFactory + 'static, S::Error: Into + 'static, S::InitError: fmt::Debug, S::Response: Into> + 'static, - ::Future: 'static, + >::Future: 'static, B: MessageBody + 'static, { let (tx, rx) = mpsc::channel(); @@ -788,10 +783,13 @@ where }), }, } - .unwrap() - .start(); + .unwrap(); + + sys.block_on(async { + let srv = srv.start(); + tx.send((System::current(), srv, local_addr)).unwrap(); + }); - tx.send((System::current(), srv, local_addr)).unwrap(); sys.run() }); @@ -1022,7 +1020,7 @@ impl TestServer { pub async fn stop(self) { self.server.stop(true).await; self.system.stop(); - delay_for(time::Duration::from_millis(100)).await; + sleep(time::Duration::from_millis(100)).await; } } diff --git a/src/types/json.rs b/src/types/json.rs index dc0870a6e..74138ca56 100644 --- a/src/types/json.rs +++ b/src/types/json.rs @@ -367,7 +367,7 @@ where let json = if let Ok(Some(mime)) = req.mime_type() { mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON) - || ctype.as_ref().map_or(false, |predicate| predicate(mime)) + || ctype.map_or(false, |predicate| predicate(mime)) } else { false }; diff --git a/src/web.rs b/src/web.rs index 85e5f2e7b..39dfc450a 100644 --- a/src/web.rs +++ b/src/web.rs @@ -5,7 +5,6 @@ use std::future::Future; pub use actix_http::Response as HttpResponse; pub use bytes::{Buf, BufMut, Bytes, BytesMut}; -pub use futures_channel::oneshot::Canceled; use crate::error::BlockingError; use crate::extract::FromRequest; diff --git a/tests/test_httpserver.rs b/tests/test_httpserver.rs index d164f4445..5eca14931 100644 --- a/tests/test_httpserver.rs +++ b/tests/test_httpserver.rs @@ -15,26 +15,30 @@ async fn test_start() { thread::spawn(move || { let sys = actix_rt::System::new("test"); - let srv = HttpServer::new(|| { - App::new().service( - web::resource("/").route(web::to(|| HttpResponse::Ok().body("test"))), - ) - }) - .workers(1) - .backlog(1) - .max_connections(10) - .max_connection_rate(10) - .keep_alive(10) - .client_timeout(5000) - .client_shutdown(0) - .server_hostname("localhost") - .system_exit() - .disable_signals() - .bind(format!("{}", addr)) - .unwrap() - .run(); + sys.block_on(async { + let srv = HttpServer::new(|| { + App::new().service( + web::resource("/") + .route(web::to(|| HttpResponse::Ok().body("test"))), + ) + }) + .workers(1) + .backlog(1) + .max_connections(10) + .max_connection_rate(10) + .keep_alive(10) + .client_timeout(5000) + .client_shutdown(0) + .server_hostname("localhost") + .system_exit() + .disable_signals() + .bind(format!("{}", addr)) + .unwrap() + .run(); + + let _ = tx.send((srv, actix_rt::System::current())); + }); - let _ = tx.send((srv, actix_rt::System::current())); let _ = sys.run(); }); let (srv, sys) = rx.recv().unwrap(); @@ -101,10 +105,13 @@ async fn test_start_ssl() { .system_exit() .disable_signals() .bind_openssl(format!("{}", addr), builder) - .unwrap() - .run(); + .unwrap(); + + sys.block_on(async { + let srv = srv.run(); + let _ = tx.send((srv, actix_rt::System::current())); + }); - let _ = tx.send((srv, actix_rt::System::current())); let _ = sys.run(); }); let (srv, sys) = rx.recv().unwrap(); diff --git a/tests/test_server.rs b/tests/test_server.rs index c6c316f0d..2f8ce625e 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -45,7 +45,7 @@ const STR: &str = "Hello World Hello World Hello World Hello World Hello World \ struct TestBody { data: Bytes, chunk_size: usize, - delay: actix_rt::time::Delay, + delay: Pin>, } impl TestBody { @@ -53,7 +53,7 @@ impl TestBody { TestBody { data, chunk_size, - delay: actix_rt::time::delay_for(std::time::Duration::from_millis(10)), + delay: Box::pin(actix_rt::time::sleep(std::time::Duration::from_millis(10))), } } } @@ -67,7 +67,8 @@ impl futures_core::stream::Stream for TestBody { ) -> Poll> { ready!(Pin::new(&mut self.delay).poll(cx)); - self.delay = actix_rt::time::delay_for(std::time::Duration::from_millis(10)); + self.delay = + Box::pin(actix_rt::time::sleep(std::time::Duration::from_millis(10))); let chunk_size = std::cmp::min(self.chunk_size, self.data.len()); let chunk = self.data.split_to(chunk_size); if chunk.is_empty() {