Merge branch 'master' into logger-custom-response-replace

This commit is contained in:
benny-n 2022-02-22 01:31:53 +02:00
commit 1f886ae741
49 changed files with 793 additions and 348 deletions

View File

@ -152,3 +152,34 @@ jobs:
# - name: Upload to Codecov # - name: Upload to Codecov
# uses: codecov/codecov-action@v1 # uses: codecov/codecov-action@v1
# with: { file: cobertura.xml } # with: { file: cobertura.xml }
nextest:
name: nextest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Generate Cargo.lock
uses: actions-rs/cargo@v1
with: { command: generate-lockfile }
- name: Cache Dependencies
uses: Swatinem/rust-cache@v1.3.0
- name: Install cargo-nextest
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-nextest
- name: Test with cargo-nextest
uses: actions-rs/cargo@v1
with:
command: nextest
args: run

View File

@ -22,10 +22,10 @@ path = "src/lib.rs"
experimental-io-uring = ["actix-web/experimental-io-uring", "tokio-uring"] experimental-io-uring = ["actix-web/experimental-io-uring", "tokio-uring"]
[dependencies] [dependencies]
actix-http = "3.0.0-rc.1" actix-http = "3.0.0-rc.3"
actix-service = "2" actix-service = "2"
actix-utils = "3" actix-utils = "3"
actix-web = { version = "4.0.0-rc.2", default-features = false } actix-web = { version = "4.0.0-rc.3", default-features = false }
askama_escape = "0.10" askama_escape = "0.10"
bitflags = "1" bitflags = "1"
@ -43,6 +43,6 @@ tokio-uring = { version = "0.2", optional = true, features = ["bytes"] }
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-test = "0.1.0-beta.12" actix-test = "0.1.0-beta.13"
actix-web = "4.0.0-rc.2" actix-web = "4.0.0-rc.3"
tempfile = "3.2" tempfile = "3.2"

View File

