diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml
index d19471a16..828d62561 100644
--- a/.github/workflows/bench.yml
+++ b/.github/workflows/bench.yml
@@ -1,4 +1,4 @@
-name: Benchmark (Linux)
+name: Benchmark
on:
pull_request:
diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml
index fb1ed7f32..e966fa4ab 100644
--- a/.github/workflows/clippy-fmt.yml
+++ b/.github/workflows/clippy-fmt.yml
@@ -1,32 +1,39 @@
+name: Lint
+
on:
pull_request:
types: [opened, synchronize, reopened]
-name: Clippy and rustfmt Check
jobs:
- clippy_check:
+ fmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- - uses: actions-rs/toolchain@v1
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt
- override: true
- name: Check with rustfmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- - uses: actions-rs/toolchain@v1
+ clippy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install Rust
+ uses: actions-rs/toolchain@v1
with:
- toolchain: nightly
+ toolchain: stable
components: clippy
override: true
- name: Check with Clippy
uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
- args: --all-features --all --tests
+ args: --workspace --tests --all-features
diff --git a/.github/workflows/upload-doc.yml b/.github/workflows/upload-doc.yml
index ba87a5637..c080dd8c3 100644
--- a/.github/workflows/upload-doc.yml
+++ b/.github/workflows/upload-doc.yml
@@ -24,7 +24,7 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: doc
- args: --no-deps --workspace --all-features
+ args: --workspace --all-features --no-deps
- name: Tweak HTML
run: echo "" > target/doc/index.html
diff --git a/CHANGES.md b/CHANGES.md
index a6bcd56cc..9a3b7fe3e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,6 +4,8 @@
### Added
* The method `Either, web::Form>::into_inner()` which returns the inner type for
whichever variant was created. Also works for `Either, web::Json>`. [#1894]
+* Add `services!` macro for helping register multiple services to `App`. [#1933]
+* Enable registering vector of same type of `HttpServiceFactory` to `App` [#1933]
### Changed
* Rework `Responder` trait to be sync and returns `Response`/`HttpResponse` directly.
@@ -11,7 +13,12 @@
* `ServiceRequest::into_parts` and `ServiceRequest::from_parts` would not fail.
`ServiceRequest::from_request` would not fail and no payload would be generated [#1893]
* 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`
+ in argument [#1905]
+* `App::wrap_fn`, `Resource::wrap_fn` and `Scope::wrap_fn` would give `&Service` in closure
+ argument [#1905]
+* `web::block` accept any closure that has an output bound to `Send` and `'static`. [#1957]
+
### Fixed
* Multiple calls `App::data` with the same type now keeps the latest call's data. [#1906]
@@ -27,7 +34,10 @@
[#1893]: https://github.com/actix/actix-web/pull/1893
[#1894]: https://github.com/actix/actix-web/pull/1894
[#1869]: https://github.com/actix/actix-web/pull/1869
+[#1905]: https://github.com/actix/actix-web/pull/1905
[#1906]: https://github.com/actix/actix-web/pull/1906
+[#1933]: https://github.com/actix/actix-web/pull/1933
+[#1957]: https://github.com/actix/actix-web/pull/1957
## 4.0.0-beta.1 - 2021-01-07
diff --git a/Cargo.toml b/Cargo.toml
index bae6cb6cb..479a89f87 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -47,10 +47,10 @@ compress = ["actix-http/compress", "awc/compress"]
secure-cookies = ["actix-http/secure-cookies"]
# openssl
-openssl = ["actix-tls/accept", "actix-tls/openssl", "awc/openssl", "open-ssl"]
+openssl = ["tls_openssl", "actix-tls/accept", "actix-tls/openssl", "awc/openssl"]
# rustls
-rustls = ["actix-tls/accept", "actix-tls/rustls", "awc/rustls", "rust-tls"]
+rustls = ["tls_rustls", "actix-tls/accept", "actix-tls/rustls", "awc/rustls"]
[[example]]
name = "basic"
@@ -74,19 +74,19 @@ required-features = ["rustls"]
[dependencies]
actix-codec = "0.4.0-beta.1"
-actix-macros = "0.1.0"
-actix-router = "0.2.4"
-actix-rt = "2.0.0-beta.2"
-actix-server = "2.0.0-beta.2"
-actix-service = "2.0.0-beta.3"
-actix-utils = "3.0.0-beta.1"
-actix-tls = { version = "3.0.0-beta.2", default-features = false, optional = true }
+actix-macros = "0.2.0"
+actix-router = "0.2.7"
+actix-rt = "2"
+actix-server = "2.0.0-beta.3"
+actix-service = "2.0.0-beta.4"
+actix-utils = "3.0.0-beta.2"
+actix-tls = { version = "3.0.0-beta.3", default-features = false, optional = true }
actix-web-codegen = "0.4.0"
actix-http = "3.0.0-beta.1"
awc = { version = "3.0.0-beta.1", default-features = false }
-ahash = "0.6"
+ahash = "0.7"
bytes = "1"
derive_more = "0.99.5"
either = "1.5.3"
@@ -101,14 +101,14 @@ regex = "1.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_urlencoded = "0.7"
-time = { version = "0.2.7", default-features = false, features = ["std"] }
+time = { version = "0.2.23", default-features = false, features = ["std"] }
url = "2.1"
-open-ssl = { package = "openssl", version = "0.10", optional = true }
-rust-tls = { package = "rustls", version = "0.19.0", optional = true }
+tls_openssl = { package = "openssl", version = "0.10.9", optional = true }
+tls_rustls = { package = "rustls", version = "0.19.0", optional = true }
smallvec = "1.6"
[dev-dependencies]
-actix = "0.11.0-beta.1"
+actix = { version = "0.11.0-beta.2", default-features = false }
actix-http = { version = "3.0.0-beta.1", features = ["actors"] }
rand = "0.8"
env_logger = "0.8"
diff --git a/README.md b/README.md
index 956bb3741..8a703117f 100644
--- a/README.md
+++ b/README.md
@@ -11,10 +11,9 @@

[](https://deps.rs/crate/actix-web/3.3.2)
-[](https://travis-ci.org/actix/actix-web)
+[](https://github.com/actix/actix-web/actions)
[](https://codecov.io/gh/actix/actix-web)
-[](https://crates.io/crates/actix-web)
-[](https://gitter.im/actix/actix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
[](https://discord.gg/NWpN5mmg3x)
@@ -99,9 +98,9 @@ One of the fastest web frameworks available according to the
This project is licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
- [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0))
+ [http://www.apache.org/licenses/LICENSE-2.0])
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
- [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
+ [http://opensource.org/licenses/MIT])
at your option.
diff --git a/actix-files/CHANGES.md b/actix-files/CHANGES.md
index 9f606dfcd..8e5566b61 100644
--- a/actix-files/CHANGES.md
+++ b/actix-files/CHANGES.md
@@ -2,8 +2,10 @@
## Unreleased - 2021-xx-xx
* Fix If-Modified-Since and If-Unmodified-Since to not compare using sub-second timestamps. [#1887]
+* Replace `v_htmlescape` with `askama_escape`. [#1953]
[#1887]: https://github.com/actix/actix-web/pull/1887
+[#1953]: https://github.com/actix/actix-web/pull/1953
## 0.6.0-beta.1 - 2021-01-07
* `HttpRange::parse` now has its own error type.
diff --git a/actix-files/Cargo.toml b/actix-files/Cargo.toml
index bde2cb717..b4317596c 100644
--- a/actix-files/Cargo.toml
+++ b/actix-files/Cargo.toml
@@ -18,7 +18,9 @@ path = "src/lib.rs"
[dependencies]
actix-web = { version = "4.0.0-beta.1", default-features = false }
-actix-service = "2.0.0-beta.3"
+actix-service = "2.0.0-beta.4"
+
+askama_escape = "0.10"
bitflags = "1"
bytes = "1"
futures-core = { version = "0.3.7", default-features = false }
@@ -28,8 +30,7 @@ log = "0.4"
mime = "0.3"
mime_guess = "2.0.1"
percent-encoding = "2.1"
-v_htmlescape = "0.12"
[dev-dependencies]
-actix-rt = "2.0.0-beta.2"
+actix-rt = "2"
actix-web = "4.0.0-beta.1"
diff --git a/actix-files/src/chunked.rs b/actix-files/src/chunked.rs
index 5b7b17dc4..2a62b1d26 100644
--- a/actix-files/src/chunked.rs
+++ b/actix-files/src/chunked.rs
@@ -8,7 +8,7 @@ use std::{
};
use actix_web::{
- error::{Error, ErrorInternalServerError},
+ error::{BlockingError, Error},
rt::task::{spawn_blocking, JoinHandle},
};
use bytes::Bytes;
@@ -18,11 +18,26 @@ use futures_core::{ready, Stream};
/// A helper created from a `std::fs::File` which reads the file
/// chunk-by-chunk on a `ThreadPool`.
pub struct ChunkedReadFile {
- pub(crate) size: u64,
- pub(crate) offset: u64,
- pub(crate) file: Option,
- pub(crate) fut: Option>>,
- pub(crate) counter: u64,
+ size: u64,
+ offset: u64,
+ state: ChunkedReadFileState,
+ counter: u64,
+}
+
+enum ChunkedReadFileState {
+ File(Option),
+ Future(JoinHandle>),
+}
+
+impl ChunkedReadFile {
+ pub(crate) fn new(size: u64, offset: u64, file: File) -> Self {
+ Self {
+ size,
+ offset,
+ state: ChunkedReadFileState::File(Some(file)),
+ counter: 0,
+ }
+ }
}
impl fmt::Debug for ChunkedReadFile {
@@ -38,49 +53,52 @@ impl Stream for ChunkedReadFile {
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll