diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1ec034bc8..e4d713b48 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -16,7 +16,7 @@ jobs:
- { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
- { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc }
version:
- - 1.51.0 # MSRV
+ - 1.52.0 # MSRV
- stable
- nightly
diff --git a/CHANGES.md b/CHANGES.md
index 2509197fa..cea963ca1 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,8 @@
* Associated type `FromRequest::Config` was removed. [#2233]
* Inner field made private on `web::Payload`. [#2384]
* `Data::into_inner` and `Data::get_ref` no longer require T: Sized. [#2403]
+* Minimum supported Rust version (MSRV) is now 1.52.
+* Updated rustls to v0.20. [#2414]
### Removed
* `ServiceResponse::checked_expr` was a legacy and just removed. [#2401]
@@ -16,6 +18,7 @@
[#2362]: https://github.com/actix/actix-web/pull/2362
[#2384]: https://github.com/actix/actix-web/pull/2384
[#2401]: https://github.com/actix/actix-web/pull/2401
+[#2414]: https://github.com/actix/actix-web/pull/2414
## 4.0.0-beta.9 - 2021-09-09
diff --git a/Cargo.toml b/Cargo.toml
index 7273f2901..d53a293ab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,8 +38,6 @@ members = [
"actix-test",
"actix-router",
]
-# enable when MSRV is 1.51+
-# resolver = "2"
[features]
default = ["compress-brotli", "compress-gzip", "compress-zstd", "cookies"]
@@ -72,13 +70,13 @@ io-uring = ["actix-rt/io-uring", "actix-server/io-uring"]
[dependencies]
actix-codec = "0.4.0"
-actix-macros = "0.2.1"
+actix-macros = "0.2.3"
actix-router = "0.5.0-beta.2"
actix-rt = "2.3"
actix-server = "2.0.0-beta.6"
actix-service = "2.0.0"
actix-utils = "3.0.0"
-actix-tls = { version = "3.0.0-beta.5", default-features = false, optional = true }
+actix-tls = { version = "3.0.0-beta.6", default-features = false, optional = true }
actix-web-codegen = "0.5.0-beta.4"
actix-http = "3.0.0-beta.10"
@@ -116,11 +114,15 @@ brotli2 = "0.3.2"
criterion = { version = "0.3", features = ["html_reports"] }
env_logger = "0.8"
flate2 = "1.0.13"
-zstd = "0.7"
+futures-util = { version = "0.3.7", default-features = false, features = ["std"] }
rand = "0.8"
rcgen = "0.8"
+rustls-pemfile = "0.2"
tls-openssl = { package = "openssl", version = "0.10.9" }
-tls-rustls = { package = "rustls", version = "0.19.0" }
+tls-rustls = { package = "rustls", version = "0.20.0" }
+webpki = "0.22"
+webpki-roots = "0.22"
+zstd = "0.7"
[profile.dev]
# Disabling debug info speeds up builds a bunch and we don't rely on it for debugging that much.
diff --git a/README.md b/README.md
index 13ec3a01a..00e8fa6ce 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
[](https://crates.io/crates/actix-web)
[](https://docs.rs/actix-web/4.0.0-beta.9)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-web/4.0.0-beta.9)
@@ -32,7 +32,7 @@
* SSL support using OpenSSL or Rustls
* Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
* Includes an async [HTTP client](https://docs.rs/awc/)
-* Runs on stable Rust 1.51+
+* Runs on stable Rust 1.52+
## Documentation
diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md
index 6d1512c22..8e0a3eecf 100644
--- a/actix-files/CHANGES.md
+++ b/actix-files/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 0.6.0-beta.7 - 2021-09-09
diff --git a/actix-files/README.md b/actix-files/README.md
index 31bbd036f..ed15e3333 100644
--- a/actix-files/README.md
+++ b/actix-files/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-files)
[](https://docs.rs/actix-files/0.6.0-beta.7)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-files/0.6.0-beta.7)
@@ -15,4 +15,4 @@
- [API Documentation](https://docs.rs/actix-files/)
- [Example Project](https://github.com/actix/examples/tree/master/basics/static_index)
-- Minimum supported Rust version: 1.51 or later
+- Minimum Supported Rust Version (MSRV): 1.52
diff --git a/actix-files/src/lib.rs b/actix-files/src/lib.rs
index 011bff3d7..c8dc92c0d 100644
--- a/actix-files/src/lib.rs
+++ b/actix-files/src/lib.rs
@@ -84,7 +84,7 @@ mod tests {
use crate::named::File;
- #[actix_rt::test]
+ #[actix_web::test]
async fn test_file_extension_to_mime() {
let m = file_extension_to_mime("");
assert_eq!(m, mime::APPLICATION_OCTET_STREAM);
diff --git a/actix-files/tests/encoding.rs b/actix-files/tests/encoding.rs
index d21d4f8fd..652a7c12b 100644
--- a/actix-files/tests/encoding.rs
+++ b/actix-files/tests/encoding.rs
@@ -8,7 +8,7 @@ use actix_web::{
App,
};
-#[actix_rt::test]
+#[actix_web::test]
async fn test_utf8_file_contents() {
// use default ISO-8859-1 encoding
let srv = test::init_service(App::new().service(Files::new("/", "./tests"))).await;
diff --git a/actix-files/tests/guard.rs b/actix-files/tests/guard.rs
index 8b1785e7f..d053f3fdc 100644
--- a/actix-files/tests/guard.rs
+++ b/actix-files/tests/guard.rs
@@ -7,7 +7,7 @@ use actix_web::{
};
use bytes::Bytes;
-#[actix_rt::test]
+#[actix_web::test]
async fn test_guard_filter() {
let srv = test::init_service(
App::new()
diff --git a/actix-http-test/CHANGES.md b/actix-http-test/CHANGES.md
index 69e96f98d..98b197bcf 100644
--- a/actix-http-test/CHANGES.md
+++ b/actix-http-test/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 3.0.0-beta.5 - 2021-09-09
diff --git a/actix-http-test/Cargo.toml b/actix-http-test/Cargo.toml
index ee4971a1e..2bdd6969d 100644
--- a/actix-http-test/Cargo.toml
+++ b/actix-http-test/Cargo.toml
@@ -31,7 +31,7 @@ openssl = ["tls-openssl", "awc/openssl"]
[dependencies]
actix-service = "2.0.0"
actix-codec = "0.4.0"
-actix-tls = "3.0.0-beta.5"
+actix-tls = "3.0.0-beta.6"
actix-utils = "3.0.0"
actix-rt = "2.2"
actix-server = "2.0.0-beta.3"
diff --git a/actix-http-test/README.md b/actix-http-test/README.md
index f75b9c137..6bf0d710a 100644
--- a/actix-http-test/README.md
+++ b/actix-http-test/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-http-test)
[](https://docs.rs/actix-http-test/3.0.0-beta.5)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-http-test/3.0.0-beta.5)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-http-test)
-- Minimum Supported Rust Version (MSRV): 1.51.0
+- Minimum Supported Rust Version (MSRV): 1.52
diff --git a/actix-http-test/src/lib.rs b/actix-http-test/src/lib.rs
index ec7b46ffb..c7b083b5e 100644
--- a/actix-http-test/src/lib.rs
+++ b/actix-http-test/src/lib.rs
@@ -36,7 +36,7 @@ use socket2::{Domain, Protocol, Socket, Type};
/// Ok(HttpResponse::Ok().into())
/// }
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_example() {
/// let mut srv = TestServer::start(
/// || HttpService::new(
diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md
index 775b9e6d5..3911fc00a 100644
--- a/actix-http/CHANGES.md
+++ b/actix-http/CHANGES.md
@@ -1,6 +1,11 @@
# Changes
## Unreleased - 2021-xx-xx
+### Changed
+* Updated rustls to v0.20. [#2414]
+* Minimum supported Rust version (MSRV) is now 1.52.
+
+[#2414]: https://github.com/actix/actix-web/pull/2414
## 3.0.0-beta.10 - 2021-09-09
diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml
index 889c91331..d0724ba5f 100644
--- a/actix-http/Cargo.toml
+++ b/actix-http/Cargo.toml
@@ -46,7 +46,7 @@ actix-service = "2.0.0"
actix-codec = "0.4.0"
actix-utils = "3.0.0"
actix-rt = "2.2"
-actix-tls = { version = "3.0.0-beta.5", features = ["accept", "connect"] }
+actix-tls = { version = "3.0.0-beta.6", features = ["accept", "connect"] }
ahash = "0.7"
base64 = "0.13"
@@ -85,17 +85,18 @@ trust-dns-resolver = { version = "0.20.0", optional = true }
[dev-dependencies]
actix-server = "2.0.0-beta.3"
actix-http-test = { version = "3.0.0-beta.5", features = ["openssl"] }
-actix-tls = { version = "3.0.0-beta.5", features = ["openssl"] }
+actix-tls = { version = "3.0.0-beta.6", features = ["openssl"] }
async-stream = "0.3"
criterion = { version = "0.3", features = ["html_reports"] }
env_logger = "0.8"
rcgen = "0.8"
regex = "1.3"
+rustls-pemfile = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
-tls-openssl = { version = "0.10", package = "openssl" }
-tls-rustls = { version = "0.19", package = "rustls" }
-webpki = { version = "0.21" }
+tls-openssl = { package = "openssl", version = "0.10.9" }
+tls-rustls = { package = "rustls", version = "0.20.0" }
+webpki = { version = "0.22" }
[[example]]
name = "ws"
diff --git a/actix-http/README.md b/actix-http/README.md
index b58b47f5c..68a6e0a5d 100644
--- a/actix-http/README.md
+++ b/actix-http/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-http)
[](https://docs.rs/actix-http/3.0.0-beta.10)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-http/3.0.0-beta.10)
@@ -14,7 +14,7 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-http)
-- Minimum Supported Rust Version (MSRV): 1.51.0
+- Minimum Supported Rust Version (MSRV): 1.52
## Example
diff --git a/actix-http/examples/ws.rs b/actix-http/examples/ws.rs
index d3cedf870..b6be4d2f1 100644
--- a/actix-http/examples/ws.rs
+++ b/actix-http/examples/ws.rs
@@ -85,22 +85,31 @@ impl Stream for Heartbeat {
fn tls_config() -> rustls::ServerConfig {
use std::io::BufReader;
- use rustls::{
- internal::pemfile::{certs, pkcs8_private_keys},
- NoClientAuth, ServerConfig,
- };
+ use rustls::{Certificate, PrivateKey};
+ use rustls_pemfile::{certs, pkcs8_private_keys};
let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
- let mut config = ServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
- let cert_chain = certs(cert_file).unwrap();
+ let cert_chain = certs(cert_file)
+ .unwrap()
+ .into_iter()
+ .map(Certificate)
+ .collect();
let mut keys = pkcs8_private_keys(key_file).unwrap();
- config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
+
+ let mut config = rustls::ServerConfig::builder()
+ .with_safe_defaults()
+ .with_no_client_auth()
+ .with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
+ .unwrap();
+
+ config.alpn_protocols.push(b"http/1.1".to_vec());
+ config.alpn_protocols.push(b"h2".to_vec());
config
}
diff --git a/actix-http/src/client/connector.rs b/actix-http/src/client/connector.rs
index bd46919e8..bde5e4853 100644
--- a/actix-http/src/client/connector.rs
+++ b/actix-http/src/client/connector.rs
@@ -313,18 +313,15 @@ where
SslConnector::Rustls(tls) => {
const H2: &[u8] = b"h2";
- use actix_tls::connect::ssl::rustls::{
- RustlsConnector, Session, TlsStream,
- };
+ use actix_tls::connect::ssl::rustls::{RustlsConnector, TlsStream};
impl IntoConnectionIo for TcpConnection> {
fn into_connection_io(self) -> (Box, Protocol) {
let sock = self.into_parts().0;
- let h2 = sock
- .get_ref()
- .1
- .get_alpn_protocol()
- .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+ let h2 =
+ sock.get_ref().1.alpn_protocol().map_or(false, |protos| {
+ protos.windows(2).any(|w| w == H2)
+ });
if h2 {
(Box::new(sock), Protocol::Http2)
} else {
diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs
index aef765b89..69530ed11 100644
--- a/actix-http/src/h1/dispatcher.rs
+++ b/actix-http/src/h1/dispatcher.rs
@@ -303,9 +303,9 @@ where
body: &impl MessageBody,
) -> Result {
let size = body.size();
- let mut this = self.project();
+ let this = self.project();
this.codec
- .encode(Message::Item((message, size)), &mut this.write_buf)
+ .encode(Message::Item((message, size)), this.write_buf)
.map_err(|err| {
if let Some(mut payload) = this.payload.take() {
payload.set_error(PayloadError::Incomplete(None));
@@ -425,13 +425,13 @@ where
Poll::Ready(Some(Ok(item))) => {
this.codec.encode(
Message::Chunk(Some(item)),
- &mut this.write_buf,
+ this.write_buf,
)?;
}
Poll::Ready(None) => {
this.codec
- .encode(Message::Chunk(None), &mut this.write_buf)?;
+ .encode(Message::Chunk(None), this.write_buf)?;
// payload stream finished.
// set state to None and handle next message
this.state.set(State::None);
@@ -460,13 +460,13 @@ where
Poll::Ready(Some(Ok(item))) => {
this.codec.encode(
Message::Chunk(Some(item)),
- &mut this.write_buf,
+ this.write_buf,
)?;
}
Poll::Ready(None) => {
this.codec
- .encode(Message::Chunk(None), &mut this.write_buf)?;
+ .encode(Message::Chunk(None), this.write_buf)?;
// payload stream finished.
// set state to None and handle next message
this.state.set(State::None);
@@ -592,7 +592,7 @@ where
let mut updated = false;
let mut this = self.as_mut().project();
loop {
- match this.codec.decode(&mut this.read_buf) {
+ match this.codec.decode(this.read_buf) {
Ok(Some(msg)) => {
updated = true;
this.flags.insert(Flags::STARTED);
diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs
index 5e1d47785..ead14206b 100644
--- a/actix-http/src/h1/encoder.rs
+++ b/actix-http/src/h1/encoder.rs
@@ -20,6 +20,7 @@ const AVERAGE_HEADER_SIZE: usize = 30;
#[derive(Debug)]
pub(crate) struct MessageEncoder {
+ #[allow(dead_code)]
pub length: BodySize,
pub te: TransferEncoding,
_phantom: PhantomData,
diff --git a/actix-http/src/h2/service.rs b/actix-http/src/h2/service.rs
index 09e24045b..32dae8ac3 100644
--- a/actix-http/src/h2/service.rs
+++ b/actix-http/src/h2/service.rs
@@ -177,7 +177,7 @@ mod rustls {
> {
let mut protos = vec![b"h2".to_vec()];
protos.extend_from_slice(&config.alpn_protocols);
- config.set_protocols(&protos);
+ config.alpn_protocols = protos;
Acceptor::new(config)
.map_err(TlsError::Tls)
diff --git a/actix-http/src/lib.rs b/actix-http/src/lib.rs
index 3ad8d095e..42ce4ffe4 100644
--- a/actix-http/src/lib.rs
+++ b/actix-http/src/lib.rs
@@ -103,14 +103,9 @@ type ConnectCallback = dyn Fn(&IO, &mut Extensions);
///
/// # Implementation Details
/// Uses Option to reduce necessary allocations when merging with request extensions.
+#[derive(Default)]
pub(crate) struct OnConnectData(Option);
-impl Default for OnConnectData {
- fn default() -> Self {
- Self(None)
- }
-}
-
impl OnConnectData {
/// Construct by calling the on-connect callback with the underlying transport I/O.
pub(crate) fn from_io(
diff --git a/actix-http/src/service.rs b/actix-http/src/service.rs
index afe47bf2d..62c968870 100644
--- a/actix-http/src/service.rs
+++ b/actix-http/src/service.rs
@@ -263,7 +263,7 @@ mod openssl {
mod rustls {
use std::io;
- use actix_tls::accept::rustls::{Acceptor, ServerConfig, Session, TlsStream};
+ use actix_tls::accept::rustls::{Acceptor, ServerConfig, TlsStream};
use actix_tls::accept::TlsError;
use super::*;
@@ -308,14 +308,13 @@ mod rustls {
> {
let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
protos.extend_from_slice(&config.alpn_protocols);
- config.set_protocols(&protos);
+ config.alpn_protocols = protos;
Acceptor::new(config)
.map_err(TlsError::Tls)
.map_init_err(|_| panic!())
.and_then(|io: TlsStream| async {
- let proto = if let Some(protos) = io.get_ref().1.get_alpn_protocol()
- {
+ let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
if protos.windows(2).any(|window| window == b"h2") {
Protocol::Http2
} else {
diff --git a/actix-http/src/ws/mask.rs b/actix-http/src/ws/mask.rs
index 276ca4a85..11a6ddc32 100644
--- a/actix-http/src/ws/mask.rs
+++ b/actix-http/src/ws/mask.rs
@@ -25,8 +25,8 @@ pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) {
//
// un aligned prefix and suffix would be mask/unmask per byte.
// proper aligned middle slice goes into fast path and operates on 4-byte blocks.
- let (mut prefix, words, mut suffix) = unsafe { buf.align_to_mut::() };
- apply_mask_fallback(&mut prefix, mask);
+ let (prefix, words, suffix) = unsafe { buf.align_to_mut::() };
+ apply_mask_fallback(prefix, mask);
let head = prefix.len() & 3;
let mask_u32 = if head > 0 {
if cfg!(target_endian = "big") {
@@ -40,7 +40,7 @@ pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) {
for word in words.iter_mut() {
*word ^= mask_u32;
}
- apply_mask_fallback(&mut suffix, mask_u32.to_ne_bytes());
+ apply_mask_fallback(suffix, mask_u32.to_ne_bytes());
}
#[cfg(test)]
diff --git a/actix-http/tests/test_rustls.rs b/actix-http/tests/test_rustls.rs
index cb7c77ad6..69c7db74d 100644
--- a/actix-http/tests/test_rustls.rs
+++ b/actix-http/tests/test_rustls.rs
@@ -3,7 +3,7 @@
extern crate tls_rustls as rustls;
use std::{
- convert::Infallible,
+ convert::{Infallible, TryFrom},
io::{self, BufReader, Write},
net::{SocketAddr, TcpStream as StdTcpStream},
sync::Arc,
@@ -20,16 +20,17 @@ use actix_http::{
};
use actix_http_test::test_server;
use actix_service::{fn_factory_with_config, fn_service};
+use actix_tls::connect::ssl::rustls::TLS_SERVER_ROOTS;
use actix_utils::future::{err, ok};
use bytes::{Bytes, BytesMut};
use derive_more::{Display, Error};
use futures_core::Stream;
use futures_util::stream::{once, StreamExt as _};
use rustls::{
- internal::pemfile::{certs, pkcs8_private_keys},
- NoClientAuth, ServerConfig as RustlsServerConfig, Session,
+ Certificate, OwnedTrustAnchor, PrivateKey, RootCertStore,
+ ServerConfig as RustlsServerConfig, ServerName,
};
-use webpki::DNSNameRef;
+use rustls_pemfile::{certs, pkcs8_private_keys};
async fn load_body(mut stream: S) -> Result
where
@@ -47,13 +48,24 @@ fn tls_config() -> RustlsServerConfig {
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
- let mut config = RustlsServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
- let cert_chain = certs(cert_file).unwrap();
+ let cert_chain = certs(cert_file)
+ .unwrap()
+ .into_iter()
+ .map(Certificate)
+ .collect();
let mut keys = pkcs8_private_keys(key_file).unwrap();
- config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
+
+ let mut config = RustlsServerConfig::builder()
+ .with_safe_defaults()
+ .with_no_client_auth()
+ .with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
+ .unwrap();
+
+ config.alpn_protocols.push(HTTP1_1_ALPN_PROTOCOL.to_vec());
+ config.alpn_protocols.push(H2_ALPN_PROTOCOL.to_vec());
config
}
@@ -62,19 +74,39 @@ pub fn get_negotiated_alpn_protocol(
addr: SocketAddr,
client_alpn_protocol: &[u8],
) -> Option> {
- let mut config = rustls::ClientConfig::new();
+ let mut root_certs = RootCertStore::empty();
+ for cert in TLS_SERVER_ROOTS.0 {
+ let cert = OwnedTrustAnchor::from_subject_spki_name_constraints(
+ cert.subject,
+ cert.spki,
+ cert.name_constraints,
+ );
+ let certs = vec![cert].into_iter();
+ root_certs.add_server_trust_anchors(certs);
+ }
+
+ let mut config = rustls::ClientConfig::builder()
+ .with_safe_defaults()
+ .with_root_certificates(root_certs)
+ .with_no_client_auth();
+
config.alpn_protocols.push(client_alpn_protocol.to_vec());
- let mut sess = rustls::ClientSession::new(
- &Arc::new(config),
- DNSNameRef::try_from_ascii_str("localhost").unwrap(),
- );
+
+ let mut sess = rustls::ClientConnection::new(
+ Arc::new(config),
+ ServerName::try_from("localhost").unwrap(),
+ )
+ .unwrap();
+
let mut sock = StdTcpStream::connect(addr).unwrap();
let mut stream = rustls::Stream::new(&mut sess, &mut sock);
+
// The handshake will fails because the client will not be able to verify the server
// certificate, but it doesn't matter here as we are just interested in the negotiated ALPN
// protocol
let _ = stream.flush();
- sess.get_alpn_protocol().map(|proto| proto.to_vec())
+
+ sess.alpn_protocol().map(|proto| proto.to_vec())
}
#[actix_rt::test]
diff --git a/actix-multipart/CHANGES.md b/actix-multipart/CHANGES.md
index c32583f08..33da6a202 100644
--- a/actix-multipart/CHANGES.md
+++ b/actix-multipart/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 0.4.0-beta.6 - 2021-09-09
diff --git a/actix-multipart/README.md b/actix-multipart/README.md
index f3366f50c..254ef877b 100644
--- a/actix-multipart/README.md
+++ b/actix-multipart/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-multipart)
[](https://docs.rs/actix-multipart/0.4.0-beta.6)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-multipart/0.4.0-beta.6)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-multipart)
-- Minimum Supported Rust Version (MSRV): 1.51.0
+- Minimum Supported Rust Version (MSRV): 1.52
diff --git a/actix-router/CHANGES.md b/actix-router/CHANGES.md
index 001903438..c2858f2ba 100644
--- a/actix-router/CHANGES.md
+++ b/actix-router/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 0.5.0-beta.2 - 2021-09-09
diff --git a/actix-router/src/resource.rs b/actix-router/src/resource.rs
index be54336e9..dcd655350 100644
--- a/actix-router/src/resource.rs
+++ b/actix-router/src/resource.rs
@@ -394,9 +394,7 @@ impl ResourceDef {
pub fn set_name(&mut self, name: impl Into) {
let name = name.into();
- if name.is_empty() {
- panic!("resource name should not be empty");
- }
+ assert!(!name.is_empty(), "resource name should not be empty");
self.name = Some(name)
}
@@ -978,9 +976,7 @@ impl ResourceDef {
let (name, pattern) = match param.find(':') {
Some(idx) => {
- if tail {
- panic!("custom regex is not supported for tail match");
- }
+ assert!(!tail, "custom regex is not supported for tail match");
let (name, pattern) = param.split_at(idx);
(name, &pattern[1..])
@@ -1087,12 +1083,12 @@ impl ResourceDef {
re.push_str(&escape(unprocessed));
}
- if dyn_segment_count > MAX_DYNAMIC_SEGMENTS {
- panic!(
- "Only {} dynamic segments are allowed, provided: {}",
- MAX_DYNAMIC_SEGMENTS, dyn_segment_count
- );
- }
+ assert!(
+ dyn_segment_count <= MAX_DYNAMIC_SEGMENTS,
+ "Only {} dynamic segments are allowed, provided: {}",
+ MAX_DYNAMIC_SEGMENTS,
+ dyn_segment_count
+ );
// Store the pattern in capture group #1 to have context info outside it
let mut re = format!("({})", re);
diff --git a/actix-router/src/router.rs b/actix-router/src/router.rs
index f5deb8583..fad1a440b 100644
--- a/actix-router/src/router.rs
+++ b/actix-router/src/router.rs
@@ -6,8 +6,9 @@ use crate::{IntoPatterns, Resource, ResourceDef, ResourcePath};
pub struct ResourceId(pub u16);
/// Information about current resource
-#[derive(Clone, Debug)]
+#[derive(Debug, Clone)]
pub struct ResourceInfo {
+ #[allow(dead_code)]
resource: ResourceId,
}
diff --git a/actix-test/CHANGES.md b/actix-test/CHANGES.md
index 58e05c4b6..9c0a9ee81 100644
--- a/actix-test/CHANGES.md
+++ b/actix-test/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 0.1.0-beta.4 - 2021-09-09
diff --git a/actix-test/Cargo.toml b/actix-test/Cargo.toml
index 41d32257c..62a27e5a5 100644
--- a/actix-test/Cargo.toml
+++ b/actix-test/Cargo.toml
@@ -35,4 +35,4 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_urlencoded = "0.7"
tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
-tls-rustls = { package = "rustls", version = "0.19.0", optional = true }
+tls-rustls = { package = "rustls", version = "0.20.0", optional = true }
diff --git a/actix-test/src/lib.rs b/actix-test/src/lib.rs
index c863af44a..23a7eeba1 100644
--- a/actix-test/src/lib.rs
+++ b/actix-test/src/lib.rs
@@ -64,7 +64,7 @@ pub use actix_web::test::{
/// Ok(HttpResponse::Ok())
/// }
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_example() {
/// let srv = actix_test::start(||
/// App::new().service(my_handler)
@@ -104,7 +104,7 @@ where
/// Ok(HttpResponse::Ok())
/// }
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_example() {
/// let srv = actix_test::start_with(actix_test::config().h1(), ||
/// App::new().service(my_handler)
diff --git a/actix-web-actors/CHANGES.md b/actix-web-actors/CHANGES.md
index 2e453063f..e3693f0f6 100644
--- a/actix-web-actors/CHANGES.md
+++ b/actix-web-actors/CHANGES.md
@@ -1,6 +1,7 @@
# Changes
## Unreleased - 2021-xx-xx
+* Minimum supported Rust version (MSRV) is now 1.52.
## 4.0.0-beta.7 - 2021-09-09
diff --git a/actix-web-actors/README.md b/actix-web-actors/README.md
index a647e4bc9..2c29dedf2 100644
--- a/actix-web-actors/README.md
+++ b/actix-web-actors/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-web-actors)
[](https://docs.rs/actix-web-actors/4.0.0-beta.7)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-web-actors/4.0.0-beta.7)
@@ -14,4 +14,4 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-web-actors)
-- Minimum supported Rust version: 1.51 or later
+- Minimum Supported Rust Version (MSRV): 1.52
diff --git a/actix-web-codegen/CHANGES.md b/actix-web-codegen/CHANGES.md
index dae9830aa..f1f050b2c 100644
--- a/actix-web-codegen/CHANGES.md
+++ b/actix-web-codegen/CHANGES.md
@@ -2,8 +2,11 @@
## Unreleased - 2021-xx-xx
* Improve error recovery potential when macro input is invalid. [#2410]
+* Add `#[actix_web::test]` macro for setting up tests with a runtime. [#2409]
+* Minimum supported Rust version (MSRV) is now 1.52.
[#2410]: https://github.com/actix/actix-web/pull/2410
+[#2409]: https://github.com/actix/actix-web/pull/2409
## 0.5.0-beta.4 - 2021-09-09
diff --git a/actix-web-codegen/Cargo.toml b/actix-web-codegen/Cargo.toml
index b8b346b8e..afedafdfd 100644
--- a/actix-web-codegen/Cargo.toml
+++ b/actix-web-codegen/Cargo.toml
@@ -2,11 +2,12 @@
name = "actix-web-codegen"
version = "0.5.0-beta.4"
description = "Routing and runtime macros for Actix Web"
-readme = "README.md"
homepage = "https://actix.rs"
-repository = "https://github.com/actix/actix-web"
-documentation = "https://docs.rs/actix-web-codegen"
-authors = ["Nikolay Kim "]
+repository = "https://github.com/actix/actix-web.git"
+authors = [
+ "Nikolay Kim ",
+ "Rob Ede ",
+]
license = "MIT OR Apache-2.0"
edition = "2018"
@@ -21,7 +22,7 @@ actix-router = "0.5.0-beta.2"
[dev-dependencies]
actix-rt = "2.2"
-actix-macros = "0.2.2"
+actix-macros = "0.2.3"
actix-test = "0.1.0-beta.3"
actix-utils = "3.0.0"
actix-web = "4.0.0-beta.9"
diff --git a/actix-web-codegen/README.md b/actix-web-codegen/README.md
index 268e8b01d..ee552cfb5 100644
--- a/actix-web-codegen/README.md
+++ b/actix-web-codegen/README.md
@@ -4,7 +4,7 @@
[](https://crates.io/crates/actix-web-codegen)
[](https://docs.rs/actix-web-codegen/0.5.0-beta.4)
-[](https://blog.rust-lang.org/2020/03/12/Rust-1.51.html)
+[](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)

[](https://deps.rs/crate/actix-web-codegen/0.5.0-beta.4)
@@ -14,7 +14,7 @@
## Documentation & Resources
- [API Documentation](https://docs.rs/actix-web-codegen)
-- Minimum supported Rust version: 1.51 or later.
+- Minimum Supported Rust Version (MSRV): 1.52
## Compile Testing
diff --git a/actix-web-codegen/src/lib.rs b/actix-web-codegen/src/lib.rs
index 2237f422c..85faf6bca 100644
--- a/actix-web-codegen/src/lib.rs
+++ b/actix-web-codegen/src/lib.rs
@@ -59,6 +59,7 @@
#![recursion_limit = "512"]
use proc_macro::TokenStream;
+use quote::quote;
mod route;
@@ -157,24 +158,41 @@ method_macro! {
}
/// Marks async main function as the actix system entry-point.
-///
-/// # Actix Web Re-export
-/// This macro can be applied with `#[actix_web::main]` when used in Actix Web applications.
-///
+
/// # Examples
/// ```
-/// #[actix_web_codegen::main]
+/// #[actix_web::main]
/// async fn main() {
/// async { println!("Hello world"); }.await
/// }
/// ```
#[proc_macro_attribute]
pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
- use quote::quote;
- let input = syn::parse_macro_input!(item as syn::ItemFn);
- (quote! {
- #[actix_web::rt::main(system = "::actix_web::rt::System")]
- #input
+ let mut output: TokenStream = (quote! {
+ #[::actix_web::rt::main(system = "::actix_web::rt::System")]
})
- .into()
+ .into();
+
+ output.extend(item);
+ output
+}
+
+/// Marks async test functions to use the actix system entry-point.
+///
+/// # Examples
+/// ```
+/// #[actix_web::test]
+/// async fn test() {
+/// assert_eq!(async { "Hello world" }.await, "Hello world");
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
+ let mut output: TokenStream = (quote! {
+ #[::actix_web::rt::test(system = "::actix_web::rt::System")]
+ })
+ .into();
+
+ output.extend(item);
+ output
}
diff --git a/actix-web-codegen/src/route.rs b/actix-web-codegen/src/route.rs
index 4d4af7eca..eac1948a7 100644
--- a/actix-web-codegen/src/route.rs
+++ b/actix-web-codegen/src/route.rs
@@ -220,7 +220,7 @@ fn guess_resource_type(typ: &syn::Type) -> ResourceType {
impl Route {
pub fn new(
args: AttributeArgs,
- input: TokenStream,
+ ast: syn::ItemFn,
method: Option,
) -> syn::Result {
if args.is_empty() {
@@ -234,14 +234,11 @@ impl Route {
),
));
}
- let ast: syn::ItemFn = syn::parse(input)?;
+
let name = ast.sig.ident.clone();
- // Try and pull out the doc comments so that we can reapply them to the
- // generated struct.
- //
- // Note that multi line doc comments are converted to multiple doc
- // attributes.
+ // Try and pull out the doc comments so that we can reapply them to the generated struct.
+ // Note that multi line doc comments are converted to multiple doc attributes.
let doc_attributes = ast
.attrs
.iter()
@@ -349,9 +346,16 @@ pub(crate) fn with_method(
input: TokenStream,
) -> TokenStream {
let args = parse_macro_input!(args as syn::AttributeArgs);
- match Route::new(args, input.clone(), method) {
+
+ let ast = match syn::parse::(input.clone()) {
+ Ok(ast) => ast,
+ // on parse error, make IDEs happy; see fn docs
+ Err(err) => return input_and_compile_error(input, err),
+ };
+
+ match Route::new(args, ast, method) {
Ok(route) => route.into_token_stream().into(),
- // on parse err, make IDEs happy; see fn docs
+ // on macro related error, make IDEs happy; see fn docs
Err(err) => input_and_compile_error(input, err),
}
}
@@ -365,5 +369,5 @@ pub(crate) fn with_method(
fn input_and_compile_error(mut item: TokenStream, err: syn::Error) -> TokenStream {
let compile_err = TokenStream::from(err.to_compile_error());
item.extend(compile_err);
- return item;
+ item
}
diff --git a/actix-web-codegen/tests/test_macro.rs b/actix-web-codegen/tests/test_macro.rs
index 6b08c409c..769cf2bc3 100644
--- a/actix-web-codegen/tests/test_macro.rs
+++ b/actix-web-codegen/tests/test_macro.rs
@@ -256,7 +256,7 @@ async fn test_auto_async() {
assert!(response.status().is_success());
}
-#[actix_rt::test]
+#[actix_web::test]
async fn test_wrap() {
let srv = actix_test::start(|| App::new().service(get_wrap));
diff --git a/actix-web-codegen/tests/trybuild.rs b/actix-web-codegen/tests/trybuild.rs
index 54bc1caec..dd70cb7ca 100644
--- a/actix-web-codegen/tests/trybuild.rs
+++ b/actix-web-codegen/tests/trybuild.rs
@@ -1,4 +1,4 @@
-#[rustversion::stable(1.51)] // MSRV
+#[rustversion::stable(1.52)] // MSRV
#[test]
fn compile_macros() {
let t = trybuild::TestCases::new();
@@ -13,4 +13,6 @@ fn compile_macros() {
t.compile_fail("tests/trybuild/route-malformed-path-fail.rs");
t.pass("tests/trybuild/docstring-ok.rs");
+
+ t.pass("tests/trybuild/test-runtime.rs");
}
diff --git a/actix-web-codegen/tests/trybuild/test-runtime.rs b/actix-web-codegen/tests/trybuild/test-runtime.rs
new file mode 100644
index 000000000..0b901b258
--- /dev/null
+++ b/actix-web-codegen/tests/trybuild/test-runtime.rs
@@ -0,0 +1,6 @@
+#[actix_web::test]
+async fn my_test() {
+ assert!(async { 1 }.await, 1);
+}
+
+fn main() {}
diff --git a/awc/CHANGES.md b/awc/CHANGES.md
index 252b62efa..49d88e5e8 100644
--- a/awc/CHANGES.md
+++ b/awc/CHANGES.md
@@ -1,6 +1,9 @@
# Changes
## Unreleased - 2021-xx-xx
+* Updated rustls to v0.20. [#2414]
+
+[#2414]: https://github.com/actix/actix-web/pull/2414
## 3.0.0-beta.8 - 2021-09-09
diff --git a/awc/Cargo.toml b/awc/Cargo.toml
index 262c3dce5..967d49602 100644
--- a/awc/Cargo.toml
+++ b/awc/Cargo.toml
@@ -73,8 +73,8 @@ rand = "0.8"
serde = "1.0"
serde_json = "1.0"
serde_urlencoded = "0.7"
-tls-openssl = { version = "0.10.9", package = "openssl", optional = true }
-tls-rustls = { version = "0.19.0", package = "rustls", optional = true, features = ["dangerous_configuration"] }
+tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
+tls-rustls = { package = "rustls", version = "0.20.0", optional = true, features = ["dangerous_configuration"] }
[dev-dependencies]
actix-web = { version = "4.0.0-beta.9", features = ["openssl"] }
@@ -82,7 +82,7 @@ actix-http = { version = "3.0.0-beta.10", features = ["openssl"] }
actix-http-test = { version = "3.0.0-beta.5", features = ["openssl"] }
actix-utils = "3.0.0"
actix-server = "2.0.0-beta.3"
-actix-tls = { version = "3.0.0-beta.5", features = ["openssl", "rustls"] }
+actix-tls = { version = "3.0.0-beta.6", features = ["openssl", "rustls"] }
actix-test = { version = "0.1.0-beta.3", features = ["openssl", "rustls"] }
brotli2 = "0.3.2"
@@ -90,7 +90,9 @@ env_logger = "0.8"
flate2 = "1.0.13"
futures-util = { version = "0.3.7", default-features = false }
rcgen = "0.8"
-webpki = "0.21"
+rustls-pemfile = "0.2"
+webpki = "0.22"
+webpki-roots = "0.22"
[[example]]
name = "client"
diff --git a/awc/README.md b/awc/README.md
index 868bc5cae..38c967e69 100644
--- a/awc/README.md
+++ b/awc/README.md
@@ -12,7 +12,7 @@
- [API Documentation](https://docs.rs/awc)
- [Example Project](https://github.com/actix/examples/tree/HEAD/security/awc_https)
-- Minimum Supported Rust Version (MSRV): 1.51.0
+- Minimum Supported Rust Version (MSRV): 1.52
## Example
diff --git a/awc/tests/test_rustls_client.rs b/awc/tests/test_rustls_client.rs
index bc811c046..95f2d0616 100644
--- a/awc/tests/test_rustls_client.rs
+++ b/awc/tests/test_rustls_client.rs
@@ -8,6 +8,7 @@ use std::{
atomic::{AtomicUsize, Ordering},
Arc,
},
+ time::SystemTime,
};
use actix_http::HttpService;
@@ -15,37 +16,52 @@ use actix_http_test::test_server;
use actix_service::{fn_service, map_config, ServiceFactoryExt};
use actix_utils::future::ok;
use actix_web::{dev::AppConfig, http::Version, web, App, HttpResponse};
-use rustls::internal::pemfile::{certs, pkcs8_private_keys};
-use rustls::{ClientConfig, NoClientAuth, ServerConfig};
+use rustls::{
+ client::{ServerCertVerified, ServerCertVerifier},
+ Certificate, ClientConfig, OwnedTrustAnchor, PrivateKey, RootCertStore, ServerConfig,
+ ServerName,
+};
+use rustls_pemfile::{certs, pkcs8_private_keys};
+use webpki_roots::TLS_SERVER_ROOTS;
fn tls_config() -> ServerConfig {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
- let mut config = ServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
- let cert_chain = certs(cert_file).unwrap();
+ let cert_chain = certs(cert_file)
+ .unwrap()
+ .into_iter()
+ .map(Certificate)
+ .collect();
let mut keys = pkcs8_private_keys(key_file).unwrap();
- config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
- config
+ ServerConfig::builder()
+ .with_safe_defaults()
+ .with_no_client_auth()
+ .with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
+ .unwrap()
}
mod danger {
+ use super::*;
+
pub struct NoCertificateVerification;
- impl rustls::ServerCertVerifier for NoCertificateVerification {
+ impl ServerCertVerifier for NoCertificateVerification {
fn verify_server_cert(
&self,
- _roots: &rustls::RootCertStore,
- _presented_certs: &[rustls::Certificate],
- _dns_name: webpki::DNSNameRef<'_>,
- _ocsp: &[u8],
- ) -> Result {
- Ok(rustls::ServerCertVerified::assertion())
+ _end_entity: &Certificate,
+ _intermediates: &[Certificate],
+ _server_name: &ServerName,
+ _scts: &mut dyn Iterator- ,
+ _ocsp_response: &[u8],
+ _now: SystemTime,
+ ) -> Result {
+ Ok(ServerCertVerified::assertion())
}
}
}
@@ -73,10 +89,26 @@ async fn test_connection_reuse_h2() {
})
.await;
- // disable TLS verification
- let mut config = ClientConfig::new();
+ let mut root_certs = RootCertStore::empty();
+ for cert in TLS_SERVER_ROOTS.0 {
+ let cert = OwnedTrustAnchor::from_subject_spki_name_constraints(
+ cert.subject,
+ cert.spki,
+ cert.name_constraints,
+ );
+ let certs = vec![cert].into_iter();
+ root_certs.add_server_trust_anchors(certs);
+ }
+
+ let mut config = ClientConfig::builder()
+ .with_safe_defaults()
+ .with_root_certificates(root_certs)
+ .with_no_client_auth();
+
let protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
- config.set_protocols(&protos);
+ config.alpn_protocols = protos;
+
+ // disable TLS verification
config
.dangerous()
.set_certificate_verifier(Arc::new(danger::NoCertificateVerification));
diff --git a/clippy.toml b/clippy.toml
index 829dd1c59..cef91fde7 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -1 +1 @@
-msrv = "1.51"
+msrv = "1.52"
diff --git a/examples/basic.rs b/examples/basic.rs
index 796f002e8..d29546129 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -35,7 +35,7 @@ async fn main() -> std::io::Result<()> {
)
.service(web::resource("/test1.html").to(|| async { "Test\r\n" }))
})
- .bind("127.0.0.1:8080")?
+ .bind(("127.0.0.1", 8080))?
.workers(1)
.run()
.await
diff --git a/src/lib.rs b/src/lib.rs
index d008fdb7f..3ad77ff5f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -53,7 +53,7 @@
//! * SSL support using OpenSSL or Rustls
//! * Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
//! * Includes an async [HTTP client](https://docs.rs/awc/)
-//! * Runs on stable Rust 1.51+
+//! * Runs on stable Rust 1.52+
//!
//! # Crate Features
//! * `cookies` - cookies support (enabled by default)
diff --git a/src/middleware/compress.rs b/src/middleware/compress.rs
index 0e61a8e7e..4854f4beb 100644
--- a/src/middleware/compress.rs
+++ b/src/middleware/compress.rs
@@ -276,7 +276,7 @@ impl AcceptEncoding {
let mut encodings = raw
.replace(' ', "")
.split(',')
- .filter_map(|l| AcceptEncoding::new(l))
+ .filter_map(AcceptEncoding::new)
.collect::>();
encodings.sort();
diff --git a/src/test.rs b/src/test.rs
index 99e708592..43bf612c6 100644
--- a/src/test.rs
+++ b/src/test.rs
@@ -52,7 +52,7 @@ pub fn default_service(
/// use actix_service::Service;
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_init_service() {
/// let app = test::init_service(
/// App::new()
@@ -98,7 +98,7 @@ where
/// ```
/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_response() {
/// let app = test::init_service(
/// App::new()
@@ -129,7 +129,7 @@ where
/// use actix_web::{test, web, App, HttpResponse, http::header};
/// use bytes::Bytes;
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_index() {
/// let app = test::init_service(
/// App::new().service(
@@ -176,7 +176,7 @@ where
/// use actix_web::{test, web, App, HttpResponse, http::header};
/// use bytes::Bytes;
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_index() {
/// let app = test::init_service(
/// App::new().service(
@@ -224,7 +224,7 @@ where
/// name: String,
/// }
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_post_person() {
/// let app = test::init_service(
/// App::new().service(
@@ -296,7 +296,7 @@ where
/// name: String
/// }
///
-/// #[actix_rt::test]
+/// #[actix_web::test]
/// async fn test_add_person() {
/// let app = test::init_service(
/// App::new().service(
@@ -356,8 +356,8 @@ where
/// }
/// }
///
-/// #[test]
-/// fn test_index() {
+/// #[actix_web::test]
+/// async fn test_index() {
/// let req = test::TestRequest::default().insert_header("content-type", "text/plain")
/// .to_http_request();
///
diff --git a/src/types/path.rs b/src/types/path.rs
index b58aec18d..cd24deb81 100644
--- a/src/types/path.rs
+++ b/src/types/path.rs
@@ -102,7 +102,7 @@ where
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let error_handler = req
.app_data::()
- .and_then(|c| c.ehandler.clone());
+ .and_then(|c| c.err_handler.clone());
ready(
de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
@@ -158,9 +158,9 @@ where
/// );
/// }
/// ```
-#[derive(Clone)]
+#[derive(Clone, Default)]
pub struct PathConfig {
- ehandler: Option Error + Send + Sync>>,
+ err_handler: Option Error + Send + Sync>>,
}
impl PathConfig {
@@ -169,17 +169,11 @@ impl PathConfig {
where
F: Fn(PathError, &HttpRequest) -> Error + Send + Sync + 'static,
{
- self.ehandler = Some(Arc::new(f));
+ self.err_handler = Some(Arc::new(f));
self
}
}
-impl Default for PathConfig {
- fn default() -> Self {
- PathConfig { ehandler: None }
- }
-}
-
#[cfg(test)]
mod tests {
use actix_router::ResourceDef;
diff --git a/src/types/query.rs b/src/types/query.rs
index eed337194..ba2034bfc 100644
--- a/src/types/query.rs
+++ b/src/types/query.rs
@@ -167,7 +167,7 @@ impl FromRequest for Query {
/// .app_data(query_cfg)
/// .service(index);
/// ```
-#[derive(Clone)]
+#[derive(Clone, Default)]
pub struct QueryConfig {
err_handler: Option Error + Send + Sync>>,
}
@@ -183,12 +183,6 @@ impl QueryConfig {
}
}
-impl Default for QueryConfig {
- fn default() -> Self {
- QueryConfig { err_handler: None }
- }
-}
-
#[cfg(test)]
mod tests {
use actix_http::http::StatusCode;
diff --git a/tests/test-macro-import-conflict.rs b/tests/test-macro-import-conflict.rs
new file mode 100644
index 000000000..0d23bb41d
--- /dev/null
+++ b/tests/test-macro-import-conflict.rs
@@ -0,0 +1,15 @@
+//! Checks that test macro does not cause problems in the presence of imports named "test" that
+//! could be either a module with test items or the "test with runtime" macro itself.
+//!
+//! Before actix/actix-net#399 was implemented, this macro was running twice. The first run output
+//! `#[test]` and it got run again and since it was in scope.
+//!
+//! Prevented by using the fully-qualified test marker (`#[::core::prelude::v1::test]`).
+
+use actix_web::test;
+
+#[actix_web::test]
+async fn test_macro_naming_conflict() {
+ let _req = test::TestRequest::default();
+ assert_eq!(async { 1 }.await, 1);
+}
diff --git a/tests/test_server.rs b/tests/test_server.rs
index beb8ff0f5..ff6f5ae5e 100644
--- a/tests/test_server.rs
+++ b/tests/test_server.rs
@@ -883,27 +883,31 @@ async fn test_brotli_encoding_large_openssl() {
mod plus_rustls {
use std::io::BufReader;
- use rustls::{
- internal::pemfile::{certs, pkcs8_private_keys},
- NoClientAuth, ServerConfig as RustlsServerConfig,
- };
+ use rustls::{Certificate, PrivateKey, ServerConfig as RustlsServerConfig};
+ use rustls_pemfile::{certs, pkcs8_private_keys};
use super::*;
- fn rustls_config() -> RustlsServerConfig {
+ fn tls_config() -> RustlsServerConfig {
let cert = rcgen::generate_simple_self_signed(vec!["localhost".to_owned()]).unwrap();
let cert_file = cert.serialize_pem().unwrap();
let key_file = cert.serialize_private_key_pem();
- let mut config = RustlsServerConfig::new(NoClientAuth::new());
let cert_file = &mut BufReader::new(cert_file.as_bytes());
let key_file = &mut BufReader::new(key_file.as_bytes());
- let cert_chain = certs(cert_file).unwrap();
+ let cert_chain = certs(cert_file)
+ .unwrap()
+ .into_iter()
+ .map(Certificate)
+ .collect();
let mut keys = pkcs8_private_keys(key_file).unwrap();
- config.set_single_cert(cert_chain, keys.remove(0)).unwrap();
- config
+ RustlsServerConfig::builder()
+ .with_safe_defaults()
+ .with_no_client_auth()
+ .with_single_cert(cert_chain, PrivateKey(keys.remove(0)))
+ .unwrap()
}
#[actix_rt::test]
@@ -914,7 +918,7 @@ mod plus_rustls {
.map(char::from)
.collect::();
- let srv = actix_test::start_with(actix_test::config().rustls(rustls_config()), || {
+ let srv = actix_test::start_with(actix_test::config().rustls(tls_config()), || {
App::new().service(web::resource("/").route(web::to(|bytes: Bytes| {
HttpResponse::Ok()
.encoding(actix_web::http::ContentEncoding::Identity)