@ -13,6 +13,6 @@
## Documentation & Resources ## Documentation & Resources
- [API Documentation](https://docs.rs/actix-files/) - [API Documentation](https://docs.rs/actix-files)
- [Example Project](https://github.com/actix/examples/tree/master/basics/static_index) - [Example Project](https://github.com/actix/examples/tree/master/basics/static-files)
- Minimum Supported Rust Version (MSRV): 1.54 - Minimum Supported Rust Version (MSRV): 1.54

View File

@ -75,7 +75,7 @@ pub(crate) fn directory_listing(
if dir.is_visible(&entry) { if dir.is_visible(&entry) {
let entry = entry.unwrap(); let entry = entry.unwrap();
let p = match entry.path().strip_prefix(&dir.path) { let p = match entry.path().strip_prefix(&dir.path) {
Ok(p) if cfg!(windows) => base.join(p).to_string_lossy().replace("\\", "/"), Ok(p) if cfg!(windows) => base.join(p).to_string_lossy().replace('\\', "/"),
Ok(p) => base.join(p).to_string_lossy().into_owned(), Ok(p) => base.join(p).to_string_lossy().into_owned(),
Err(_) => continue, Err(_) => continue,
}; };

View File

@ -3,6 +3,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 3.0.0-beta.13 - 2022-02-16
- No significant changes since `3.0.0-beta.12`.
## 3.0.0-beta.12 - 2022-01-31 ## 3.0.0-beta.12 - 2022-01-31
- No significant changes since `3.0.0-beta.11`. - No significant changes since `3.0.0-beta.11`.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-http-test" name = "actix-http-test"
version = "3.0.0-beta.12" version = "3.0.0-beta.13"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Various helpers for Actix applications to use during testing" description = "Various helpers for Actix applications to use during testing"
keywords = ["http", "web", "framework", "async", "futures"] keywords = ["http", "web", "framework", "async", "futures"]
@ -30,12 +30,12 @@ openssl = ["tls-openssl", "awc/openssl"]
[dependencies] [dependencies]
actix-service = "2.0.0" actix-service = "2.0.0"
actix-codec = "0.4.1" actix-codec = "0.5"
actix-tls = "3.0.0" actix-tls = "3"
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-rt = "2.2" actix-rt = "2.2"
actix-server = "2" actix-server = "2"
awc = { version = "3.0.0-beta.20", default-features = false } awc = { version = "3.0.0-beta.21", default-features = false }
base64 = "0.13" base64 = "0.13"
bytes = "1" bytes = "1"
@ -51,5 +51,5 @@ tls-openssl = { version = "0.10.9", package = "openssl", optional = true }
tokio = { version = "1.8.4", features = ["sync"] } tokio = { version = "1.8.4", features = ["sync"] }
[dev-dependencies] [dev-dependencies]
actix-web = { version = "4.0.0-rc.2", default-features = false, features = ["cookies"] } actix-web = { version = "4.0.0-rc.3", default-features = false, features = ["cookies"] }
actix-http = "3.0.0-rc.1" actix-http = "3.0.0-rc.3"

View File

@ -3,11 +3,11 @@
> Various helpers for Actix applications to use during testing. > Various helpers for Actix applications to use during testing.
[![crates.io](https://img.shields.io/crates/v/actix-http-test?label=latest)](https://crates.io/crates/actix-http-test) [![crates.io](https://img.shields.io/crates/v/actix-http-test?label=latest)](https://crates.io/crates/actix-http-test)
[![Documentation](https://docs.rs/actix-http-test/badge.svg?version=3.0.0-beta.12)](https://docs.rs/actix-http-test/3.0.0-beta.12) [![Documentation](https://docs.rs/actix-http-test/badge.svg?version=3.0.0-beta.13)](https://docs.rs/actix-http-test/3.0.0-beta.13)
[![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html) [![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http-test) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http-test)
<br> <br>
[![Dependency Status](https://deps.rs/crate/actix-http-test/3.0.0-beta.12/status.svg)](https://deps.rs/crate/actix-http-test/3.0.0-beta.12) [![Dependency Status](https://deps.rs/crate/actix-http-test/3.0.0-beta.13/status.svg)](https://deps.rs/crate/actix-http-test/3.0.0-beta.13)
[![Download](https://img.shields.io/crates/d/actix-http-test.svg)](https://crates.io/crates/actix-http-test) [![Download](https://img.shields.io/crates/d/actix-http-test.svg)](https://crates.io/crates/actix-http-test)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -1,6 +1,13 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 3.0.0-rc.3 - 2022-02-16
- No significant changes since `3.0.0-rc.2`.
## 3.0.0-rc.2 - 2022-02-08
### Added ### Added
- Implement `From<Vec<u8>>` for `Response<Vec<u8>>`. [#2625] - Implement `From<Vec<u8>>` for `Response<Vec<u8>>`. [#2625]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-http" name = "actix-http"
version = "3.0.0-rc.1" version = "3.0.0-rc.3"
authors = [ authors = [
"Nikolay Kim <fafhrd91@gmail.com>", "Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>", "Rob Ede <robjtede@icloud.com>",
@ -20,7 +20,7 @@ edition = "2018"
[package.metadata.docs.rs] [package.metadata.docs.rs]
# features that docs.rs will build with # features that docs.rs will build with
features = ["openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd"] features = ["http2", "openssl", "rustls", "compress-brotli", "compress-gzip", "compress-zstd"]
[lib] [lib]
name = "actix_http" name = "actix_http"
@ -57,7 +57,7 @@ __compress = []
[dependencies] [dependencies]
actix-service = "2" actix-service = "2"
actix-codec = "0.4.1" actix-codec = "0.5"
actix-utils = "3" actix-utils = "3"
actix-rt = { version = "2.2", default-features = false } actix-rt = { version = "2.2", default-features = false }
@ -89,7 +89,7 @@ rand = { version = "0.8", optional = true }
sha-1 = { version = "0.10", optional = true } sha-1 = { version = "0.10", optional = true }
# openssl/rustls # openssl/rustls
actix-tls = { version = "3.0.0", default-features = false, optional = true } actix-tls = { version = "3", default-features = false, optional = true }
# compress-* # compress-*
brotli = { version = "3.3.3", optional = true } brotli = { version = "3.3.3", optional = true }
@ -97,10 +97,10 @@ flate2 = { version = "1.0.13", optional = true }
zstd = { version = "0.10", optional = true } zstd = { version = "0.10", optional = true }
[dev-dependencies] [dev-dependencies]
actix-http-test = { version = "3.0.0-beta.12", features = ["openssl"] } actix-http-test = { version = "3.0.0-beta.13", features = ["openssl"] }
actix-server = "2" actix-server = "2"
actix-tls = { version = "3.0.0", features = ["openssl"] } actix-tls = { version = "3", features = ["openssl"] }
actix-web = "4.0.0-rc.2" actix-web = "4.0.0-rc.3"
async-stream = "0.3" async-stream = "0.3"
criterion = { version = "0.3", features = ["html_reports"] } criterion = { version = "0.3", features = ["html_reports"] }

View File

@ -3,11 +3,11 @@
> HTTP primitives for the Actix ecosystem. > HTTP primitives for the Actix ecosystem.
[![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http) [![crates.io](https://img.shields.io/crates/v/actix-http?label=latest)](https://crates.io/crates/actix-http)
[![Documentation](https://docs.rs/actix-http/badge.svg?version=3.0.0-rc.1)](https://docs.rs/actix-http/3.0.0-rc.1) [![Documentation](https://docs.rs/actix-http/badge.svg?version=3.0.0-rc.3)](https://docs.rs/actix-http/3.0.0-rc.3)
[![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html) [![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-http.svg)
<br /> <br />
[![dependency status](https://deps.rs/crate/actix-http/3.0.0-rc.1/status.svg)](https://deps.rs/crate/actix-http/3.0.0-rc.1) [![dependency status](https://deps.rs/crate/actix-http/3.0.0-rc.3/status.svg)](https://deps.rs/crate/actix-http/3.0.0-rc.3)
[![Download](https://img.shields.io/crates/d/actix-http.svg)](https://crates.io/crates/actix-http) [![Download](https://img.shields.io/crates/d/actix-http.svg)](https://crates.io/crates/actix-http)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -80,7 +80,7 @@ mod tests {
use futures_core::ready; use futures_core::ready;
use futures_util::{stream, FutureExt as _}; use futures_util::{stream, FutureExt as _};
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*; use super::*;
use crate::body::to_bytes; use crate::body::to_bytes;
@ -91,10 +91,10 @@ mod tests {
assert_impl_all!(BodyStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody); assert_impl_all!(BodyStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody);
assert_impl_all!(BodyStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody); assert_impl_all!(BodyStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody);
assert_not_impl_all!(BodyStream<stream::Empty<Bytes>>: MessageBody); assert_not_impl_any!(BodyStream<stream::Empty<Bytes>>: MessageBody);
assert_not_impl_all!(BodyStream<stream::Repeat<Bytes>>: MessageBody); assert_not_impl_any!(BodyStream<stream::Repeat<Bytes>>: MessageBody);
// crate::Error is not Clone // crate::Error is not Clone
assert_not_impl_all!(BodyStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody); assert_not_impl_any!(BodyStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody);
#[actix_rt::test] #[actix_rt::test]
async fn skips_empty_chunks() { async fn skips_empty_chunks() {

View File

@ -105,14 +105,13 @@ impl MessageBody for BoxBody {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*; use super::*;
use crate::body::to_bytes; use crate::body::to_bytes;
assert_impl_all!(BoxBody: MessageBody, fmt::Debug, Unpin); assert_impl_all!(BoxBody: fmt::Debug, MessageBody, Unpin);
assert_not_impl_any!(BoxBody: Send, Sync);
assert_not_impl_all!(BoxBody: Send, Sync, Unpin);
#[actix_rt::test] #[actix_rt::test]
async fn nested_boxed_body() { async fn nested_boxed_body() {

View File

@ -10,6 +10,17 @@ use super::{BodySize, BoxBody, MessageBody};
use crate::Error; use crate::Error;
pin_project! { pin_project! {
/// An "either" type specialized for body types.
///
/// It is common, in middleware especially, to conditionally return an inner service's unknown/
/// generic body `B` type or return early with a new response. This type's "right" variant
/// defaults to `BoxBody` since error responses are the common case.
///
/// For example, middleware will often have `type Response = ServiceResponse<EitherBody<B>>`.
/// This means that the inner service's response body type maps to the `Left` variant and the
/// middleware's own error responses use the default `Right` variant of `BoxBody`. Of course,
/// there's no reason it couldn't use `EitherBody<B, String>` instead if its alternative
/// responses have a known type.
#[project = EitherBodyProj] #[project = EitherBodyProj]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum EitherBody<L, R = BoxBody> { pub enum EitherBody<L, R = BoxBody> {
@ -22,7 +33,10 @@ pin_project! {
} }
impl<L> EitherBody<L, BoxBody> { impl<L> EitherBody<L, BoxBody> {
/// Creates new `EitherBody` using left variant and boxed right variant. /// Creates new `EitherBody` left variant with a boxed right variant.
///
/// If the expected `R` type will be inferred and is not `BoxBody` then use the
/// [`left`](Self::left) constructor instead.
#[inline] #[inline]
pub fn new(body: L) -> Self { pub fn new(body: L) -> Self {
Self::Left { body } Self::Left { body }

View File

@ -19,7 +19,7 @@ use super::{BodySize, BoxBody};
/// It is not usually necessary to create custom body types, this trait is already [implemented for /// It is not usually necessary to create custom body types, this trait is already [implemented for
/// a large number of sensible body types](#foreign-impls) including: /// a large number of sensible body types](#foreign-impls) including:
/// - Empty body: `()` /// - Empty body: `()`
/// - Text-based: `String`, `&'static str`, `ByteString`. /// - Text-based: `String`, `&'static str`, [`ByteString`](https://docs.rs/bytestring/1).
/// - Byte-based: `Bytes`, `BytesMut`, `Vec<u8>`, `&'static [u8]`; /// - Byte-based: `Bytes`, `BytesMut`, `Vec<u8>`, `&'static [u8]`;
/// - Streams: [`BodyStream`](super::BodyStream), [`SizedStream`](super::SizedStream) /// - Streams: [`BodyStream`](super::BodyStream), [`SizedStream`](super::SizedStream)
/// ///

View File

@ -76,7 +76,7 @@ mod tests {
use actix_rt::pin; use actix_rt::pin;
use actix_utils::future::poll_fn; use actix_utils::future::poll_fn;
use futures_util::stream; use futures_util::stream;
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*; use super::*;
use crate::body::to_bytes; use crate::body::to_bytes;
@ -87,10 +87,10 @@ mod tests {
assert_impl_all!(SizedStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody); assert_impl_all!(SizedStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody);
assert_impl_all!(SizedStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody); assert_impl_all!(SizedStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody);
assert_not_impl_all!(SizedStream<stream::Empty<Bytes>>: MessageBody); assert_not_impl_any!(SizedStream<stream::Empty<Bytes>>: MessageBody);
assert_not_impl_all!(SizedStream<stream::Repeat<Bytes>>: MessageBody); assert_not_impl_any!(SizedStream<stream::Repeat<Bytes>>: MessageBody);
// crate::Error is not Clone // crate::Error is not Clone
assert_not_impl_all!(SizedStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody); assert_not_impl_any!(SizedStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody);
#[actix_rt::test] #[actix_rt::test]
async fn skips_empty_chunks() { async fn skips_empty_chunks() {

View File

@ -128,7 +128,10 @@ impl Decoder for ClientCodec {
type Error = ParseError; type Error = ParseError;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> { fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
debug_assert!(!self.inner.payload.is_some(), "Payload decoder is set"); debug_assert!(
self.inner.payload.is_none(),
"Payload decoder should not be set"
);
if let Some((req, payload)) = self.inner.decoder.decode(src)? { if let Some((req, payload)) = self.inner.decoder.decode(src)? {
if let Some(conn_type) = req.conn_type() { if let Some(conn_type) = req.conn_type() {

View File

@ -3,6 +3,7 @@
//! ## Crate Features //! ## Crate Features
//! | Feature | Functionality | //! | Feature | Functionality |
//! | ------------------- | ------------------------------------------- | //! | ------------------- | ------------------------------------------- |
//! | `http2` | HTTP/2 support via [h2]. |
//! | `openssl` | TLS support via [OpenSSL]. | //! | `openssl` | TLS support via [OpenSSL]. |
//! | `rustls` | TLS support via [rustls]. | //! | `rustls` | TLS support via [rustls]. |
//! | `compress-brotli` | Payload compression support: Brotli. | //! | `compress-brotli` | Payload compression support: Brotli. |
@ -10,6 +11,7 @@
//! | `compress-zstd` | Payload compression support: Zstd. | //! | `compress-zstd` | Payload compression support: Zstd. |
//! | `trust-dns` | Use [trust-dns] as the client DNS resolver. | //! | `trust-dns` | Use [trust-dns] as the client DNS resolver. |
//! //!
//! [h2]: https://crates.io/crates/h2
//! [OpenSSL]: https://crates.io/crates/openssl //! [OpenSSL]: https://crates.io/crates/openssl
//! [rustls]: https://crates.io/crates/rustls //! [rustls]: https://crates.io/crates/rustls
//! [trust-dns]: https://crates.io/crates/trust-dns //! [trust-dns]: https://crates.io/crates/trust-dns

View File

@ -15,7 +15,7 @@ path = "src/lib.rs"
[dependencies] [dependencies]
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-web = { version = "4.0.0-rc.2", default-features = false } actix-web = { version = "4.0.0-rc.3", default-features = false }
bytes = "1" bytes = "1"
derive_more = "0.99.5" derive_more = "0.99.5"
@ -28,7 +28,7 @@ twoway = "0.2"
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-http = "3.0.0-rc.1" actix-http = "3.0.0-rc.3"
futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] }
tokio = { version = "1.8.4", features = ["sync"] } tokio = { version = "1.8.4", features = ["sync"] }
tokio-stream = "0.1" tokio-stream = "0.1"

View File

@ -145,7 +145,8 @@ macro_rules! register {
concat!("/user/keys"), concat!("/user/keys"),
concat!("/user/keys/", $p1), concat!("/user/keys/", $p1),
]; ];
std::array::IntoIter::new(arr)
IntoIterator::into_iter(arr)
}}; }};
} }
@ -158,7 +159,7 @@ fn call() -> impl Iterator<Item = &'static str> {
"/repos/rust-lang/rust/releases/1.51.0", "/repos/rust-lang/rust/releases/1.51.0",
]; ];
std::array::IntoIter::new(arr) IntoIterator::into_iter(arr)
} }
fn compare_routers(c: &mut Criterion) { fn compare_routers(c: &mut Criterion) {

View File

@ -898,7 +898,7 @@ impl ResourceDef {
} }
let pattern_re_set = RegexSet::new(re_set).unwrap(); let pattern_re_set = RegexSet::new(re_set).unwrap();
let segments = segments.unwrap_or_else(Vec::new); let segments = segments.unwrap_or_default();
( (
PatternType::DynamicSet(pattern_re_set, pattern_data), PatternType::DynamicSet(pattern_re_set, pattern_data),

View File

@ -3,6 +3,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 0.1.0-beta.13 - 2022-02-16
- No significant changes since `0.1.0-beta.12`.
## 0.1.0-beta.12 - 2022-01-31 ## 0.1.0-beta.12 - 2022-01-31
- Rename `TestServerConfig::{client_timeout => client_request_timeout}`. [#2611] - Rename `TestServerConfig::{client_timeout => client_request_timeout}`. [#2611]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-test" name = "actix-test"
version = "0.1.0-beta.12" version = "0.1.0-beta.13"
authors = [ authors = [
"Nikolay Kim <fafhrd91@gmail.com>", "Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>", "Rob Ede <robjtede@icloud.com>",
@ -28,14 +28,14 @@ rustls = ["tls-rustls", "actix-http/rustls", "awc/rustls"]
openssl = ["tls-openssl", "actix-http/openssl", "awc/openssl"] openssl = ["tls-openssl", "actix-http/openssl", "awc/openssl"]
[dependencies] [dependencies]
actix-codec = "0.4.1" actix-codec = "0.5"
actix-http = "3.0.0-rc.1" actix-http = "3.0.0-rc.3"
actix-http-test = "3.0.0-beta.12" actix-http-test = "3.0.0-beta.13"
actix-rt = "2.1" actix-rt = "2.1"
actix-service = "2.0.0" actix-service = "2.0.0"
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-web = { version = "4.0.0-rc.2", default-features = false, features = ["cookies"] } actix-web = { version = "4.0.0-rc.3", default-features = false, features = ["cookies"] }
awc = { version = "3.0.0-beta.20", default-features = false, features = ["cookies"] } awc = { version = "3.0.0-beta.21", default-features = false, features = ["cookies"] }
futures-core = { version = "0.3.7", default-features = false, features = ["std"] } futures-core = { version = "0.3.7", default-features = false, features = ["std"] }
futures-util = { version = "0.3.7", default-features = false, features = [] } futures-util = { version = "0.3.7", default-features = false, features = [] }

View File

@ -3,6 +3,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 4.0.0-beta.12 - 2022-02-16
- No significant changes since `4.0.0-beta.11`.
## 4.0.0-beta.11 - 2022-01-31 ## 4.0.0-beta.11 - 2022-01-31
- No significant changes since `4.0.0-beta.10`. - No significant changes since `4.0.0-beta.10`.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-web-actors" name = "actix-web-actors"
version = "4.0.0-beta.11" version = "4.0.0-beta.12"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Actix actors support for Actix Web" description = "Actix actors support for Actix Web"
keywords = ["actix", "http", "web", "framework", "async"] keywords = ["actix", "http", "web", "framework", "async"]
@ -15,9 +15,9 @@ path = "src/lib.rs"
[dependencies] [dependencies]
actix = { version = "0.12.0", default-features = false } actix = { version = "0.12.0", default-features = false }
actix-codec = "0.4.1" actix-codec = "0.5"
actix-http = "3.0.0-rc.1" actix-http = "3.0.0-rc.3"
actix-web = { version = "4.0.0-rc.2", default-features = false } actix-web = { version = "4.0.0-rc.3", default-features = false }
bytes = "1" bytes = "1"
bytestring = "1" bytestring = "1"
@ -27,8 +27,8 @@ tokio = { version = "1.8.4", features = ["sync"] }
[dev-dependencies] [dev-dependencies]
actix-rt = "2.2" actix-rt = "2.2"
actix-test = "0.1.0-beta.12" actix-test = "0.1.0-beta.13"
awc = { version = "3.0.0-beta.20", default-features = false } awc = { version = "3.0.0-beta.21", default-features = false }
env_logger = "0.9" env_logger = "0.9"
futures-util = { version = "0.3.7", default-features = false } futures-util = { version = "0.3.7", default-features = false }

View File

@ -3,11 +3,11 @@
> Actix actors support for Actix Web. > Actix actors support for Actix Web.
[![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors) [![crates.io](https://img.shields.io/crates/v/actix-web-actors?label=latest)](https://crates.io/crates/actix-web-actors)
[![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.0.0-beta.11)](https://docs.rs/actix-web-actors/4.0.0-beta.11) [![Documentation](https://docs.rs/actix-web-actors/badge.svg?version=4.0.0-beta.12)](https://docs.rs/actix-web-actors/4.0.0-beta.12)
[![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html) [![Version](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.54.0.html)
![License](https://img.shields.io/crates/l/actix-web-actors.svg) ![License](https://img.shields.io/crates/l/actix-web-actors.svg)
<br /> <br />
[![dependency status](https://deps.rs/crate/actix-web-actors/4.0.0-beta.11/status.svg)](https://deps.rs/crate/actix-web-actors/4.0.0-beta.11) [![dependency status](https://deps.rs/crate/actix-web-actors/4.0.0-beta.12/status.svg)](https://deps.rs/crate/actix-web-actors/4.0.0-beta.12)
[![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors) [![Download](https://img.shields.io/crates/d/actix-web-actors.svg)](https://crates.io/crates/actix-web-actors)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@ -23,9 +23,9 @@ syn = { version = "1", features = ["full", "parsing"] }
[dev-dependencies] [dev-dependencies]
actix-macros = "0.2.3" actix-macros = "0.2.3"
actix-rt = "2.2" actix-rt = "2.2"
actix-test = "0.1.0-beta.12" actix-test = "0.1.0-beta.13"
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-web = "4.0.0-rc.2" actix-web = "4.0.0-rc.3"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
trybuild = "1" trybuild = "1"

View File

@ -152,6 +152,10 @@ method_macro!(Patch, patch);
/// Marks async main function as the Actix Web system entry-point. /// Marks async main function as the Actix Web system entry-point.
/// ///
/// Note that Actix Web also works under `#[tokio::main]` since version 4.0. However, this macro is
/// still necessary for actor support (since actors use a `System`). Read more in the
/// [`actix_web::rt`](https://docs.rs/actix-web/4/actix_web/rt) module docs.
///
/// # Examples /// # Examples
/// ``` /// ```
/// #[actix_web::main] /// #[actix_web::main]

View File

@ -1,42 +1,60 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
### Added ### Added
- Implement `Responder` for `Vec<u8>`. [#2625]
- Re-export `KeepAlive` in `http` mod. [#2625]
- `middleware::logger::custom_status_replace`. [#2631] - `middleware::logger::custom_status_replace`. [#2631]
[#2625]: https://github.com/actix/actix-web/pull/2625
[#2631]: https://github.com/actix/actix-web/pull/2631 [#2631]: https://github.com/actix/actix-web/pull/2631
## 4.0.0-rc.3 - 2022-02-08
### Changed
- `middleware::Condition` gained a broader compatibility; `Compat` is needed in fewer cases. [#2635]
- Implement `Responder` for `Vec<u8>`. [#2625]
- Re-export `KeepAlive` in `http` mod. [#2625]
[#2625]: https://github.com/actix/actix-web/pull/2625
[#2635]: https://github.com/actix/actix-web/pull/2635
## 4.0.0-rc.2 - 2022-02-02 ## 4.0.0-rc.2 - 2022-02-02
### Added ### Added
- On-by-default `macros` feature flag to enable routing and runtime macros. [#2619] - On-by-default `macros` feature flag to enable routing and runtime macros. [#2619]
### Removed ### Removed
- `rt::{Arbiter, ArbiterHandle}` re-exports. [#2619] - `rt::{Arbiter, ArbiterHandle}` re-exports. [#2619]
[#2619]: https://github.com/actix/actix-web/pull/2619 [#2619]: https://github.com/actix/actix-web/pull/2619
## 4.0.0-rc.1 - 2022-01-31 ## 4.0.0-rc.1 - 2022-01-31
### Changed ### Changed
- Rename `HttpServer::{client_timeout => client_request_timeout}`. [#2611] - Rename `HttpServer::{client_timeout => client_request_timeout}`. [#2611]
- Rename `HttpServer::{client_shutdown => client_disconnect_timeout}`. [#2611] - Rename `HttpServer::{client_shutdown => client_disconnect_timeout}`. [#2611]
### Removed ### Removed
- `impl Future for HttpResponse`. [#2601] - `impl Future for HttpResponse`. [#2601]
[#2601]: https://github.com/actix/actix-web/pull/2601 [#2601]: https://github.com/actix/actix-web/pull/2601
[#2611]: https://github.com/actix/actix-web/pull/2611 [#2611]: https://github.com/actix/actix-web/pull/2611
## 4.0.0-beta.21 - 2022-01-21 ## 4.0.0-beta.21 - 2022-01-21
### Added ### Added
- `HttpResponse::add_removal_cookie`. [#2586] - `HttpResponse::add_removal_cookie`. [#2586]
- `Logger::log_target`. [#2594] - `Logger::log_target`. [#2594]
### Removed ### Removed
- `HttpRequest::req_data[_mut]()`; request-local data is still available through `.extensions()`. [#2585] - `HttpRequest::req_data[_mut]()`; request-local data is still available through `.extensions()`. [#2585]
- `HttpRequestBuilder::del_cookie`. [#2591] - `HttpRequestBuilder::del_cookie`. [#2591]
@ -45,13 +63,15 @@
[#2591]: https://github.com/actix/actix-web/pull/2591 [#2591]: https://github.com/actix/actix-web/pull/2591
[#2594]: https://github.com/actix/actix-web/pull/2594 [#2594]: https://github.com/actix/actix-web/pull/2594
## 4.0.0-beta.20 - 2022-01-14 ## 4.0.0-beta.20 - 2022-01-14
### Added ### Added
- `GuardContext::header` [#2569] - `GuardContext::header` [#2569]
- `ServiceConfig::configure` to allow easy nesting of configuration functions. [#1988] - `ServiceConfig::configure` to allow easy nesting of configuration functions. [#1988]
### Changed ### Changed
- `HttpResponse` can now be used as a `Responder` with any body type. [#2567] - `HttpResponse` can now be used as a `Responder` with any body type. [#2567]
- `Result` extractor wrapper can now convert error types. [#2581] - `Result` extractor wrapper can now convert error types. [#2581]
- Associated types in `FromRequest` impl for `Option` and `Result` has changed. [#2581] - Associated types in `FromRequest` impl for `Option` and `Result` has changed. [#2581]
@ -65,52 +85,61 @@
[#2582]: https://github.com/actix/actix-web/pull/2582 [#2582]: https://github.com/actix/actix-web/pull/2582
[#2584]: https://github.com/actix/actix-web/pull/2584 [#2584]: https://github.com/actix/actix-web/pull/2584
## 4.0.0-beta.19 - 2022-01-04 ## 4.0.0-beta.19 - 2022-01-04
### Added ### Added
- `impl Hash` for `http::header::Encoding`. [#2501] - `impl Hash` for `http::header::Encoding`. [#2501]
- `AcceptEncoding::negotiate()`. [#2501] - `AcceptEncoding::negotiate()`. [#2501]
### Changed ### Changed
- `AcceptEncoding::preference` now returns `Option<Preference<Encoding>>`. [#2501] - `AcceptEncoding::preference` now returns `Option<Preference<Encoding>>`. [#2501]
- Rename methods `BodyEncoding::{encoding => encode_with, get_encoding => preferred_encoding}`. [#2501] - Rename methods `BodyEncoding::{encoding => encode_with, get_encoding => preferred_encoding}`. [#2501]
- `http::header::Encoding` now only represents `Content-Encoding` types. [#2501] - `http::header::Encoding` now only represents `Content-Encoding` types. [#2501]
### Fixed ### Fixed
- Auto-negotiation of content encoding is more fault-tolerant when using the `Compress` middleware. [#2501] - Auto-negotiation of content encoding is more fault-tolerant when using the `Compress` middleware. [#2501]
### Removed ### Removed
- `Compress::new`; restricting compression algorithm is done through feature flags. [#2501] - `Compress::new`; restricting compression algorithm is done through feature flags. [#2501]
- `BodyEncoding` trait; signalling content encoding is now only done via the `Content-Encoding` header. [#2565] - `BodyEncoding` trait; signalling content encoding is now only done via the `Content-Encoding` header. [#2565]
[#2501]: https://github.com/actix/actix-web/pull/2501 [#2501]: https://github.com/actix/actix-web/pull/2501
[#2565]: https://github.com/actix/actix-web/pull/2565 [#2565]: https://github.com/actix/actix-web/pull/2565
## 4.0.0-beta.18 - 2021-12-29 ## 4.0.0-beta.18 - 2021-12-29
### Changed ### Changed
- Update `cookie` dependency (re-exported) to `0.16`. [#2555] - Update `cookie` dependency (re-exported) to `0.16`. [#2555]
- Minimum supported Rust version (MSRV) is now 1.54. - Minimum supported Rust version (MSRV) is now 1.54.
### Security ### Security
- `cookie` upgrade addresses [`RUSTSEC-2020-0071`]. - `cookie` upgrade addresses [`RUSTSEC-2020-0071`].
[#2555]: https://github.com/actix/actix-web/pull/2555 [#2555]: https://github.com/actix/actix-web/pull/2555
[`RUSTSEC-2020-0071`]: https://rustsec.org/advisories/RUSTSEC-2020-0071.html [`rustsec-2020-0071`]: https://rustsec.org/advisories/RUSTSEC-2020-0071.html
## 4.0.0-beta.17 - 2021-12-29 ## 4.0.0-beta.17 - 2021-12-29
### Added ### Added
- `guard::GuardContext` for use with the `Guard` trait. [#2552] - `guard::GuardContext` for use with the `Guard` trait. [#2552]
- `ServiceRequest::guard_ctx` for obtaining a guard context. [#2552] - `ServiceRequest::guard_ctx` for obtaining a guard context. [#2552]
### Changed ### Changed
- `Guard` trait now receives a `&GuardContext`. [#2552] - `Guard` trait now receives a `&GuardContext`. [#2552]
- `guard::fn_guard` functions now receives a `&GuardContext`. [#2552] - `guard::fn_guard` functions now receives a `&GuardContext`. [#2552]
- Some guards now return `impl Guard` and their concrete types are made private: `guard::Header` and all the method guards. [#2552] - Some guards now return `impl Guard` and their concrete types are made private: `guard::Header` and all the method guards. [#2552]
- The `Not` guard is now generic over the type of guard it wraps. [#2552] - The `Not` guard is now generic over the type of guard it wraps. [#2552]
### Fixed ### Fixed
- Rename `ConnectionInfo::{remote_addr => peer_addr}`, deprecating the old name. [#2554] - Rename `ConnectionInfo::{remote_addr => peer_addr}`, deprecating the old name. [#2554]
- `ConnectionInfo::peer_addr` will not return the port number. [#2554] - `ConnectionInfo::peer_addr` will not return the port number. [#2554]
- `ConnectionInfo::realip_remote_addr` will not return the port number if sourcing the IP from the peer's socket address. [#2554] - `ConnectionInfo::realip_remote_addr` will not return the port number if sourcing the IP from the peer's socket address. [#2554]
@ -118,22 +147,25 @@
[#2552]: https://github.com/actix/actix-web/pull/2552 [#2552]: https://github.com/actix/actix-web/pull/2552
[#2554]: https://github.com/actix/actix-web/pull/2554 [#2554]: https://github.com/actix/actix-web/pull/2554
## 4.0.0-beta.16 - 2021-12-27 ## 4.0.0-beta.16 - 2021-12-27
### Changed ### Changed
- No longer require `Scope` service body type to be boxed. [#2523] - No longer require `Scope` service body type to be boxed. [#2523]
- No longer require `Resource` service body type to be boxed. [#2526] - No longer require `Resource` service body type to be boxed. [#2526]
[#2523]: https://github.com/actix/actix-web/pull/2523 [#2523]: https://github.com/actix/actix-web/pull/2523
[#2526]: https://github.com/actix/actix-web/pull/2526 [#2526]: https://github.com/actix/actix-web/pull/2526
## 4.0.0-beta.15 - 2021-12-17 ## 4.0.0-beta.15 - 2021-12-17
### Added ### Added
- Method on `Responder` trait (`customize`) for customizing responders and `CustomizeResponder` struct. [#2510] - Method on `Responder` trait (`customize`) for customizing responders and `CustomizeResponder` struct. [#2510]
- Implement `Debug` for `DefaultHeaders`. [#2510] - Implement `Debug` for `DefaultHeaders`. [#2510]
### Changed ### Changed
- Align `DefaultHeader` method terminology, deprecating previous methods. [#2510] - Align `DefaultHeader` method terminology, deprecating previous methods. [#2510]
- Response service types in `ErrorHandlers` middleware now use `ServiceResponse<EitherBody<B>>` to allow changing the body type. [#2515] - Response service types in `ErrorHandlers` middleware now use `ServiceResponse<EitherBody<B>>` to allow changing the body type. [#2515]
- Both variants in `ErrorHandlerResponse` now use `ServiceResponse<EitherBody<B>>`. [#2515] - Both variants in `ErrorHandlerResponse` now use `ServiceResponse<EitherBody<B>>`. [#2515]
@ -143,6 +175,7 @@
- Relax body type and error bounds on test utilities. [#2518] - Relax body type and error bounds on test utilities. [#2518]
### Removed ### Removed
- Top-level `EitherExtractError` export. [#2510] - Top-level `EitherExtractError` export. [#2510]
- Conversion implementations for `either` crate. [#2516] - Conversion implementations for `either` crate. [#2516]
- `test::load_stream` and `test::load_body`; replace usage with `body::to_bytes`. [#2518] - `test::load_stream` and `test::load_body`; replace usage with `body::to_bytes`. [#2518]
@ -152,9 +185,10 @@
[#2516]: https://github.com/actix/actix-web/pull/2516 [#2516]: https://github.com/actix/actix-web/pull/2516
[#2518]: https://github.com/actix/actix-web/pull/2518 [#2518]: https://github.com/actix/actix-web/pull/2518
## 4.0.0-beta.14 - 2021-12-11 ## 4.0.0-beta.14 - 2021-12-11
### Added ### Added
- Methods on `AcceptLanguage`: `ranked` and `preference`. [#2480] - Methods on `AcceptLanguage`: `ranked` and `preference`. [#2480]
- `AcceptEncoding` typed header. [#2482] - `AcceptEncoding` typed header. [#2482]
- `Range` typed header. [#2485] - `Range` typed header. [#2485]
@ -165,6 +199,7 @@
- `ServiceResponse::into_parts`. [#2499] - `ServiceResponse::into_parts`. [#2499]
### Changed ### Changed
- Rename `Accept::{mime_precedence => ranked}`. [#2480] - Rename `Accept::{mime_precedence => ranked}`. [#2480]
- Rename `Accept::{mime_preference => preference}`. [#2480] - Rename `Accept::{mime_preference => preference}`. [#2480]
- Un-deprecate `App::data_factory`. [#2484] - Un-deprecate `App::data_factory`. [#2484]
@ -174,11 +209,13 @@
- Request-local data container is no longer part of a `RequestHead`. Instead it is a distinct part of a `Request`. [#2487] - Request-local data container is no longer part of a `RequestHead`. Instead it is a distinct part of a `Request`. [#2487]
### Fixed ### Fixed
- Accept wildcard `*` items in `AcceptLanguage`. [#2480] - Accept wildcard `*` items in `AcceptLanguage`. [#2480]
- Re-exports `dev::{BodySize, MessageBody, SizedStream}`. They are exposed through the `body` module. [#2468] - Re-exports `dev::{BodySize, MessageBody, SizedStream}`. They are exposed through the `body` module. [#2468]
- Typed headers containing lists that require one or more items now enforce this minimum. [#2482] - Typed headers containing lists that require one or more items now enforce this minimum. [#2482]
### Removed ### Removed
- `ConnectionInfo::get`. [#2487] - `ConnectionInfo::get`. [#2487]
[#2430]: https://github.com/actix/actix-web/pull/2430 [#2430]: https://github.com/actix/actix-web/pull/2430
@ -193,46 +230,54 @@
[#2493]: https://github.com/actix/actix-web/pull/2493 [#2493]: https://github.com/actix/actix-web/pull/2493
[#2499]: https://github.com/actix/actix-web/pull/2499 [#2499]: https://github.com/actix/actix-web/pull/2499
## 4.0.0-beta.13 - 2021-11-30 ## 4.0.0-beta.13 - 2021-11-30
### Changed ### Changed
- Update `actix-tls` to `3.0.0-rc.1`. [#2474] - Update `actix-tls` to `3.0.0-rc.1`. [#2474]
[#2474]: https://github.com/actix/actix-web/pull/2474 [#2474]: https://github.com/actix/actix-web/pull/2474
## 4.0.0-beta.12 - 2021-11-22 ## 4.0.0-beta.12 - 2021-11-22
### Changed ### Changed
- Compress middleware's response type is now `AnyBody<Encoder<B>>`. [#2448] - Compress middleware's response type is now `AnyBody<Encoder<B>>`. [#2448]
### Fixed ### Fixed
- Relax `Unpin` bound on `S` (stream) parameter of `HttpResponseBuilder::streaming`. [#2448] - Relax `Unpin` bound on `S` (stream) parameter of `HttpResponseBuilder::streaming`. [#2448]
### Removed ### Removed
- `dev::ResponseBody` re-export; is function is replaced by the new `dev::AnyBody` enum. [#2446] - `dev::ResponseBody` re-export; is function is replaced by the new `dev::AnyBody` enum. [#2446]
[#2446]: https://github.com/actix/actix-web/pull/2446 [#2446]: https://github.com/actix/actix-web/pull/2446
[#2448]: https://github.com/actix/actix-web/pull/2448 [#2448]: https://github.com/actix/actix-web/pull/2448
## 4.0.0-beta.11 - 2021-11-15 ## 4.0.0-beta.11 - 2021-11-15
### Added ### Added
- Re-export `dev::ServerHandle` from `actix-server`. [#2442] - Re-export `dev::ServerHandle` from `actix-server`. [#2442]
### Changed ### Changed
- `ContentType::html` now produces `text/html; charset=utf-8` instead of `text/html`. [#2423] - `ContentType::html` now produces `text/html; charset=utf-8` instead of `text/html`. [#2423]
- Update `actix-server` to `2.0.0-beta.9`. [#2442] - Update `actix-server` to `2.0.0-beta.9`. [#2442]
[#2423]: https://github.com/actix/actix-web/pull/2423 [#2423]: https://github.com/actix/actix-web/pull/2423
[#2442]: https://github.com/actix/actix-web/pull/2442 [#2442]: https://github.com/actix/actix-web/pull/2442
## 4.0.0-beta.10 - 2021-10-20 ## 4.0.0-beta.10 - 2021-10-20
### Added ### Added
- Option to allow `Json` extractor to work without a `Content-Type` header present. [#2362] - Option to allow `Json` extractor to work without a `Content-Type` header present. [#2362]
- `#[actix_web::test]` macro for setting up tests with a runtime. [#2409] - `#[actix_web::test]` macro for setting up tests with a runtime. [#2409]
### Changed ### Changed
- Associated type `FromRequest::Config` was removed. [#2233] - Associated type `FromRequest::Config` was removed. [#2233]
- Inner field made private on `web::Payload`. [#2384] - Inner field made private on `web::Payload`. [#2384]
- `Data::into_inner` and `Data::get_ref` no longer requires `T: Sized`. [#2403] - `Data::into_inner` and `Data::get_ref` no longer requires `T: Sized`. [#2403]
@ -240,6 +285,7 @@
- Minimum supported Rust version (MSRV) is now 1.52. - Minimum supported Rust version (MSRV) is now 1.52.
### Removed ### Removed
- Useless `ServiceResponse::checked_expr` method. [#2401] - Useless `ServiceResponse::checked_expr` method. [#2401]
[#2233]: https://github.com/actix/actix-web/pull/2233 [#2233]: https://github.com/actix/actix-web/pull/2233
@ -250,18 +296,21 @@
[#2409]: https://github.com/actix/actix-web/pull/2409 [#2409]: https://github.com/actix/actix-web/pull/2409
[#2414]: https://github.com/actix/actix-web/pull/2414 [#2414]: https://github.com/actix/actix-web/pull/2414
## 4.0.0-beta.9 - 2021-09-09 ## 4.0.0-beta.9 - 2021-09-09
### Added ### Added
- Re-export actix-service `ServiceFactory` in `dev` module. [#2325] - Re-export actix-service `ServiceFactory` in `dev` module. [#2325]
### Changed ### Changed
- Compress middleware will return 406 Not Acceptable when no content encoding is acceptable to the client. [#2344] - Compress middleware will return 406 Not Acceptable when no content encoding is acceptable to the client. [#2344]
- Move `BaseHttpResponse` to `dev::Response`. [#2379] - Move `BaseHttpResponse` to `dev::Response`. [#2379]
- Enable `TestRequest::param` to accept more than just static strings. [#2172] - Enable `TestRequest::param` to accept more than just static strings. [#2172]
- Minimum supported Rust version (MSRV) is now 1.51. - Minimum supported Rust version (MSRV) is now 1.51.
### Fixed ### Fixed
- Fix quality parse error in Accept-Encoding header. [#2344] - Fix quality parse error in Accept-Encoding header. [#2344]
- Re-export correct type at `web::HttpResponse`. [#2379] - Re-export correct type at `web::HttpResponse`. [#2379]
@ -270,20 +319,23 @@
[#2344]: https://github.com/actix/actix-web/pull/2344 [#2344]: https://github.com/actix/actix-web/pull/2344
[#2379]: https://github.com/actix/actix-web/pull/2379 [#2379]: https://github.com/actix/actix-web/pull/2379
## 4.0.0-beta.8 - 2021-06-26 ## 4.0.0-beta.8 - 2021-06-26
### Added ### Added
- Add `ServiceRequest::parts_mut`. [#2177] - Add `ServiceRequest::parts_mut`. [#2177]
- Add extractors for `Uri` and `Method`. [#2263] - Add extractors for `Uri` and `Method`. [#2263]
- Add extractors for `ConnectionInfo` and `PeerAddr`. [#2263] - Add extractors for `ConnectionInfo` and `PeerAddr`. [#2263]
- Add `Route::service` for using hand-written services as handlers. [#2262] - Add `Route::service` for using hand-written services as handlers. [#2262]
### Changed ### Changed
- Change compression algorithm features flags. [#2250] - Change compression algorithm features flags. [#2250]
- Deprecate `App::data` and `App::data_factory`. [#2271] - Deprecate `App::data` and `App::data_factory`. [#2271]
- Smarter extraction of `ConnectionInfo` parts. [#2282] - Smarter extraction of `ConnectionInfo` parts. [#2282]
### Fixed ### Fixed
- Scope and Resource middleware can access data items set on their own layer. [#2288] - Scope and Resource middleware can access data items set on their own layer. [#2288]
[#2177]: https://github.com/actix/actix-web/pull/2177 [#2177]: https://github.com/actix/actix-web/pull/2177
@ -294,12 +346,14 @@
[#2282]: https://github.com/actix/actix-web/pull/2282 [#2282]: https://github.com/actix/actix-web/pull/2282
[#2288]: https://github.com/actix/actix-web/pull/2288 [#2288]: https://github.com/actix/actix-web/pull/2288
## 4.0.0-beta.7 - 2021-06-17 ## 4.0.0-beta.7 - 2021-06-17
### Added ### Added
- `HttpServer::worker_max_blocking_threads` for setting block thread pool. [#2200] - `HttpServer::worker_max_blocking_threads` for setting block thread pool. [#2200]
### Changed ### Changed
- Adjusted default JSON payload limit to 2MB (from 32kb) and included size and limits in the `JsonPayloadError::Overflow` error variant. [#2162] - Adjusted default JSON payload limit to 2MB (from 32kb) and included size and limits in the `JsonPayloadError::Overflow` error variant. [#2162]
- `ServiceResponse::error_response` now uses body type of `Body`. [#2201] - `ServiceResponse::error_response` now uses body type of `Body`. [#2201]
- `ServiceResponse::checked_expr` now returns a `Result`. [#2201] - `ServiceResponse::checked_expr` now returns a `Result`. [#2201]
@ -312,6 +366,7 @@
- `middleware::normalize` now will not try to normalize URIs with no valid path [#2246] - `middleware::normalize` now will not try to normalize URIs with no valid path [#2246]
### Removed ### Removed
- `HttpResponse::take_body` and old `HttpResponse::into_body` method that casted body type. [#2201] - `HttpResponse::take_body` and old `HttpResponse::into_body` method that casted body type. [#2201]
[#2162]: https://github.com/actix/actix-web/pull/2162 [#2162]: https://github.com/actix/actix-web/pull/2162
@ -320,36 +375,39 @@
[#2253]: https://github.com/actix/actix-web/pull/2253 [#2253]: https://github.com/actix/actix-web/pull/2253
[#2246]: https://github.com/actix/actix-web/pull/2246 [#2246]: https://github.com/actix/actix-web/pull/2246
## 4.0.0-beta.6 - 2021-04-17 ## 4.0.0-beta.6 - 2021-04-17
### Added ### Added
- `HttpResponse` and `HttpResponseBuilder` types. [#2065] - `HttpResponse` and `HttpResponseBuilder` types. [#2065]
### Changed ### Changed
- Most error types are now marked `#[non_exhaustive]`. [#2148] - Most error types are now marked `#[non_exhaustive]`. [#2148]
- Methods on `ContentDisposition` that took `T: AsRef<str>` now take `impl AsRef<str>`. - Methods on `ContentDisposition` that took `T: AsRef<str>` now take `impl AsRef<str>`.
[#2065]: https://github.com/actix/actix-web/pull/2065 [#2065]: https://github.com/actix/actix-web/pull/2065
[#2148]: https://github.com/actix/actix-web/pull/2148 [#2148]: https://github.com/actix/actix-web/pull/2148
## 4.0.0-beta.5 - 2021-04-02 ## 4.0.0-beta.5 - 2021-04-02
### Added ### Added
- `Header` extractor for extracting common HTTP headers in handlers. [#2094] - `Header` extractor for extracting common HTTP headers in handlers. [#2094]
- Added `TestServer::client_headers` method. [#2097] - Added `TestServer::client_headers` method. [#2097]
### Changed ### Changed
- `CustomResponder` would return error as `HttpResponse` when `CustomResponder::with_header` failed
instead of skipping. (Only the first error is kept when multiple error occur) [#2093] - `CustomResponder` would return error as `HttpResponse` when `CustomResponder::with_header` failed instead of skipping. (Only the first error is kept when multiple error occur) [#2093]
### Fixed ### Fixed
- Double ampersand in Logger format is escaped correctly. [#2067] - Double ampersand in Logger format is escaped correctly. [#2067]
### Removed ### Removed
- The `client` mod was removed. Clients should now use `awc` directly.
[871ca5e4](https://github.com/actix/actix-web/commit/871ca5e4ae2bdc22d1ea02701c2992fa8d04aed7) - The `client` mod was removed. Clients should now use `awc` directly. [871ca5e4](https://github.com/actix/actix-web/commit/871ca5e4ae2bdc22d1ea02701c2992fa8d04aed7)
- Integration testing was moved to new `actix-test` crate. Namely these items from the `test` - Integration testing was moved to new `actix-test` crate. Namely these items from the `test` module: `TestServer`, `TestServerConfig`, `start`, `start_with`, and `unused_addr`. [#2112]
module: `TestServer`, `TestServerConfig`, `start`, `start_with`, and `unused_addr`. [#2112]
[#2067]: https://github.com/actix/actix-web/pull/2067 [#2067]: https://github.com/actix/actix-web/pull/2067
[#2093]: https://github.com/actix/actix-web/pull/2093 [#2093]: https://github.com/actix/actix-web/pull/2093
@ -357,50 +415,48 @@
[#2097]: https://github.com/actix/actix-web/pull/2097 [#2097]: https://github.com/actix/actix-web/pull/2097
[#2112]: https://github.com/actix/actix-web/pull/2112 [#2112]: https://github.com/actix/actix-web/pull/2112
## 4.0.0-beta.4 - 2021-03-09 ## 4.0.0-beta.4 - 2021-03-09
### Changed ### Changed
- Feature `cookies` is now optional and enabled by default. [#1981] - Feature `cookies` is now optional and enabled by default. [#1981]
- `JsonBody::new` returns a default limit of 32kB to be consistent with `JsonConfig` and the default - `JsonBody::new` returns a default limit of 32kB to be consistent with `JsonConfig` and the default behaviour of the `web::Json<T>` extractor. [#2010]
behaviour of the `web::Json<T>` extractor. [#2010]
[#1981]: https://github.com/actix/actix-web/pull/1981 [#1981]: https://github.com/actix/actix-web/pull/1981
[#2010]: https://github.com/actix/actix-web/pull/2010 [#2010]: https://github.com/actix/actix-web/pull/2010
## 4.0.0-beta.3 - 2021-02-10 ## 4.0.0-beta.3 - 2021-02-10
- Update `actix-web-codegen` to `0.5.0-beta.1`. - Update `actix-web-codegen` to `0.5.0-beta.1`.
## 4.0.0-beta.2 - 2021-02-10 ## 4.0.0-beta.2 - 2021-02-10
### Added ### Added
- The method `Either<web::Json<T>, web::Form<T>>::into_inner()` which returns the inner type for
whichever variant was created. Also works for `Either<web::Form<T>, web::Json<T>>`. [#1894] - The method `Either<web::Json<T>, web::Form<T>>::into_inner()` which returns the inner type for whichever variant was created. Also works for `Either<web::Form<T>, web::Json<T>>`. [#1894]
- Add `services!` macro for helping register multiple services to `App`. [#1933] - Add `services!` macro for helping register multiple services to `App`. [#1933]
- Enable registering a vec of services of the same type to `App` [#1933] - Enable registering a vec of services of the same type to `App` [#1933]
### Changed ### Changed
- Rework `Responder` trait to be sync and returns `Response`/`HttpResponse` directly.
Making it simpler and more performant. [#1891] - Rework `Responder` trait to be sync and returns `Response`/`HttpResponse` directly. Making it simpler and more performant. [#1891]
- `ServiceRequest::into_parts` and `ServiceRequest::from_parts` can no longer fail. [#1893] - `ServiceRequest::into_parts` and `ServiceRequest::from_parts` can no longer fail. [#1893]
- `ServiceRequest::from_request` can no longer fail. [#1893] - `ServiceRequest::from_request` can no longer fail. [#1893]
- Our `Either` type now uses `Left`/`Right` variants (instead of `A`/`B`) [#1894] - Our `Either` type now uses `Left`/`Right` variants (instead of `A`/`B`) [#1894]
- `test::{call_service, read_response, read_response_json, send_request}` take `&Service` - `test::{call_service, read_response, read_response_json, send_request}` take `&Service` in argument [#1905]
in argument [#1905] - `App::wrap_fn`, `Resource::wrap_fn` and `Scope::wrap_fn` provide `&Service` in closure argument. [#1905]
- `App::wrap_fn`, `Resource::wrap_fn` and `Scope::wrap_fn` provide `&Service` in closure
argument. [#1905]
- `web::block` no longer requires the output is a Result. [#1957] - `web::block` no longer requires the output is a Result. [#1957]
### Fixed ### Fixed
- Multiple calls to `App::data` with the same type now keeps the latest call's data. [#1906] - Multiple calls to `App::data` with the same type now keeps the latest call's data. [#1906]
### Removed ### Removed
- Public field of `web::Path` has been made private. [#1894] - Public field of `web::Path` has been made private. [#1894]
- Public field of `web::Query` has been made private. [#1894] - Public field of `web::Query` has been made private. [#1894]
- `TestRequest::with_header`; use `TestRequest::default().insert_header()`. [#1869] - `TestRequest::with_header`; use `TestRequest::default().insert_header()`. [#1869]
- `AppService::set_service_data`; for custom HTTP service factories adding application data, use the - `AppService::set_service_data`; for custom HTTP service factories adding application data, use the layered data model by calling `ServiceRequest::add_data_container` when handling requests instead. [#1906]
layered data model by calling `ServiceRequest::add_data_container` when handling
requests instead. [#1906]
[#1891]: https://github.com/actix/actix-web/pull/1891 [#1891]: https://github.com/actix/actix-web/pull/1891
[#1893]: https://github.com/actix/actix-web/pull/1893 [#1893]: https://github.com/actix/actix-web/pull/1893
@ -411,30 +467,30 @@
[#1933]: https://github.com/actix/actix-web/pull/1933 [#1933]: https://github.com/actix/actix-web/pull/1933
[#1957]: https://github.com/actix/actix-web/pull/1957 [#1957]: https://github.com/actix/actix-web/pull/1957
## 4.0.0-beta.1 - 2021-01-07 ## 4.0.0-beta.1 - 2021-01-07
### Added ### Added
- `Compat` middleware enabling generic response body/error type of middlewares like `Logger` and
`Compress` to be used in `middleware::Condition` and `Resource`, `Scope` services. [#1865] - `Compat` middleware enabling generic response body/error type of middlewares like `Logger` and `Compress` to be used in `middleware::Condition` and `Resource`, `Scope` services. [#1865]
### Changed ### Changed
- Update `actix-*` dependencies to tokio `1.0` based versions. [#1813] - Update `actix-*` dependencies to tokio `1.0` based versions. [#1813]
- Bumped `rand` to `0.8`. - Bumped `rand` to `0.8`.
- Update `rust-tls` to `0.19`. [#1813] - Update `rust-tls` to `0.19`. [#1813]
- Rename `Handler` to `HandlerService` and rename `Factory` to `Handler`. [#1852] - Rename `Handler` to `HandlerService` and rename `Factory` to `Handler`. [#1852]
- The default `TrailingSlash` is now `Trim`, in line with existing documentation. See migration - The default `TrailingSlash` is now `Trim`, in line with existing documentation. See migration guide for implications. [#1875]
guide for implications. [#1875]
- Rename `DefaultHeaders::{content_type => add_content_type}`. [#1875] - Rename `DefaultHeaders::{content_type => add_content_type}`. [#1875]
- MSRV is now 1.46.0. - MSRV is now 1.46.0.
### Fixed ### Fixed
- Added the underlying parse error to `test::read_body_json`'s panic message. [#1812] - Added the underlying parse error to `test::read_body_json`'s panic message. [#1812]
### Removed ### Removed
- Public modules `middleware::{normalize, err_handlers}`. All necessary middleware types are now
exposed directly by the `middleware` module. - Public modules `middleware::{normalize, err_handlers}`. All necessary middleware types are now exposed directly by the `middleware` module.
- Remove `actix-threadpool` as dependency. `actix_threadpool::BlockingError` error type can be imported - Remove `actix-threadpool` as dependency. `actix_threadpool::BlockingError` error type can be imported from `actix_web::error` module. [#1878]
from `actix_web::error` module. [#1878]
[#1812]: https://github.com/actix/actix-web/pull/1812 [#1812]: https://github.com/actix/actix-web/pull/1812
[#1813]: https://github.com/actix/actix-web/pull/1813 [#1813]: https://github.com/actix/actix-web/pull/1813
@ -443,16 +499,18 @@
[#1875]: https://github.com/actix/actix-web/pull/1875 [#1875]: https://github.com/actix/actix-web/pull/1875
[#1878]: https://github.com/actix/actix-web/pull/1878 [#1878]: https://github.com/actix/actix-web/pull/1878
## 3.3.3 - 2021-12-18 ## 3.3.3 - 2021-12-18
### Changed ### Changed
- Soft-deprecate `NormalizePath::default()`, noting upcoming behavior change in v4. [#2529] - Soft-deprecate `NormalizePath::default()`, noting upcoming behavior change in v4. [#2529]
[#2529]: https://github.com/actix/actix-web/pull/2529 [#2529]: https://github.com/actix/actix-web/pull/2529
## 3.3.2 - 2020-12-01 ## 3.3.2 - 2020-12-01
### Fixed ### Fixed
- Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. [#1762] - Removed an occasional `unwrap` on `None` panic in `NormalizePathNormalization`. [#1762]
- Fix `match_pattern()` returning `None` for scope with empty path resource. [#1798] - Fix `match_pattern()` returning `None` for scope with empty path resource. [#1798]
- Increase minimum `socket2` version. [#1803] - Increase minimum `socket2` version. [#1803]
@ -461,24 +519,27 @@
[#1798]: https://github.com/actix/actix-web/pull/1798 [#1798]: https://github.com/actix/actix-web/pull/1798
[#1803]: https://github.com/actix/actix-web/pull/1803 [#1803]: https://github.com/actix/actix-web/pull/1803
## 3.3.1 - 2020-11-29 ## 3.3.1 - 2020-11-29
- Ensure `actix-http` dependency uses same `serde_urlencoded`. - Ensure `actix-http` dependency uses same `serde_urlencoded`.
## 3.3.0 - 2020-11-25 ## 3.3.0 - 2020-11-25
### Added ### Added
- Add `Either<A, B>` extractor helper. [#1788] - Add `Either<A, B>` extractor helper. [#1788]
### Changed ### Changed
- Upgrade `serde_urlencoded` to `0.7`. [#1773] - Upgrade `serde_urlencoded` to `0.7`. [#1773]
[#1773]: https://github.com/actix/actix-web/pull/1773 [#1773]: https://github.com/actix/actix-web/pull/1773
[#1788]: https://github.com/actix/actix-web/pull/1788 [#1788]: https://github.com/actix/actix-web/pull/1788
## 3.2.0 - 2020-10-30 ## 3.2.0 - 2020-10-30
### Added ### Added
- Implement `exclude_regex` for Logger middleware. [#1723] - Implement `exclude_regex` for Logger middleware. [#1723]
- Add request-local data extractor `web::ReqData`. [#1748] - Add request-local data extractor `web::ReqData`. [#1748]
- Add ability to register closure for request middleware logging. [#1749] - Add ability to register closure for request middleware logging. [#1749]
@ -486,6 +547,7 @@
- Expose `on_connect` for access to the connection stream before request is handled. [#1754] - Expose `on_connect` for access to the connection stream before request is handled. [#1754]
### Changed ### Changed
- Updated actix-web-codegen dependency for access to new `#[route(...)]` multi-method macro. - Updated actix-web-codegen dependency for access to new `#[route(...)]` multi-method macro.
- Print non-configured `Data<T>` type when attempting extraction. [#1743] - Print non-configured `Data<T>` type when attempting extraction. [#1743]
- Re-export bytes::Buf{Mut} in web module. [#1750] - Re-export bytes::Buf{Mut} in web module. [#1750]
@ -498,52 +560,53 @@
[#1754]: https://github.com/actix/actix-web/pull/1754 [#1754]: https://github.com/actix/actix-web/pull/1754
[#1749]: https://github.com/actix/actix-web/pull/1749 [#1749]: https://github.com/actix/actix-web/pull/1749
## 3.1.0 - 2020-09-29 ## 3.1.0 - 2020-09-29
### Changed ### Changed
- Add `TrailingSlash::MergeOnly` behaviour to `NormalizePath`, which allows `NormalizePath`
to retain any trailing slashes. [#1695] - Add `TrailingSlash::MergeOnly` behaviour to `NormalizePath`, which allows `NormalizePath` to retain any trailing slashes. [#1695]
- Remove bound `std::marker::Sized` from `web::Data` to support storing `Arc<dyn Trait>` - Remove bound `std::marker::Sized` from `web::Data` to support storing `Arc<dyn Trait>` via `web::Data::from` [#1710]
via `web::Data::from` [#1710]
### Fixed ### Fixed
- `ResourceMap` debug printing is no longer infinitely recursive. [#1708] - `ResourceMap` debug printing is no longer infinitely recursive. [#1708]
[#1695]: https://github.com/actix/actix-web/pull/1695 [#1695]: https://github.com/actix/actix-web/pull/1695
[#1708]: https://github.com/actix/actix-web/pull/1708 [#1708]: https://github.com/actix/actix-web/pull/1708
[#1710]: https://github.com/actix/actix-web/pull/1710 [#1710]: https://github.com/actix/actix-web/pull/1710
## 3.0.2 - 2020-09-15 ## 3.0.2 - 2020-09-15
### Fixed ### Fixed
- `NormalizePath` when used with `TrailingSlash::Trim` no longer trims the root path "/". [#1678] - `NormalizePath` when used with `TrailingSlash::Trim` no longer trims the root path "/". [#1678]
[#1678]: https://github.com/actix/actix-web/pull/1678 [#1678]: https://github.com/actix/actix-web/pull/1678
## 3.0.1 - 2020-09-13 ## 3.0.1 - 2020-09-13
### Changed ### Changed
- `middleware::normalize::TrailingSlash` enum is now accessible. [#1673] - `middleware::normalize::TrailingSlash` enum is now accessible. [#1673]
[#1673]: https://github.com/actix/actix-web/pull/1673 [#1673]: https://github.com/actix/actix-web/pull/1673
## 3.0.0 - 2020-09-11 ## 3.0.0 - 2020-09-11
- No significant changes from `3.0.0-beta.4`. - No significant changes from `3.0.0-beta.4`.
## 3.0.0-beta.4 - 2020-09-09 ## 3.0.0-beta.4 - 2020-09-09
### Added ### Added
- `middleware::NormalizePath` now has configurable behavior for either always having a trailing
slash, or as the new addition, always trimming trailing slashes. [#1639] - `middleware::NormalizePath` now has configurable behavior for either always having a trailing slash, or as the new addition, always trimming trailing slashes. [#1639]
### Changed ### Changed
- Update actix-codec and actix-utils dependencies. [#1634] - Update actix-codec and actix-utils dependencies. [#1634]
- `FormConfig` and `JsonConfig` configurations are now also considered when set - `FormConfig` and `JsonConfig` configurations are now also considered when set using `App::data`. [#1641]
using `App::data`. [#1641]
- `HttpServer::maxconn` is renamed to the more expressive `HttpServer::max_connections`. [#1655] - `HttpServer::maxconn` is renamed to the more expressive `HttpServer::max_connections`. [#1655]
- `HttpServer::maxconnrate` is renamed to the more expressive - `HttpServer::maxconnrate` is renamed to the more expressive `HttpServer::max_connection_rate`. [#1655]
`HttpServer::max_connection_rate`. [#1655]
[#1639]: https://github.com/actix/actix-web/pull/1639 [#1639]: https://github.com/actix/actix-web/pull/1639
[#1641]: https://github.com/actix/actix-web/pull/1641 [#1641]: https://github.com/actix/actix-web/pull/1641
@ -551,22 +614,23 @@
[#1655]: https://github.com/actix/actix-web/pull/1655 [#1655]: https://github.com/actix/actix-web/pull/1655
## 3.0.0-beta.3 - 2020-08-17 ## 3.0.0-beta.3 - 2020-08-17
### Changed ### Changed
- Update `rustls` to 0.18 - Update `rustls` to 0.18
## 3.0.0-beta.2 - 2020-08-17 ## 3.0.0-beta.2 - 2020-08-17
### Changed ### Changed
- `PayloadConfig` is now also considered in `Bytes` and `String` extractors when set
using `App::data`. [#1610] - `PayloadConfig` is now also considered in `Bytes` and `String` extractors when set using `App::data`. [#1610]
- `web::Path` now has a public representation: `web::Path(pub T)` that enables - `web::Path` now has a public representation: `web::Path(pub T)` that enables destructuring. [#1594]
destructuring. [#1594] - `ServiceRequest::app_data` allows retrieval of non-Data data without splitting into parts to access `HttpRequest` which already allows this. [#1618]
- `ServiceRequest::app_data` allows retrieval of non-Data data without splitting into parts to
access `HttpRequest` which already allows this. [#1618]
- Re-export all error types from `awc`. [#1621] - Re-export all error types from `awc`. [#1621]
- MSRV is now 1.42.0. - MSRV is now 1.42.0.
### Fixed ### Fixed
- Memory leak of app data in pooled requests. [#1609] - Memory leak of app data in pooled requests. [#1609]
[#1594]: https://github.com/actix/actix-web/pull/1594 [#1594]: https://github.com/actix/actix-web/pull/1594
@ -575,28 +639,32 @@
[#1618]: https://github.com/actix/actix-web/pull/1618 [#1618]: https://github.com/actix/actix-web/pull/1618
[#1621]: https://github.com/actix/actix-web/pull/1621 [#1621]: https://github.com/actix/actix-web/pull/1621
## 3.0.0-beta.1 - 2020-07-13 ## 3.0.0-beta.1 - 2020-07-13
### Added ### Added
- Re-export `actix_rt::main` as `actix_web::main`. - Re-export `actix_rt::main` as `actix_web::main`.
- `HttpRequest::match_pattern` and `ServiceRequest::match_pattern` for extracting the matched - `HttpRequest::match_pattern` and `ServiceRequest::match_pattern` for extracting the matched resource pattern.
resource pattern.
- `HttpRequest::match_name` and `ServiceRequest::match_name` for extracting matched resource name. - `HttpRequest::match_name` and `ServiceRequest::match_name` for extracting matched resource name.
### Changed ### Changed
- Fix actix_http::h1::dispatcher so it returns when HW_BUFFER_SIZE is reached. Should reduce peak memory consumption during large uploads. [#1550] - Fix actix_http::h1::dispatcher so it returns when HW_BUFFER_SIZE is reached. Should reduce peak memory consumption during large uploads. [#1550]
- Migrate cookie handling to `cookie` crate. Actix-web no longer requires `ring` dependency. - Migrate cookie handling to `cookie` crate. Actix-web no longer requires `ring` dependency.
- MSRV is now 1.41.1 - MSRV is now 1.41.1
### Fixed ### Fixed
- `NormalizePath` improved consistency when path needs slashes added _and_ removed. - `NormalizePath` improved consistency when path needs slashes added _and_ removed.
## 3.0.0-alpha.3 - 2020-05-21 ## 3.0.0-alpha.3 - 2020-05-21
### Added ### Added
- Add option to create `Data<T>` from `Arc<T>` [#1509] - Add option to create `Data<T>` from `Arc<T>` [#1509]
### Changed ### Changed
- Resources and Scopes can now access non-overridden data types set on App (or containing scopes) when setting their own data. [#1486] - Resources and Scopes can now access non-overridden data types set on App (or containing scopes) when setting their own data. [#1486]
- Fix audit issue logging by default peer address [#1485] - Fix audit issue logging by default peer address [#1485]
- Bump minimum supported Rust version to 1.40 - Bump minimum supported Rust version to 1.40
@ -619,7 +687,6 @@
[#1452]: https://github.com/actix/actix-web/pull/1452 [#1452]: https://github.com/actix/actix-web/pull/1452
[#1486]: https://github.com/actix/actix-web/pull/1486 [#1486]: https://github.com/actix/actix-web/pull/1486
## [3.0.0-alpha.1] - 2020-03-11 ## [3.0.0-alpha.1] - 2020-03-11
### Added ### Added
@ -665,7 +732,6 @@
- Fix `AppConfig::secure()` is always false. #1202 - Fix `AppConfig::secure()` is always false. #1202
## [2.0.0-alpha.6] - 2019-12-15 ## [2.0.0-alpha.6] - 2019-12-15
### Fixed ### Fixed
@ -690,7 +756,6 @@
- Migrate to tokio 0.2 - Migrate to tokio 0.2
## [2.0.0-alpha.1] - 2019-11-22 ## [2.0.0-alpha.1] - 2019-11-22
### Changed ### Changed
@ -699,7 +764,6 @@
- Remove implementation of `Responder` for `()`. (#1167) - Remove implementation of `Responder` for `()`. (#1167)
## [1.0.9] - 2019-11-14 ## [1.0.9] - 2019-11-14
### Added ### Added
@ -710,20 +774,17 @@
- Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129) - Support `Host` guards when the `Host` header is unset (e.g. HTTP/2 requests) (#1129)
## [1.0.8] - 2019-09-25 ## [1.0.8] - 2019-09-25
### Added ### Added
- Add `Scope::register_data` and `Resource::register_data` methods, parallel to - Add `Scope::register_data` and `Resource::register_data` methods, parallel to `App::register_data`.
`App::register_data`.
- Add `middleware::Condition` that conditionally enables another middleware - Add `middleware::Condition` that conditionally enables another middleware
- Allow to re-construct `ServiceRequest` from `HttpRequest` and `Payload` - Allow to re-construct `ServiceRequest` from `HttpRequest` and `Payload`
- Add `HttpServer::listen_uds` for ability to listen on UDS FD rather than path, - Add `HttpServer::listen_uds` for ability to listen on UDS FD rather than path, which is useful for example with systemd.
which is useful for example with systemd.
### Changed ### Changed
@ -731,14 +792,12 @@
- Use actix-testing for testing utils - Use actix-testing for testing utils
## [1.0.7] - 2019-08-29 ## [1.0.7] - 2019-08-29
### Fixed ### Fixed
- Request Extensions leak #1062 - Request Extensions leak #1062
## [1.0.6] - 2019-08-28 ## [1.0.6] - 2019-08-28
### Added ### Added
@ -749,8 +808,7 @@
- Add `into_inner` to `Data` - Add `into_inner` to `Data`
- Add `test::TestRequest::set_form()` convenience method to automatically serialize data and set - Add `test::TestRequest::set_form()` convenience method to automatically serialize data and set the header in test requests.
the header in test requests.
### Changed ### Changed
@ -762,35 +820,30 @@
- Update url to 2.1 - Update url to 2.1
## [1.0.5] - 2019-07-18 ## [1.0.5] - 2019-07-18
### Added ### Added
- Unix domain sockets (HttpServer::bind_uds) #92 - Unix domain sockets (HttpServer::bind_uds) #92
- Actix now logs errors resulting in "internal server error" responses always, with the `error` - Actix now logs errors resulting in "internal server error" responses always, with the `error` logging level
logging level
### Fixed ### Fixed
- Restored logging of errors through the `Logger` middleware - Restored logging of errors through the `Logger` middleware
## [1.0.4] - 2019-07-17 ## [1.0.4] - 2019-07-17
### Added ### Added
- Add `Responder` impl for `(T, StatusCode) where T: Responder` - Add `Responder` impl for `(T, StatusCode) where T: Responder`
- Allow to access app's resource map via - Allow to access app's resource map via `ServiceRequest::resource_map()` and `HttpRequest::resource_map()` methods.
`ServiceRequest::resource_map()` and `HttpRequest::resource_map()` methods.
### Changed ### Changed
- Upgrade `rand` dependency version to 0.7 - Upgrade `rand` dependency version to 0.7
## [1.0.3] - 2019-06-28 ## [1.0.3] - 2019-06-28
### Added ### Added
@ -799,8 +852,7 @@
### Changed ### Changed
- Use `encoding_rs` crate instead of unmaintained `encoding` crate - Use `encoding_rs` crate instead of unmaintained `encoding` crate
## [1.0.2] - 2019-06-17 ## [1.0.2] - 2019-06-17
@ -810,7 +862,6 @@
- Move identity middleware to `actix-identity` crate. - Move identity middleware to `actix-identity` crate.
## [1.0.1] - 2019-06-17 ## [1.0.1] - 2019-06-17
### Added ### Added
@ -835,7 +886,6 @@
- HttpRequest::url_for is broken with nested scopes #915 - HttpRequest::url_for is broken with nested scopes #915
## [1.0.0] - 2019-06-05 ## [1.0.0] - 2019-06-05
### Added ### Added
@ -844,8 +894,7 @@
- Add `ServiceRequest::set_payload()` method. - Add `ServiceRequest::set_payload()` method.
- Add `test::TestRequest::set_json()` convenience method to automatically - Add `test::TestRequest::set_json()` convenience method to automatically serialize data and set header in test requests.
serialize data and set header in test requests.
- Add macros for head, options, trace, connect and patch http methods - Add macros for head, options, trace, connect and patch http methods
@ -859,7 +908,6 @@
- Clear http requests pool on app service drop #860 - Clear http requests pool on app service drop #860
## [1.0.0-rc] - 2019-05-18 ## [1.0.0-rc] - 2019-05-18
### Added ### Added
@ -875,7 +923,6 @@
- Codegen with parameters in the path only resolves the first registered endpoint #841 - Codegen with parameters in the path only resolves the first registered endpoint #841
## [1.0.0-beta.4] - 2019-05-12 ## [1.0.0-beta.4] - 2019-05-12
### Added ### Added
@ -887,7 +934,6 @@
- `App::configure` take an `FnOnce` instead of `Fn` - `App::configure` take an `FnOnce` instead of `Fn`
- Upgrade actix-net crates - Upgrade actix-net crates
## [1.0.0-beta.3] - 2019-05-04 ## [1.0.0-beta.3] - 2019-05-04
### Added ### Added
@ -896,11 +942,9 @@
### Changed ### Changed
- Extractor configuration could be registered with `App::data()` - Extractor configuration could be registered with `App::data()` or with `Resource::data()` #775
or with `Resource::data()` #775
- Route data is unified with app data, `Route::data()` moved to resource - Route data is unified with app data, `Route::data()` moved to resource level to `Resource::data()`
level to `Resource::data()`
- CORS handling without headers #702 - CORS handling without headers #702
@ -914,7 +958,6 @@
- `App::data_factory()` is deleted. - `App::data_factory()` is deleted.
## [1.0.0-beta.2] - 2019-04-24 ## [1.0.0-beta.2] - 2019-04-24
### Added ### Added
@ -923,7 +966,7 @@
- Add helper functions for reading response body `test::read_body()` - Add helper functions for reading response body `test::read_body()`
- Add support for `remainder match` (i.e "/path/{tail}*") - Add support for `remainder match` (i.e "/path/{tail}\*")
- Extend `Responder` trait, allow to override status code and headers. - Extend `Responder` trait, allow to override status code and headers.
@ -937,13 +980,11 @@
- Fix async web::Data factory handling - Fix async web::Data factory handling
## [1.0.0-beta.1] - 2019-04-20 ## [1.0.0-beta.1] - 2019-04-20
### Added ### Added
- Add helper functions for reading test response body, - Add helper functions for reading test response body, `test::read_response()` and test::read_response_json()`
`test::read_response()` and test::read_response_json()`
- Add `.peer_addr()` #744 - Add `.peer_addr()` #744
@ -963,7 +1004,6 @@
- Fixed `TestRequest::app_data()` - Fixed `TestRequest::app_data()`
## [1.0.0-alpha.6] - 2019-04-14 ## [1.0.0-alpha.6] - 2019-04-14
### Changed ### Changed
@ -972,12 +1012,10 @@
- Remove generic type for request payload, always use default. - Remove generic type for request payload, always use default.
- Removed `Decompress` middleware. Bytes, String, Json, Form extractors - Removed `Decompress` middleware. Bytes, String, Json, Form extractors automatically decompress payload.
automatically decompress payload.
- Make extractor config type explicit. Add `FromRequest::Config` associated type. - Make extractor config type explicit. Add `FromRequest::Config` associated type.
## [1.0.0-alpha.5] - 2019-04-12 ## [1.0.0-alpha.5] - 2019-04-12
### Added ### Added
@ -988,7 +1026,6 @@
- Removed native-tls support - Removed native-tls support
## [1.0.0-alpha.4] - 2019-04-08 ## [1.0.0-alpha.4] - 2019-04-08
### Added ### Added
@ -1011,7 +1048,6 @@
- Fix body propagation in Response::from_error. #760 - Fix body propagation in Response::from_error. #760
## [1.0.0-alpha.3] - 2019-04-02 ## [1.0.0-alpha.3] - 2019-04-02
### Changed ### Changed
@ -1026,7 +1062,6 @@
- Removed unused `actix_web::web::md()` - Removed unused `actix_web::web::md()`
## [1.0.0-alpha.2] - 2019-03-29 ## [1.0.0-alpha.2] - 2019-03-29
### Added ### Added

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-web" name = "actix-web"
version = "4.0.0-rc.2" version = "4.0.0-rc.3"
authors = [ authors = [
"Nikolay Kim <fafhrd91@gmail.com>", "Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>", "Rob Ede <robjtede@icloud.com>",
@ -63,7 +63,7 @@ __compress = []
experimental-io-uring = ["actix-server/io-uring"] experimental-io-uring = ["actix-server/io-uring"]
[dependencies] [dependencies]
actix-codec = "0.4.1" actix-codec = "0.5"
actix-macros = { version = "0.2.3", optional = true } actix-macros = { version = "0.2.3", optional = true }
actix-rt = { version = "2.6", default-features = false } actix-rt = { version = "2.6", default-features = false }
actix-server = "2" actix-server = "2"
@ -71,7 +71,7 @@ actix-service = "2"
actix-utils = "3" actix-utils = "3"
actix-tls = { version = "3", default-features = false, optional = true } actix-tls = { version = "3", default-features = false, optional = true }
actix-http = { version = "3.0.0-rc.1", features = ["http2", "ws"] } actix-http = { version = "3.0.0-rc.3", features = ["http2", "ws"] }
actix-router = "0.5.0-rc.3" actix-router = "0.5.0-rc.3"
actix-web-codegen = { version = "0.5.0-rc.2", optional = true } actix-web-codegen = { version = "0.5.0-rc.2", optional = true }
@ -100,8 +100,8 @@ url = "2.1"
[dev-dependencies] [dev-dependencies]
actix-files = "0.6.0-beta.16" actix-files = "0.6.0-beta.16"
actix-test = { version = "0.1.0-beta.12", features = ["openssl", "rustls"] } actix-test = { version = "0.1.0-beta.13", features = ["openssl", "rustls"] }
awc = { version = "3.0.0-beta.20", features = ["openssl"] } awc = { version = "3.0.0-beta.21", features = ["openssl"] }
brotli = "3.3.3" brotli = "3.3.3"
const-str = "0.3" const-str = "0.3"
@ -116,6 +116,7 @@ serde = { version = "1.0", features = ["derive"] }
static_assertions = "1" static_assertions = "1"
tls-openssl = { package = "openssl", version = "0.10.9" } tls-openssl = { package = "openssl", version = "0.10.9" }
tls-rustls = { package = "rustls", version = "0.20.0" } tls-rustls = { package = "rustls", version = "0.20.0" }
tokio = { version = "1.13.1", features = ["rt-multi-thread", "macros"] }
zstd = "0.10" zstd = "0.10"
[[test]] [[test]]

View File

@ -1,32 +1,67 @@
# Migrating to 4.0.0 # Migrating to 4.0.0
It is assumed that migration is happening _from_ v3.x. If migration from older version of Actix Web, see the other historical migration notes in this folder. This guide walks you through the process of migrating from v3.x.y to v4.x.y.
If you are migrating to v4.x.y from an older version of Actix Web (v2.x.y or earlier), check out the other historical migration notes in this folder.
This is not an exhaustive list of changes. Smaller or less impactful code changes are outlined, with links to the PRs that introduced them, are shown in [CHANGES.md](./CHANGES.md). If you think any of the changes not mentioned here deserve to be, submit an issue or PR. This document is not designed to be exhaustive - it focuses on the most significant changes coming in v4.
You can find an exhaustive changelog in [CHANGES.md](./CHANGES.md), complete of PR links. If you think that some of the changes that we omitted deserve to be called out in this document, please open an issue or submit a PR.
Headings marked with :warning: are **breaking behavioral changes** and will probably not surface as compile-time errors. Automated tests _might_ detect their effects on your app. Headings marked with :warning: are **breaking behavioral changes**. They will probably not surface as compile-time errors though automated tests _might_ detect their effects on your app.
## Table of Contents: ## Table of Contents:
- [MSRV](#msrv) - [MSRV](#msrv)
- [Tokio v1 Ecosystem](#tokio-v1-ecosystem)
- [Module Structure](#module-structure) - [Module Structure](#module-structure)
- [`NormalizePath` Middleware :warning:](#normalizepath-middleware-warning) - [`NormalizePath` Middleware :warning:](#normalizepath-middleware-warning)
- [Server Settings :warning:](#server-settings-warning)
- [`FromRequest` Trait](#fromrequest-trait) - [`FromRequest` Trait](#fromrequest-trait)
- [Compression Feature Flags](#compression-feature-flags) - [Compression Feature Flags](#compression-feature-flags)
- [`web::Path`](#webpath) - [`web::Path`](#webpath)
- [Rustls](#rustls-crate-upgrade) - [Rustls Crate Upgrade](#rustls-crate-upgrade)
- [Removed `awc` Client Re-export](#removed-awc-client-re-export)
- [Integration Testing Utils Moved To `actix-test`](#integration-testing-utils-moved-to-actix-test)
- [Header APIs](#header-apis)
- [Response Body Types](#response-body-types)
- [Middleware Trait APIs](#middleware-trait-apis)
- [`Responder` Trait](#responder-trait)
- [`App::data` Deprecation :warning:](#appdata-deprecation-warning)
- [Direct Dependency On `actix-rt` And `actix-service`](#direct-dependency-on-actix-rt-and-actix-service)
- [Server Must Be Polled :warning:](#server-must-be-polled-warning)
- [Guards API](#guards-api)
- [Returning `HttpResponse` synchronously](#returning-httpresponse-synchronously)
- [`#[actix_web::main]` and `#[tokio::main]`](#actixwebmain-and-tokiomain)
- [`web::block`](#webblock)
## MSRV ## MSRV
The MSRV of Actix Web has been raised from 1.42 to 1.54. The MSRV of Actix Web has been raised from 1.42 to 1.54.
## Tokio v1 Ecosystem
Actix Web v4 is now underpinned by `tokio`'s v1 ecosystem.
`cargo` supports having multiple versions of the same crate within the same dependency tree, but `tokio` v1 does not interoperate transparently with its previous versions (v0.2, v0.1). Some of your dependencies might rely on `tokio`, either directly or indirectly - if they are using an older version of `tokio`, check if an update is available.
The following command can help you to identify these dependencies:
```sh
# Find all crates in your dependency tree that depend on `tokio`
# It also reports the different versions of `tokio` in your dependency tree.
cargo tree -i tokio
# if you depend on multiple versions of tokio, use this command to
# list the dependencies relying on a specific version of tokio:
cargo tree -i tokio:0.2.25
```
## Module Structure ## Module Structure
Lots of modules has been organized in this release. If a compile error refers to "item XYZ not found in module..." or "module XYZ not found", refer to the [documentation on docs.rs](https://docs.rs/actix-web) to to search for items' new locations. Lots of modules have been re-organized in this release. If a compile error refers to "item XYZ not found in module..." or "module XYZ not found", check the [documentation on docs.rs](https://docs.rs/actix-web) to search for items' new locations.
## `NormalizePath` Middleware :warning: ## `NormalizePath` Middleware :warning:
The default `NormalizePath` behavior now strips trailing slashes by default. This was previously documented to be the case in v3 but the behavior now matches. The effect is that routes defined with trailing slashes will become inaccessible when using `NormalizePath::default()`. As such, calling `NormalizePath::default()` will log a warning. It is advised that the `new` or `trim` methods be used instead. The default `NormalizePath` behavior now strips trailing slashes by default.
This was the _documented_ behaviour in Actix Web v3, but the _actual_ behaviour differed - the discrepancy has now been fixed.
As a consequence of this change, routes defined with trailing slashes will become inaccessible when using `NormalizePath::default()`. Calling `NormalizePath::default()` will log a warning. We suggest to use `new` or `trim`.
```diff ```diff
- #[get("/test/")] - #[get("/test/")]
@ -40,6 +75,12 @@ The default `NormalizePath` behavior now strips trailing slashes by default. Thi
Alternatively, explicitly require trailing slashes: `NormalizePath::new(TrailingSlash::Always)`. Alternatively, explicitly require trailing slashes: `NormalizePath::new(TrailingSlash::Always)`.
## Server Settings :warning:
Until Actix Web v4, the underlying `actix-server` crate used the number of available **logical** cores as the default number of worker threads. The new default is the number of [physical CPU cores available](https://github.com/actix/actix-net/commit/3a3d654c). For more information about this change, refer to [this analysis](https://github.com/actix/actix-web/issues/957).
If you notice performance regressions, please open a new issue detailing your observations.
## `FromRequest` Trait ## `FromRequest` Trait
The associated type `Config` of `FromRequest` was removed. If you have custom extractors, you can just remove this implementation and refer to config types directly, if required. The associated type `Config` of `FromRequest` was removed. If you have custom extractors, you can just remove this implementation and refer to config types directly, if required.
@ -54,17 +95,16 @@ Consequently, the `FromRequest::configure` method was also removed. Config for e
## Compression Feature Flags ## Compression Feature Flags
Feature flag `compress` has been split into its supported algorithm (brotli, gzip, zstd). By default, all compression algorithms are enabled. The new flags are: The `compress` feature flag has been split into more granular feature flags, one for each supported algorithm (brotli, gzip, zstd). By default, all compression algorithms are enabled. If you want to select specific compression codecs, the new flags are:
- `compress-brotli` - `compress-brotli`
- `compress-gzip` - `compress-gzip`
- `compress-zstd` - `compress-zstd`
If you have set in your `Cargo.toml` dedicated `actix-web` features and you still want to have compression enabled.
## `web::Path` ## `web::Path`
The inner field for `web::Path` was made private because It was causing too many issues when used with inner tuple types due to its `Deref` impl. The inner field for `web::Path` is now private.
It was causing too many issues when used with inner tuple types due to its `Deref` implementation.
```diff ```diff
- async fn handler(web::Path((foo, bar)): web::Path<(String, String)>) { - async fn handler(web::Path((foo, bar)): web::Path<(String, String)>) {
@ -74,62 +114,236 @@ The inner field for `web::Path` was made private because It was causing too many
## Rustls Crate Upgrade ## Rustls Crate Upgrade
Required version of `rustls` dependency was bumped to the latest version 0.20. As a result, the new server config builder has changed. [See the updated example project &rarr;.](https://github.com/actix/examples/tree/HEAD/security/rustls/) Actix Web now depends on version 0.20 of `rustls`. As a result, the server config builder has changed. [See the updated example project.](https://github.com/actix/examples/tree/master/https-tls/rustls/)
## Removed `awc` Client Re-export ## Removed `awc` Client Re-export
Actix Web's sister crate `awc` is no longer re-exported through the `client` module. This allows `awc` its own release cadence and prevents its own breaking changes from being blocked due to a re-export. Actix Web's sister crate `awc` is no longer re-exported through the `client` module. This allows `awc` to have its own release cadence - its breaking changes are no longer blocked by Actix Web's (more conservative) release schedule.
```diff ```diff
- use actix_web::client::Client; - use actix_web::client::Client;
+ use awc::Client; + use awc::Client;
``` ```
## Integration Testing Utils Moved to `actix-test` ## Integration Testing Utils Moved To `actix-test`
Actix Web's `test` module used to contain `TestServer`. Since this required the `awc` client and it was removed as a re-export (see above), it was moved to its own crate [`actix-test`](https://docs.rs/actix-test). `TestServer` has been moved to its own crate, [`actix-test`](https://docs.rs/actix-test).
```diff ```diff
- use use actix_web::test::start; - use use actix_web::test::start;
+ use use actix_test::start; + use use actix_test::start;
``` ```
`TestServer` previously lived in `actix_web::test`, but it depends on `awc` which is no longer part of Actix Web's public API (see above).
## Header APIs ## Header APIs
TODO Header related APIs have been standardized across all `actix-*` crates. The terminology now better matches the underlying `HeaderMap` naming conventions.
## Body Types / Removal of Body+ResponseBody types / Addition of EitherBody In short, "insert" always indicates that any existing headers with the same name are overridden, while "append" is used for adding with no removal (e.g. multi-valued headers).
TODO For request and response builder APIs, the new methods provide a unified interface for adding key-value pairs _and_ typed headers, which can often be more expressive.
In particular, folks seem to be struggling with the `ErrorHandlers` middleware because of this change and the obscured nature of `EitherBody` within its types. ```diff
- .set_header("Api-Key", "1234")
+ .insert_header(("Api-Key", "1234"))
- .header("Api-Key", "1234")
+ .append_header(("Api-Key", "1234"))
- .set(ContentType::json())
+ .insert_header(ContentType::json())
```
We chose to deprecate most of the old methods instead of removing them immediately - the warning notes will guide you on how to update.
## Response Body Types
There have been a lot of changes to response body types. They are now more expressive and their purpose should be more intuitive.
We have boosted the quality and completeness of the documentation for all items in the [`body` module](https://docs.rs/actix-web/4/actix_web/body).
### `ResponseBody`
`ResponseBody` is gone. Its purpose was confusing and has been replaced by better components.
### `Body`
`Body` is also gone. In combination with `ResponseBody`, the API it provided was sub-optimal and did not encourage expressive types. Here are the equivalents in the new system (check docs):
- `Body::None` => `body::None::new()`
- `Body::Empty` => `()` / `web::Bytes::new()`
- `Body::Bytes` => `web::Bytes::from(...)`
- `Body::Message` => `.boxed()` / `BoxBody`
### `BoxBody`
`BoxBody` is a new type-erased body type. It's used for all error response bodies.
Creating a boxed body is best done by calling [`.boxed()`](https://docs.rs/actix-web/4/actix_web/body/trait.MessageBody.html#method.boxed) on a `MessageBody` type.
### `EitherBody`
`EitherBody` is a new "either" type that is particularly useful in middlewares that can bail early, returning their own response plus body type.
### Error Handlers
TODO In particular, folks seem to be struggling with the `ErrorHandlers` middleware because of this change and the obscured nature of `EitherBody` within its types.
## Middleware Trait APIs ## Middleware Trait APIs
This section builds upon guidance from the [response body types](#response-body-types) section.
TODO TODO
TODO: Also write the Middleware author's guide. TODO: Also write the Middleware author's guide.
## `Responder` Trait ## `Responder` Trait
TODO The `Responder` trait's interface has changed. Errors should be handled and converted to responses within the `respond_to` method. It's also no longer async so the associated `type Future` has been removed; there was no compelling use case found for it. These changes simplify the interface and implementation a lot.
## `App::data` deprecation Now that more emphasis is placed on expressive body types, as explained in the [body types migration section](#response-body-types), this trait has introduced an associated `type Body`. The simplest migration will be to use `BoxBody` + `.map_into_boxed_body()` but if there is a more expressive type for your responder then try to use that instead.
TODO ```diff
impl Responder for &'static str {
- type Error = Error;
- type Future = Ready<Result<HttpResponse, Error>>;
+ type Body = &'static str;
## It's probably not necessary to import `actix-rt` or `actix-service` any more - fn respond_to(self, req: &HttpRequest) -> Self::Future {
+ fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
let res = HttpResponse::build(StatusCode::OK)
.content_type("text/plain; charset=utf-8")
.body(self);
TODO - ok(res)
+ res
}
}
```
## Server must be awaited in order to run :warning: ## `App::data` Deprecation :warning:
TODO The `App::data` method is deprecated. Replace instances of this with `App::app_data`. Exposing both methods led to lots of confusion when trying to extract the data in handlers. Now, when using the `Data` wrapper, the type you put in to `app_data` is the same type you extract in handler arguments.
You may need to review the [guidance on shared mutable state](https://docs.rs/actix-web/4/actix_web/struct.App.html#shared-mutable-state) in order to migrate this correctly.
```diff
use actix_web::web::Data;
#[get("/")]
async fn handler(my_state: Data<MyState>) -> { todo!() }
HttpServer::new(|| {
- App::new()
- .data(MyState::default())
- .service(hander)
+ let my_state: Data<MyState> = Data::new(MyState::default());
+
+ App::new()
+ .app_data(my_state)
+ .service(hander)
})
```
## Direct Dependency On `actix-rt` And `actix-service`
Improvements to module management and re-exports have resulted in not needing direct dependencies on these underlying crates for the vast majority of cases. In particular:
- all traits necessary for creating middlewares are now re-exported through the `dev` modules;
- `#[actix_web::test]` now exists for async test definitions.
Relying on these re-exports will ease the transition to future versions of Actix Web.
```diff
- use actix_service::{Service, Transform};
+ use actix_web::dev::{Service, Transform};
```
```diff
- #[actix_rt::test]
+ #[actix_web::test]
async fn test_thing() {
```
## Server Must Be Polled :warning:
In order to _start_ serving requests, the `Server` object returned from `run` **must** be `poll`ed, `await`ed, or `spawn`ed. This was done to prevent unexpected behavior and ensure that things like signal handlers are able to function correctly when enabled.
For example, in this contrived example where the server is started and then the main thread is sent to sleep, the server will no longer be able to serve requests with v4.0:
```rust
#[actix_web::main]
async fn main() {
HttpServer::new(|| App::new().default_service(web::to(HttpResponse::Conflict)))
.bind(("127.0.0.1", 8080))
.unwrap()
.run();
thread::sleep(Duration::from_secs(1000));
}
```
## Guards API ## Guards API
TODO Implementors of routing guards will need to use the modified interface of the `Guard` trait. The API is more flexible than before. See [guard module docs](https://docs.rs/actix-web/4/actix_web/guard/struct.GuardContext.html) for more details.
## HttpResponse no longer implements Future ```diff
struct MethodGuard(HttpMethod);
TODO impl Guard for MethodGuard {
- fn check(&self, request: &RequestHead) -> bool {
+ fn check(&self, ctx: &GuardContext<'_>) -> bool {
- request.method == self.0
+ ctx.head().method == self.0
}
}
```
## Returning `HttpResponse` synchronously
The implementation of `Future` for `HttpResponse` was removed because it was largely useless for all but the simplest handlers like `web::to(|| HttpResponse::Ok().finish())`. It also caused false positives on the `async_yields_async` clippy lint in reasonable scenarios. The compiler errors will looks something like:
```
web::to(|| HttpResponse::Ok().finish())
^^^^^^^ the trait `Handler<_>` is not implemented for `[closure@...]`
```
This form should be replaced with explicit async functions and closures:
```diff
- fn handler() -> HttpResponse {
+ async fn handler() -> HttpResponse {
HttpResponse::Ok().finish()
}
```
```diff
- web::to(|| HttpResponse::Ok().finish())
+ web::to(|| async { HttpResponse::Ok().finish() })
```
Or, for these extremely simple cases, utilise an `HttpResponseBuilder`:
```diff
- web::to(|| HttpResponse::Ok().finish())
+ web::to(HttpResponse::Ok)
```
## `#[actix_web::main]` and `#[tokio::main]`
Actix Web now works seamlessly with the primary way of starting a multi-threaded Tokio runtime, `#[tokio::main]`. Therefore, it is no longer necessary to spawn a thread when you need to run something alongside Actix Web that uses Tokio's multi-threaded mode; you can simply await the server within this context or, if preferred, use `tokio::spawn` just like any other async task.
For now, `actix` actor support (and therefore WebSocket support via `actix-web-actors`) still requires `#[actix_web::main]` so that a `System` context is created. Designs are being created for an alternative WebSocket interface that does not require actors that should land sometime in the v4.x cycle.
## `web::block`
The `web::block` helper has changed return type from roughly `async fn(fn() -> Result<T, E>) Result<T, BlockingError<E>>` to `async fn(fn() -> T) Result<T, BlockingError>`. That's to say that the blocking function can now return things that are not `Result`s and it does not wrap error types anymore. If you still need to return `Result`s then you'll likely want to use double `?` after the `.await`.
```diff
- let n: u32 = web::block(|| Ok(123)).await?;
+ let n: u32 = web::block(|| 123).await?;
- let n: u32 = web::block(|| Ok(123)).await?;
+ let n: u32 = web::block(|| Ok(123)).await??;
```

View File

@ -6,10 +6,10 @@
<p> <p>
[![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web) [![crates.io](https://img.shields.io/crates/v/actix-web?label=latest)](https://crates.io/crates/actix-web)
[![Documentation](https://docs.rs/actix-web/badge.svg?version=4.0.0-rc.2)](https://docs.rs/actix-web/4.0.0-rc.2) [![Documentation](https://docs.rs/actix-web/badge.svg?version=4.0.0-rc.3)](https://docs.rs/actix-web/4.0.0-rc.3)
![MSRV](https://img.shields.io/badge/rustc-1.54+-ab6000.svg) ![MSRV](https://img.shields.io/badge/rustc-1.54+-ab6000.svg)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-web.svg)
[![Dependency Status](https://deps.rs/crate/actix-web/4.0.0-rc.2/status.svg)](https://deps.rs/crate/actix-web/4.0.0-rc.2) [![Dependency Status](https://deps.rs/crate/actix-web/4.0.0-rc.3/status.svg)](https://deps.rs/crate/actix-web/4.0.0-rc.3)
<br /> <br />
[![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml) [![CI](https://github.com/actix/actix-web/actions/workflows/ci.yml/badge.svg)](https://github.com/actix/actix-web/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web) [![codecov](https://codecov.io/gh/actix/actix-web/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-web)
@ -32,7 +32,7 @@
- Static assets - Static assets
- SSL support using OpenSSL or Rustls - SSL support using OpenSSL or Rustls
- Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) - Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/))
- Includes an async [HTTP client](https://docs.rs/awc/) - Integrates with the [`awc` HTTP client](https://docs.rs/awc/)
- Runs on stable Rust 1.54+ - Runs on stable Rust 1.54+
## Documentation ## Documentation
@ -71,22 +71,24 @@ async fn main() -> std::io::Result<()> {
} }
``` ```
### More examples ### More Examples
- [Basic Setup](https://github.com/actix/examples/tree/master/basics/basics/) - [Hello World](https://github.com/actix/examples/tree/master/basics/hello-world)
- [Application State](https://github.com/actix/examples/tree/master/basics/state/) - [Basic Setup](https://github.com/actix/examples/tree/master/basics/basics)
- [JSON Handling](https://github.com/actix/examples/tree/master/json/json/) - [Application State](https://github.com/actix/examples/tree/master/basics/state)
- [Multipart Streams](https://github.com/actix/examples/tree/master/forms/multipart/) - [JSON Handling](https://github.com/actix/examples/tree/master/json/json)
- [Diesel Integration](https://github.com/actix/examples/tree/master/database_interactions/diesel/) - [Multipart Streams](https://github.com/actix/examples/tree/master/forms/multipart)
- [r2d2 Integration](https://github.com/actix/examples/tree/master/database_interactions/r2d2/) - [Diesel Integration](https://github.com/actix/examples/tree/master/databases/diesel)
- [Simple WebSocket](https://github.com/actix/examples/tree/master/websockets/websocket/) - [SQLite Integration](https://github.com/actix/examples/tree/master/databases/sqlite)
- [Tera Templates](https://github.com/actix/examples/tree/master/template_engines/tera/) - [Postgres Integration](https://github.com/actix/examples/tree/master/databases/postgres)
- [Askama Templates](https://github.com/actix/examples/tree/master/template_engines/askama/) - [Tera Templates](https://github.com/actix/examples/tree/master/templating/tera)
- [HTTPS using Rustls](https://github.com/actix/examples/tree/master/security/rustls/) - [Askama Templates](https://github.com/actix/examples/tree/master/templating/askama)
- [HTTPS using OpenSSL](https://github.com/actix/examples/tree/master/security/openssl/) - [HTTPS using Rustls](https://github.com/actix/examples/tree/master/https-tls/rustls)
- [WebSocket Chat](https://github.com/actix/examples/tree/master/websockets/chat/) - [HTTPS using OpenSSL](https://github.com/actix/examples/tree/master/https-tls/openssl)
- [Simple WebSocket](https://github.com/actix/examples/tree/master/websockets)
- [WebSocket Chat](https://github.com/actix/examples/tree/master/websockets/chat)
You may consider checking out [this directory](https://github.com/actix/examples/tree/master/) for more examples. You may consider checking out [this directory](https://github.com/actix/examples/tree/master) for more examples.
## Benchmarks ## Benchmarks
@ -101,5 +103,4 @@ This project is licensed under either of the following licenses, at your option:
## Code of Conduct ## Code of Conduct
Contribution to the actix-web repo is organized under the terms of the Contributor Covenant. Contribution to the actix-web repo is organized under the terms of the Contributor Covenant. The Actix team promises to intervene to uphold that code of conduct.
The Actix team promises to intervene to uphold that code of conduct.

View File

@ -2,7 +2,7 @@
//! properties and pass them to a handler through request-local data. //! properties and pass them to a handler through request-local data.
//! //!
//! For an example of extracting a client TLS certificate, see: //! For an example of extracting a client TLS certificate, see:
//! <https://github.com/actix/examples/tree/HEAD/security/rustls-client-cert> //! <https://github.com/actix/examples/tree/master/https-tls/rustls-client-cert>
use std::{any::Any, io, net::SocketAddr}; use std::{any::Any, io, net::SocketAddr};

View File

@ -10,12 +10,16 @@ use crate::{
/// The interface for request handlers. /// The interface for request handlers.
/// ///
/// # What Is A Request Handler /// # What Is A Request Handler
/// A request handler has three requirements: /// In short, a handler is just an async function that receives request-based arguments, in any
/// order, and returns something that can be converted to a response.
///
/// In particular, a request handler has three requirements:
/// 1. It is an async function (or a function/closure that returns an appropriate future); /// 1. It is an async function (or a function/closure that returns an appropriate future);
/// 1. The function parameters (up to 12) implement [`FromRequest`]; /// 1. The function parameters (up to 12) implement [`FromRequest`];
/// 1. The async function (or future) resolves to a type that can be converted into an /// 1. The async function (or future) resolves to a type that can be converted into an
/// [`HttpResponse`] (i.e., it implements the [`Responder`] trait). /// [`HttpResponse`] (i.e., it implements the [`Responder`] trait).
/// ///
///
/// # Compiler Errors /// # Compiler Errors
/// If you get the error `the trait Handler<_> is not implemented`, then your handler does not /// If you get the error `the trait Handler<_> is not implemented`, then your handler does not
/// fulfill the _first_ of the above requirements. Missing other requirements manifest as errors on /// fulfill the _first_ of the above requirements. Missing other requirements manifest as errors on

View File

@ -62,18 +62,18 @@ crate::http::header::common_header! {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_http::test::TestRequest;
use super::IfNoneMatch; use super::IfNoneMatch;
use crate::http::header::{EntityTag, Header, IF_NONE_MATCH}; use crate::http::header::{EntityTag, Header, IF_NONE_MATCH};
use actix_http::test::TestRequest;
#[test] #[test]
fn test_if_none_match() { fn test_if_none_match() {
let mut if_none_match: Result<IfNoneMatch, _>;
let req = TestRequest::default() let req = TestRequest::default()
.insert_header((IF_NONE_MATCH, "*")) .insert_header((IF_NONE_MATCH, "*"))
.finish(); .finish();
if_none_match = Header::parse(&req);
let mut if_none_match = IfNoneMatch::parse(&req);
assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Any)); assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Any));
let req = TestRequest::default() let req = TestRequest::default()

View File

@ -42,28 +42,29 @@
//! and otherwise utilizing them. //! and otherwise utilizing them.
//! //!
//! # Features //! # Features
//! * Supports *HTTP/1.x* and *HTTP/2* //! - Supports HTTP/1.x and HTTP/2
//! * Streaming and pipelining //! - Streaming and pipelining
//! * Keep-alive and slow requests handling //! - Powerful [request routing](https://actix.rs/docs/url-dispatch/) with optional macros
//! * Client/server [WebSockets](https://actix.rs/docs/websockets/) support //! - Full [Tokio](https://tokio.rs) compatibility
//! * Transparent content compression/decompression (br, gzip, deflate, zstd) //! - Keep-alive and slow requests handling
//! * Powerful [request routing](https://actix.rs/docs/url-dispatch/) //! - Client/server [WebSockets](https://actix.rs/docs/websockets/) support
//! * Multipart streams //! - Transparent content compression/decompression (br, gzip, deflate, zstd)
//! * Static assets //! - Multipart streams
//! * SSL support using OpenSSL or Rustls //! - Static assets
//! * Middlewares ([Logger, Session, CORS, etc](https://actix.rs/docs/middleware/)) //! - SSL support using OpenSSL or Rustls
//! * Includes an async [HTTP client](https://docs.rs/awc/) //! - Middlewares ([Logger, Session, CORS, etc](middleware))
//! * Runs on stable Rust 1.54+ //! - Integrates with the [`awc` HTTP client](https://docs.rs/awc/)
//! - Runs on stable Rust 1.54+
//! //!
//! # Crate Features //! # Crate Features
//! * `cookies` - cookies support (enabled by default) //! - `cookies` - cookies support (enabled by default)
//! * `macros` - routing and runtime macros (enabled by default) //! - `macros` - routing and runtime macros (enabled by default)
//! * `compress-brotli` - brotli content encoding compression support (enabled by default) //! - `compress-brotli` - brotli content encoding compression support (enabled by default)
//! * `compress-gzip` - gzip and deflate content encoding compression support (enabled by default) //! - `compress-gzip` - gzip and deflate content encoding compression support (enabled by default)
//! * `compress-zstd` - zstd content encoding compression support (enabled by default) //! - `compress-zstd` - zstd content encoding compression support (enabled by default)
//! * `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2` //! - `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
//! * `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2` //! - `rustls` - HTTPS support via `rustls` crate, supports `HTTP/2`
//! * `secure-cookies` - secure cookies support //! - `secure-cookies` - secure cookies support
#![deny(rust_2018_idioms, nonstandard_style)] #![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)] #![warn(future_incompatible)]

View File

@ -0,0 +1,13 @@
# Middleware Author's Guide
## What Is A Middleware?
## Middleware Traits
## Understanding Body Types
## Best Practices
## Error Propagation
## When To (Not) Use Middleware

View File

@ -1,18 +1,22 @@
//! For middleware documentation, see [`Condition`]. //! For middleware documentation, see [`Condition`].
use std::task::{Context, Poll}; use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use actix_service::{Service, Transform}; use futures_core::{future::LocalBoxFuture, ready};
use actix_utils::future::Either;
use futures_core::future::LocalBoxFuture;
use futures_util::future::FutureExt as _; use futures_util::future::FutureExt as _;
use pin_project_lite::pin_project;
use crate::{
body::EitherBody,
dev::{Service, ServiceResponse, Transform},
};
/// Middleware for conditionally enabling other middleware. /// Middleware for conditionally enabling other middleware.
/// ///
/// The controlled middleware must not change the `Service` interfaces. This means you cannot
/// control such middlewares like `Logger` or `Compress` directly. See the [`Compat`](super::Compat)
/// middleware for a workaround.
///
/// # Examples /// # Examples
/// ``` /// ```
/// use actix_web::middleware::{Condition, NormalizePath}; /// use actix_web::middleware::{Condition, NormalizePath};
@ -36,16 +40,16 @@ impl<T> Condition<T> {
} }
} }
impl<S, T, Req> Transform<S, Req> for Condition<T> impl<S, T, Req, BE, BD, Err> Transform<S, Req> for Condition<T>
where where
S: Service<Req> + 'static, S: Service<Req, Response = ServiceResponse<BD>, Error = Err> + 'static,
T: Transform<S, Req, Response = S::Response, Error = S::Error>, T: Transform<S, Req, Response = ServiceResponse<BE>, Error = Err>,
T::Future: 'static, T::Future: 'static,
T::InitError: 'static, T::InitError: 'static,
T::Transform: 'static, T::Transform: 'static,
{ {
type Response = S::Response; type Response = ServiceResponse<EitherBody<BE, BD>>;
type Error = S::Error; type Error = Err;
type Transform = ConditionMiddleware<T::Transform, S>; type Transform = ConditionMiddleware<T::Transform, S>;
type InitError = T::InitError; type InitError = T::InitError;
type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>; type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
@ -69,14 +73,14 @@ pub enum ConditionMiddleware<E, D> {
Disable(D), Disable(D),
} }
impl<E, D, Req> Service<Req> for ConditionMiddleware<E, D> impl<E, D, Req, BE, BD, Err> Service<Req> for ConditionMiddleware<E, D>
where where
E: Service<Req>, E: Service<Req, Response = ServiceResponse<BE>, Error = Err>,
D: Service<Req, Response = E::Response, Error = E::Error>, D: Service<Req, Response = ServiceResponse<BD>, Error = Err>,
{ {
type Response = E::Response; type Response = ServiceResponse<EitherBody<BE, BD>>;
type Error = E::Error; type Error = Err;
type Future = Either<E::Future, D::Future>; type Future = ConditionMiddlewareFuture<E::Future, D::Future>;
fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
match self { match self {
@ -87,27 +91,59 @@ where
fn call(&self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
match self { match self {
ConditionMiddleware::Enable(service) => Either::left(service.call(req)), ConditionMiddleware::Enable(service) => ConditionMiddlewareFuture::Enabled {
ConditionMiddleware::Disable(service) => Either::right(service.call(req)), fut: service.call(req),
},
ConditionMiddleware::Disable(service) => ConditionMiddlewareFuture::Disabled {
fut: service.call(req),
},
} }
} }
} }
pin_project! {
#[doc(hidden)]
#[project = ConditionProj]
pub enum ConditionMiddlewareFuture<E, D> {
Enabled { #[pin] fut: E, },
Disabled { #[pin] fut: D, },
}
}
impl<E, D, BE, BD, Err> Future for ConditionMiddlewareFuture<E, D>
where
E: Future<Output = Result<ServiceResponse<BE>, Err>>,
D: Future<Output = Result<ServiceResponse<BD>, Err>>,
{
type Output = Result<ServiceResponse<EitherBody<BE, BD>>, Err>;
#[inline]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let res = match self.project() {
ConditionProj::Enabled { fut } => ready!(fut.poll(cx))?.map_into_left_body(),
ConditionProj::Disabled { fut } => ready!(fut.poll(cx))?.map_into_right_body(),
};
Poll::Ready(Ok(res))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_service::IntoService; use actix_service::IntoService as _;
use actix_utils::future::ok;
use super::*; use super::*;
use crate::{ use crate::{
body::BoxBody,
dev::{ServiceRequest, ServiceResponse}, dev::{ServiceRequest, ServiceResponse},
error::Result, error::Result,
http::{ http::{
header::{HeaderValue, CONTENT_TYPE}, header::{HeaderValue, CONTENT_TYPE},
StatusCode, StatusCode,
}, },
middleware::{err_handlers::*, Compat}, middleware::{self, ErrorHandlerResponse, ErrorHandlers},
test::{self, TestRequest}, test::{self, TestRequest},
web::Bytes,
HttpResponse, HttpResponse,
}; };
@ -120,40 +156,52 @@ mod tests {
Ok(ErrorHandlerResponse::Response(res.map_into_left_body())) Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
} }
#[test]
fn compat_with_builtin_middleware() {
let _ = Condition::new(true, middleware::Compat::noop());
let _ = Condition::new(true, middleware::Logger::default());
let _ = Condition::new(true, middleware::Compress::default());
let _ = Condition::new(true, middleware::NormalizePath::trim());
let _ = Condition::new(true, middleware::DefaultHeaders::new());
let _ = Condition::new(true, middleware::ErrorHandlers::<BoxBody>::new());
let _ = Condition::new(true, middleware::ErrorHandlers::<Bytes>::new());
}
#[actix_rt::test] #[actix_rt::test]
async fn test_handler_enabled() { async fn test_handler_enabled() {
let srv = |req: ServiceRequest| { let srv = |req: ServiceRequest| async move {
ok(req.into_response(HttpResponse::InternalServerError().finish())) let resp = HttpResponse::InternalServerError().message_body(String::new())?;
Ok(req.into_response(resp))
}; };
let mw = Compat::new( let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500),
);
let mw = Condition::new(true, mw) let mw = Condition::new(true, mw)
.new_transform(srv.into_service()) .new_transform(srv.into_service())
.await .await
.unwrap(); .unwrap();
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
let resp: ServiceResponse<EitherBody<EitherBody<_, _>, String>> =
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001"); assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_handler_disabled() { async fn test_handler_disabled() {
let srv = |req: ServiceRequest| { let srv = |req: ServiceRequest| async move {
ok(req.into_response(HttpResponse::InternalServerError().finish())) let resp = HttpResponse::InternalServerError().message_body(String::new())?;
Ok(req.into_response(resp))
}; };
let mw = Compat::new( let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500),
);
let mw = Condition::new(false, mw) let mw = Condition::new(false, mw)
.new_transform(srv.into_service()) .new_transform(srv.into_service())
.await .await
.unwrap(); .unwrap();
let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await; let resp: ServiceResponse<EitherBody<EitherBody<_, _>, String>> =
test::call_service(&mw, TestRequest::default().to_srv_request()).await;
assert_eq!(resp.headers().get(CONTENT_TYPE), None); assert_eq!(resp.headers().get(CONTENT_TYPE), None);
} }
} }

View File

@ -7,7 +7,7 @@ use crate::{HttpRequest, HttpResponse, Responder};
/// Allows overriding status code and headers for a [`Responder`]. /// Allows overriding status code and headers for a [`Responder`].
/// ///
/// Created by the [`Responder::customize`] method. /// Created by calling the [`customize`](Responder::customize) method on a [`Responder`] type.
pub struct CustomizeResponder<R> { pub struct CustomizeResponder<R> {
inner: CustomizeResponderInner<R>, inner: CustomizeResponderInner<R>,
error: Option<HttpError>, error: Option<HttpError>,

View File

@ -47,6 +47,15 @@ pub trait Responder {
CustomizeResponder::new(self) CustomizeResponder::new(self)
} }
#[doc(hidden)]
#[deprecated(since = "4.0.0", note = "Prefer `.customize().with_status(header)`.")]
fn with_status(self, status: StatusCode) -> CustomizeResponder<Self>
where
Self: Sized,
{
self.customize().with_status(status)
}
#[doc(hidden)] #[doc(hidden)]
#[deprecated(since = "4.0.0", note = "Prefer `.customize().insert_header(header)`.")] #[deprecated(since = "4.0.0", note = "Prefer `.customize().insert_header(header)`.")]
fn with_header(self, header: impl TryIntoHeaderPair) -> CustomizeResponder<Self> fn with_header(self, header: impl TryIntoHeaderPair) -> CustomizeResponder<Self>

View File

@ -1,9 +1,10 @@
//! A selection of re-exports from [`actix-rt`] and [`tokio`]. //! A selection of re-exports from [`tokio`] and [`actix-rt`].
//! //!
//! [`actix-rt`]: https://docs.rs/actix_rt //! Actix Web runs on [Tokio], providing full[^compat] compatibility with its huge ecosystem of
//! [`tokio`]: https://docs.rs/tokio //! crates. Each of the server's workers uses a single-threaded runtime. Read more about the
//! architecture in [`actix-rt`]'s docs.
//! //!
//! # Running Actix Web Macro-less //! # Running Actix Web Without Macros
//! ```no_run //! ```no_run
//! use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer}; //! use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer};
//! //!
@ -12,19 +13,53 @@
//! "Hello world!\r\n" //! "Hello world!\r\n"
//! } //! }
//! //!
//! # fn main() -> std::io::Result<()> { //! fn main() -> std::io::Result<()> {
//! rt::System::new().block_on( //! rt::System::new().block_on(
//! HttpServer::new(|| {
//! App::new().service(web::resource("/").route(web::get().to(index)))
//! })
//! .bind(("127.0.0.1", 8080))?
//! .run()
//! )
//! }
//! ```
//!
//! # Running Actix Web Using `#[tokio::main]`
//! If you need to run something alongside Actix Web that uses Tokio's work stealing functionality,
//! you can run Actix Web under `#[tokio::main]`. The [`Server`](crate::dev::Server) object returned
//! from [`HttpServer::run`](crate::HttpServer::run) can also be [`spawn`]ed, if preferred.
//!
//! Note that `actix` actor support (and therefore WebSocket support through `actix-web-actors`)
//! still require `#[actix_web::main]` since they require a [`System`] to be set up.
//!
//! ```no_run
//! use actix_web::{get, middleware, rt, web, App, HttpRequest, HttpServer};
//!
//! #[get("/")]
//! async fn index(req: HttpRequest) -> &'static str {
//! println!("REQ: {:?}", req);
//! "Hello world!\r\n"
//! }
//!
//! #[tokio::main]
//! async fn main() -> std::io::Result<()> {
//! HttpServer::new(|| { //! HttpServer::new(|| {
//! App::new() //! App::new().service(index)
//! .wrap(middleware::Logger::default())
//! .service(web::resource("/").route(web::get().to(index)))
//! }) //! })
//! .bind(("127.0.0.1", 8080))? //! .bind(("127.0.0.1", 8080))?
//! .workers(1)
//! .run() //! .run()
//! ) //! .await
//! # } //! }
//! ``` //! ```
//!
//! [^compat]: Crates that use Tokio's [`block_in_place`] will not work with Actix Web. Fortunately,
//! the vast majority of Tokio-based crates do not use it.
//!
//! [`actix-rt`]: https://docs.rs/actix-rt
//! [`tokio`]: https://docs.rs/tokio
//! [Tokio]: https://docs.rs/tokio
//! [`spawn`]: https://docs.rs/tokio/1/tokio/fn.spawn.html
//! [`block_in_place`]: https://docs.rs/tokio/1/tokio/task/fn.block_in_place.html
// In particular: // In particular:
// - Omit the `Arbiter` types because they have limited value here. // - Omit the `Arbiter` types because they have limited value here.

View File

@ -128,7 +128,7 @@ where
/// Set number of workers to start. /// Set number of workers to start.
/// ///
/// By default, server uses number of available logical CPU as thread count. /// By default, the number of available physical CPUs is used as the worker count.
pub fn workers(mut self, num: usize) -> Self { pub fn workers(mut self, num: usize) -> Self {
self.builder = self.builder.workers(num); self.builder = self.builder.workers(num);
self self

View File

@ -53,9 +53,7 @@ use crate::{
/// format!("Welcome {}!", info.name) /// format!("Welcome {}!", info.name)
/// } /// }
/// ``` /// ```
#[derive( #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deref, DerefMut, AsRef, Display, From)]
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deref, DerefMut, AsRef, Display, From,
)]
pub struct Path<T>(T); pub struct Path<T>(T);
impl<T> Path<T> { impl<T> Path<T> {

View File

@ -3,6 +3,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 3.0.0-beta.21 - 2022-02-16
- No significant changes since `3.0.0-beta.20`.
## 3.0.0-beta.20 - 2022-01-31 ## 3.0.0-beta.20 - 2022-01-31
- No significant changes since `3.0.0-beta.19`. - No significant changes since `3.0.0-beta.19`.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "awc" name = "awc"
version = "3.0.0-beta.20" version = "3.0.0-beta.21"
authors = [ authors = [
"Nikolay Kim <fafhrd91@gmail.com>", "Nikolay Kim <fafhrd91@gmail.com>",
"fakeshadow <24548779@qq.com>", "fakeshadow <24548779@qq.com>",
@ -58,11 +58,11 @@ __compress = []
dangerous-h2c = [] dangerous-h2c = []
[dependencies] [dependencies]
actix-codec = "0.4.1" actix-codec = "0.5"
actix-service = "2.0.0" actix-service = "2.0.0"
actix-http = { version = "3.0.0-rc.1", features = ["http2", "ws"] } actix-http = { version = "3.0.0-rc.3", features = ["http2", "ws"] }
actix-rt = { version = "2.1", default-features = false } actix-rt = { version = "2.1", default-features = false }
actix-tls = { version = "3.0.0", features = ["connect", "uri"] } actix-tls = { version = "3", features = ["connect", "uri"] }
actix-utils = "3.0.0" actix-utils = "3.0.0"
ahash = "0.7" ahash = "0.7"
@ -93,13 +93,13 @@ tls-rustls = { package = "rustls", version = "0.20.0", optional = true, features
trust-dns-resolver = { version = "0.20.0", optional = true } trust-dns-resolver = { version = "0.20.0", optional = true }
[dev-dependencies] [dev-dependencies]
actix-http = { version = "3.0.0-rc.1", features = ["openssl"] } actix-http = { version = "3.0.0-rc.3", features = ["openssl"] }
actix-http-test = { version = "3.0.0-beta.12", features = ["openssl"] } actix-http-test = { version = "3.0.0-beta.13", features = ["openssl"] }
actix-server = "2" actix-server = "2"
actix-test = { version = "0.1.0-beta.12", features = ["openssl", "rustls"] } actix-test = { version = "0.1.0-beta.13", features = ["openssl", "rustls"] }
actix-tls = { version = "3.0.0", features = ["openssl", "rustls"] } actix-tls = { version = "3", features = ["openssl", "rustls"] }
actix-utils = "3.0.0" actix-utils = "3.0.0"
actix-web = { version = "4.0.0-rc.2", features = ["openssl"] } actix-web = { version = "4.0.0-rc.3", features = ["openssl"] }
brotli = "3.3.3" brotli = "3.3.3"
const-str = "0.3" const-str = "0.3"

View File

@ -3,15 +3,15 @@
> Async HTTP and WebSocket client library. > Async HTTP and WebSocket client library.
[![crates.io](https://img.shields.io/crates/v/awc?label=latest)](https://crates.io/crates/awc) [![crates.io](https://img.shields.io/crates/v/awc?label=latest)](https://crates.io/crates/awc)
[![Documentation](https://docs.rs/awc/badge.svg?version=3.0.0-beta.20)](https://docs.rs/awc/3.0.0-beta.20) [![Documentation](https://docs.rs/awc/badge.svg?version=3.0.0-beta.21)](https://docs.rs/awc/3.0.0-beta.21)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc) ![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/awc)
[![Dependency Status](https://deps.rs/crate/awc/3.0.0-beta.20/status.svg)](https://deps.rs/crate/awc/3.0.0-beta.20) [![Dependency Status](https://deps.rs/crate/awc/3.0.0-beta.21/status.svg)](https://deps.rs/crate/awc/3.0.0-beta.21)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x) [![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)
## Documentation & Resources ## Documentation & Resources
- [API Documentation](https://docs.rs/awc) - [API Documentation](https://docs.rs/awc)
- [Example Project](https://github.com/actix/examples/tree/HEAD/security/awc_https) - [Example Project](https://github.com/actix/examples/tree/master/https-tls/awc-https)
- Minimum Supported Rust Version (MSRV): 1.54 - Minimum Supported Rust Version (MSRV): 1.54
## Example ## Example

View File

@ -160,7 +160,7 @@ impl<S: fmt::Debug> fmt::Debug for AnyBody<S> {
mod tests { mod tests {
use std::marker::PhantomPinned; use std::marker::PhantomPinned;
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*; use super::*;
@ -181,12 +181,12 @@ mod tests {
} }
} }
assert_impl_all!(AnyBody<()>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody<()>: Send, Sync, Unpin, fmt::Debug, MessageBody);
assert_impl_all!(AnyBody<AnyBody<()>>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody<AnyBody<()>>: Send, Sync, Unpin, fmt::Debug, MessageBody);
assert_impl_all!(AnyBody<Bytes>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody<Bytes>: Send, Sync, Unpin, fmt::Debug, MessageBody);
assert_impl_all!(AnyBody: MessageBody, fmt::Debug, Unpin); assert_impl_all!(AnyBody: Unpin, fmt::Debug, MessageBody);
assert_impl_all!(AnyBody<PinType>: MessageBody); assert_impl_all!(AnyBody<PinType>: Send, Sync, MessageBody);
assert_not_impl_all!(AnyBody: Send, Sync, Unpin); assert_not_impl_any!(AnyBody: Send, Sync);
assert_not_impl_all!(AnyBody<PinType>: Send, Sync, Unpin); assert_not_impl_any!(AnyBody<PinType>: Unpin);
} }

View File

@ -337,7 +337,7 @@ where
match self.get_mut() { match self.get_mut() {
Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf), Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf),
Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf), Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf),
_ => unreachable!(H2_UNREACHABLE_WRITE), _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
} }
} }
@ -345,7 +345,7 @@ where
match self.get_mut() { match self.get_mut() {
Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx), Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx),
Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx), Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx),
_ => unreachable!(H2_UNREACHABLE_WRITE), _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
} }
} }
@ -353,7 +353,7 @@ where
match self.get_mut() { match self.get_mut() {
Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx), Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx),
Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx), Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx),
_ => unreachable!(H2_UNREACHABLE_WRITE), _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
} }
} }
@ -369,7 +369,7 @@ where
Connection::Tls(ConnectionType::H1(conn)) => { Connection::Tls(ConnectionType::H1(conn)) => {
Pin::new(conn).poll_write_vectored(cx, bufs) Pin::new(conn).poll_write_vectored(cx, bufs)
} }
_ => unreachable!(H2_UNREACHABLE_WRITE), _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
} }
} }
@ -377,7 +377,7 @@ where
match *self { match *self {
Connection::Tcp(ConnectionType::H1(ref conn)) => conn.is_write_vectored(), Connection::Tcp(ConnectionType::H1(ref conn)) => conn.is_write_vectored(),
Connection::Tls(ConnectionType::H1(ref conn)) => conn.is_write_vectored(), Connection::Tls(ConnectionType::H1(ref conn)) => conn.is_write_vectored(),
_ => unreachable!(H2_UNREACHABLE_WRITE), _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
} }
} }
} }

View File

@ -34,7 +34,7 @@ digraph {
"utils" -> { "service" "rt" "codec" } "utils" -> { "service" "rt" "codec" }
"tracing" -> { "service" } "tracing" -> { "service" }
"tls" -> { "service" "codec" "utils" } "tls" -> { "service" "codec" "utils" }
"server" -> { "service" "rt" "codec" "utils" } "server" -> { "service" "rt" "utils" }
"rt" -> { "macros" } "rt" -> { "macros" }
{ rank=same; "utils" "codec" }; { rank=same; "utils" "codec" };

View File

@ -9,7 +9,16 @@ unreleased_for() {
DIR=$1 DIR=$1
CARGO_MANIFEST=$DIR/Cargo.toml CARGO_MANIFEST=$DIR/Cargo.toml
CHANGELOG_FILE=$DIR/CHANGES.md
# determine changelog file name
if [ -f "$DIR/CHANGES.md" ]; then
CHANGELOG_FILE=$DIR/CHANGES.md
elif [ -f "$DIR/CHANGELOG.md" ]; then
CHANGELOG_FILE=$DIR/CHANGELOG.md
else
echo "No changelog file found"
exit 1
fi
# get current version # get current version
PACKAGE_NAME="$(sed -nE 's/^name ?= ?"([^"]+)"$/\1/ p' "$CARGO_MANIFEST" | head -n 1)" PACKAGE_NAME="$(sed -nE 's/^name ?= ?"([^"]+)"$/\1/ p' "$CARGO_MANIFEST" | head -n 1)"
@ -36,6 +45,6 @@ unreleased_for() {
cat "$CHANGE_CHUNK_FILE" cat "$CHANGE_CHUNK_FILE"
} }
for f in $(fd --absolute-path CHANGES.md); do for f in $(fd --absolute-path 'CHANGE\w+.md'); do
unreleased_for $(dirname $f) unreleased_for $(dirname $f)
done done