1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-08-12 12:17:08 +02:00

Compare commits

..

70 Commits

Author SHA1 Message Date
Rob Ede
d5a9a6a1c5 prepare actix-utils release 3.0.1 2022-10-21 03:15:48 +01:00
Rob Ede
ade71b7bd3 address soundness footgun in poll_fn 2022-10-21 03:14:38 +01:00
Rob Ede
cb83922b29 add macos test note 2022-10-17 04:27:34 +01:00
Rob Ede
25209f5bd8 use impl-more in -tls 2022-10-17 04:14:09 +01:00
Rob Ede
c4a0f37d0c fix minimal versions for bytestring 2022-07-23 03:06:44 +01:00
Rob Ede
0e649329b9 fix minimal versions 2022-07-23 01:47:59 +01:00
Rob Ede
66756bc448 update all crates msrv to 1.57 (#464) 2022-07-23 00:51:12 +01:00
Iskandarov Lev
126ed4c2e3 normalize logs capital letter (#463)
Co-authored-by: Rob Ede <robjtede@icloud.com>
2022-07-22 20:53:06 +01:00
Yuki Okushi
283974f3e6 Make actix-codec an optional dependency (#459) 2022-06-23 17:27:36 +01:00
Yuki Okushi
bf2aa3902c Set depth of --feature-powerset on Windows CI (#460) 2022-06-12 02:17:38 +01:00
Rob Ede
71b4e55c92 prepare bytestring release 1.1.0 (#461) 2022-06-11 13:41:11 +01:00
Marcus Griep
eb5fa30ada feat: impls for Box and String conversions (#458)
Co-authored-by: Rob Ede <robjtede@icloud.com>
2022-06-11 04:22:34 +01:00
Rob Ede
49a034259f prepare local-waker release 0.1.3 2022-05-03 14:58:09 +01:00
Rob Ede
3337f63b4e prepare local-channel release 0.1.3 2022-05-03 14:56:40 +01:00
Rob Ede
86ce140249 ensure all crates include license files
closes #456
2022-05-03 14:55:49 +01:00
Guillaume Desmottes
635aebe887 actix-server: fix UNIX signal handling documentation (#455) 2022-05-03 13:37:18 +01:00
Rob Ede
4c1e581a54 add track_caller atrtibute to spawn calls (#454)
* add track_caller attribute to spawn calls

* fix ci
2022-04-25 21:05:48 +01:00
Rob Ede
dc67ba770d fmt with import grouping 2022-04-10 02:48:53 +01:00
Rob Ede
855e3f96fe prepare actix-tls release 3.0.4 2022-03-15 19:43:47 +00:00
Rob Ede
737b438f73 prepare actix-codec release 0.5.1 2022-03-15 19:43:06 +00:00
Rob Ede
0cd70b0536 use tracing for logs (#451) 2022-03-15 19:37:08 +00:00
Rob Ede
4b6a581ef3 prepare actix-server release 2.1.1 2022-03-09 01:08:35 +00:00
Rob Ede
3e132d2bc6 update tokio-uring to 0.3 (#448) 2022-03-08 23:42:52 +00:00
Rob Ede
c5d6174cec add tracing support 2022-03-08 22:13:55 +00:00
Rob Ede
77d4a69b2f update tokio-uring to 0.3 (#449) 2022-03-08 21:57:02 +00:00
Rob Ede
ae5377fd6e update readme 2022-03-08 21:12:46 +00:00
Rob Ede
bd9bda0504 fix readme msrv notes 2022-03-02 16:42:53 +00:00
Rob Ede
41ed48219d bump lower msrv to 1.49 2022-03-02 16:40:11 +00:00
fakeshadow
7804ed12eb block and wait for accept thread to exit. (#443)
Co-authored-by: Rob Ede <robjtede@icloud.com>
2022-03-02 03:52:12 +00:00
Rob Ede
2a54065fae parallel master tests using nextest 2022-02-15 14:19:00 +00:00
Rob Ede
217cbd2228 bump tokio-util to 0.7 (#446) 2022-02-15 01:47:27 +00:00
Rob Ede
d229c1e886 fix min ver check 2022-02-12 08:42:13 +00:00
Rob Ede
6792f799a6 add minimal-versions check 2022-02-12 08:37:56 +00:00
Rob Ede
72481313cc update readme 2022-01-28 22:28:24 +00:00
Rob Ede
59b629c74b fix deps badge 2022-01-28 22:17:12 +00:00
Rob Ede
7988694242 update msrv info 2022-01-28 22:15:16 +00:00
Rob Ede
b8a7741524 fix bind_addr 2022-01-28 22:13:10 +00:00
Rob Ede
5e290d76f8 prepare actix-tls release 3.0.2 2022-01-28 22:11:21 +00:00
Rob Ede
0edb64575f update tls changelog 2022-01-28 22:10:24 +00:00
Rob Ede
941f67dec9 s/e/err 2022-01-28 22:10:06 +00:00
Babur
3e624b8376 Made new constructor for the Connection type public (#439) 2022-01-28 22:09:54 +00:00
Ibraheem Ahmed
26446fdbad Replace derive_more with declarative macros (#438)
Co-authored-by: Rob Ede <robjtede@icloud.com>
2022-01-28 22:09:33 +00:00
Rob Ede
b7b7bd2cbf add actix-server readme 2022-01-19 16:14:06 +00:00
Rob Ede
637625f9b7 prepare actix-server release 2.0.0 (#437) 2022-01-19 14:57:50 +00:00
Rob Ede
b1d5d85e72 prepare actix-server release 2.0.0-rc.4 2022-01-12 14:40:06 +00:00
Rob Ede
ed2c07b304 prepare actix-rt release 2.6.0 2022-01-12 14:40:06 +00:00
Rob Ede
4fe7fec5ef update tokio-uring to 0.2.0 (#436) 2022-01-11 23:36:49 +00:00
Rob Ede
4c9ee88ec4 prepare actix-tls release 3.0.1 2022-01-11 22:17:31 +00:00
david-mcgillicuddy-moixa
9ec3cc0fe7 Replace str_split_once to lower actix-tls msrv to 1.50.0 and bump actix-net to 1.50.0 (#434) 2022-01-10 17:00:04 +00:00
Rob Ede
01e0f922de fix ci 2021-12-31 08:38:37 +00:00
Rob Ede
10d3bb6d0d only run coverage on master ci 2021-12-31 08:36:13 +00:00
Rob Ede
3ba4eafde5 prepare actix-server release 2.0.0-rc.3 2021-12-31 08:09:28 +00:00
Rob Ede
5faa98f6d2 prepare actix-rt release 2.5.1 2021-12-31 08:09:10 +00:00
Rob Ede
b552d847ed prepare actix-codec release 0.4.2 2021-12-31 08:08:14 +00:00
Rob Ede
5058e2d14e bump tokio in local-channel dev deps 2021-12-31 08:06:41 +00:00
Rob Ede
ae9afd4de7 prepare actix-server release 2.0.0-rc.2 2021-12-27 18:33:57 +00:00
Rob Ede
01d2f18f68 simplify test server (#431) 2021-12-27 18:27:54 +00:00
Rob Ede
e92b5aaf31 expose with_tokio_rt (#430) 2021-12-27 16:00:26 +00:00
Rob Ede
459a6d1b02 update readme 2021-12-27 00:57:16 +00:00
Rob Ede
9935883905 add file reader example 2021-12-26 22:32:35 +00:00
Rob Ede
89a4c2ee27 prepare actix-tls release 3.0.0 2021-12-26 21:12:19 +00:00
Rob Ede
a4681831a7 fix changelogs 2021-12-18 03:35:18 +00:00
Rob Ede
5d2da0fdc7 prepare actix-service release 2.0.2 2021-12-18 03:26:59 +00:00
Rob Ede
ef18a8342e prepare local-waker release 0.1.2 2021-12-18 03:20:49 +00:00
Rob Ede
621deba990 fix changelog bullet points 2021-12-18 02:49:23 +00:00
Rob Ede
6a9f13c8b4 inline simple future functions 2021-12-18 02:18:01 +00:00
Rob Ede
705b31230f fix impl assertion tests 2021-12-18 02:17:48 +00:00
Rob Ede
eb490a9125 re-export openssl connector builder (#429) 2021-12-10 23:11:24 +00:00
Rob Ede
90f205a465 standardize crate level lints 2021-12-08 06:09:46 +00:00
Rob Ede
3a3d654cea use "physical" cpu cores as default worker count 2021-12-08 05:42:54 +00:00
90 changed files with 1494 additions and 869 deletions

View File

@@ -14,13 +14,10 @@ ci-check = "hack --workspace --feature-powerset --exclude-features=io-uring chec
ci-check-linux = "hack --workspace --feature-powerset check --tests --examples"
# tests avoiding io-uring feature
ci-test = " hack --feature-powerset --exclude=actix-rt --exclude=actix-server --exclude-features=io-uring test --workspace --lib --tests --no-fail-fast -- --nocapture"
ci-test-rt = " hack --feature-powerset --exclude-features=io-uring test --package=actix-rt --lib --tests --no-fail-fast -- --nocapture"
ci-test-server = "hack --feature-powerset --exclude-features=io-uring test --package=actix-server --lib --tests --no-fail-fast -- --nocapture"
ci-test = "hack --feature-powerset --exclude-features=io-uring test --lib --tests --no-fail-fast -- --nocapture"
# tests avoiding io-uring feature on Windows
ci-test-win = "hack --feature-powerset --depth 2 --exclude-features=io-uring test --lib --tests --no-fail-fast -- --nocapture"
# test with io-uring feature
ci-test-rt-linux = " hack --feature-powerset test --package=actix-rt --lib --tests --no-fail-fast -- --nocapture"
ci-test-server-linux = "hack --feature-powerset test --package=actix-server --lib --tests --no-fail-fast -- --nocapture"
# test lower msrv
ci-test-lower-msrv = "hack --workspace --exclude=actix-server --exclude=actix-tls --feature-powerset test --lib --tests --no-fail-fast -- --nocapture"
ci-test-linux = " hack --feature-powerset test --lib --tests --no-fail-fast -- --nocapture"

210
.github/workflows/ci-master.yml vendored Normal file
View File

@@ -0,0 +1,210 @@
name: CI (master only)
on:
push:
branches: [master]
jobs:
build_and_test_nightly:
strategy:
fail-fast: false
matrix:
target:
- { name: Linux, os: ubuntu-latest, triple: x86_64-unknown-linux-gnu }
- { name: macOS, os: macos-latest, triple: x86_64-apple-darwin }
- { name: Windows, os: windows-latest, triple: x86_64-pc-windows-msvc }
- { name: Windows (MinGW), os: windows-latest, triple: x86_64-pc-windows-gnu }
- { name: Windows (32-bit), os: windows-latest, triple: i686-pc-windows-msvc }
version:
- nightly
name: ${{ matrix.target.name }} / ${{ matrix.version }}
runs-on: ${{ matrix.target.os }}
env:
VCPKGRS_DYNAMIC: 1
steps:
- name: Setup Routing
if: matrix.target.os == 'macos-latest'
run: sudo ifconfig lo0 alias 127.0.0.3
- uses: actions/checkout@v2
# install OpenSSL on Windows
- name: Set vcpkg root
if: matrix.target.triple == 'x86_64-pc-windows-msvc' || matrix.target.triple == 'i686-pc-windows-msvc'
run: echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Install OpenSSL
if: matrix.target.triple == 'x86_64-pc-windows-msvc'
run: vcpkg install openssl:x64-windows
- name: Install OpenSSL
if: matrix.target.triple == 'i686-pc-windows-msvc'
run: vcpkg install openssl:x86-windows
- name: Install ${{ matrix.version }}
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.version }}-${{ matrix.target.triple }}
profile: minimal
override: true
# - name: Install MSYS2
# if: matrix.target.triple == 'x86_64-pc-windows-gnu'
# uses: msys2/setup-msys2@v2
# - name: Install MinGW Packages
# if: matrix.target.triple == 'x86_64-pc-windows-gnu'
# run: |
# msys2 -c 'pacman -Sy --noconfirm pacman'
# msys2 -c 'pacman --noconfirm -S base-devel pkg-config'
# - name: Generate Cargo.lock
# uses: actions-rs/cargo@v1
# with: { command: generate-lockfile }
# - name: Cache Dependencies
# uses: Swatinem/rust-cache@v1.2.0
- name: Install cargo-hack
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-hack
- name: check lib
if: >
matrix.target.os != 'ubuntu-latest'
&& matrix.target.triple != 'x86_64-pc-windows-gnu'
uses: actions-rs/cargo@v1
with: { command: ci-check-lib }
- name: check lib
if: matrix.target.os == 'ubuntu-latest'
uses: actions-rs/cargo@v1
with: { command: ci-check-lib-linux }
- name: check lib
if: matrix.target.triple == 'x86_64-pc-windows-gnu'
uses: actions-rs/cargo@v1
with: { command: ci-check-min }
- name: check full
# TODO: compile OpenSSL and run tests on MinGW
if: >
matrix.target.os != 'ubuntu-latest'
&& matrix.target.triple != 'x86_64-pc-windows-gnu'
uses: actions-rs/cargo@v1
with: { command: ci-check }
- name: check all
if: matrix.target.os == 'ubuntu-latest'
uses: actions-rs/cargo@v1
with: { command: ci-check-linux }
- name: tests
if: >
matrix.target.os != 'ubuntu-latest'
&& matrix.target.triple != 'x86_64-pc-windows-gnu'
run: cargo ci-test
- name: tests
if: matrix.target.os == 'ubuntu-latest'
run: |
sudo bash -c "ulimit -Sl 512 && ulimit -Hl 512 && PATH=$PATH:/usr/share/rust/.cargo/bin && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test-linux"
- name: Clear the cargo caches
run: |
cargo install cargo-cache --version 0.6.2 --no-default-features --features ci-autoclean
cargo-cache
coverage:
name: coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust (nightly)
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
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: Generate coverage file
if: github.ref == 'refs/heads/master'
run: |
cargo install cargo-tarpaulin
cargo tarpaulin --out Xml --verbose
- name: Upload to Codecov
if: github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v1
with: { file: cobertura.xml }
minimal-versions:
name: minimal versions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust (nightly)
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
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-minimal-versions
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-minimal-versions
- name: Install cargo-hack
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-hack
- name: Check With Minimal Versions
uses: actions-rs/cargo@v1
with:
command: minimal-versions
args: check
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

@@ -18,9 +18,8 @@ jobs:
- { name: Windows (MinGW), os: windows-latest, triple: x86_64-pc-windows-gnu }
- { name: Windows (32-bit), os: windows-latest, triple: i686-pc-windows-msvc }
version:
- 1.52.0 # MSRV for -server and -tls
- 1.57.0
- stable
- nightly
name: ${{ matrix.target.name }} / ${{ matrix.version }}
runs-on: ${{ matrix.target.os }}
@@ -74,6 +73,10 @@ jobs:
command: install
args: cargo-hack
- name: Generate Cargo.lock
uses: actions-rs/cargo@v1
with: { command: generate-lockfile }
- name: check lib
if: >
matrix.target.os != 'ubuntu-latest'
@@ -88,7 +91,7 @@ jobs:
if: matrix.target.triple == 'x86_64-pc-windows-gnu'
uses: actions-rs/cargo@v1
with: { command: ci-check-min }
- name: check full
# TODO: compile OpenSSL and run tests on MinGW
if: >
@@ -101,80 +104,23 @@ jobs:
uses: actions-rs/cargo@v1
with: { command: ci-check-linux }
- name: tests
if: matrix.target.os == 'macos-latest'
run: cargo ci-test
- name: tests
if: >
matrix.target.os != 'ubuntu-latest'
matrix.target.os == 'windows-latest'
&& matrix.target.triple != 'x86_64-pc-windows-gnu'
run: |
cargo ci-test
cargo ci-test-rt
cargo ci-test-server
run: cargo ci-test-win
- name: tests
if: matrix.target.os == 'ubuntu-latest'
run: |
sudo bash -c "ulimit -Sl 512 && ulimit -Hl 512 && PATH=$PATH:/usr/share/rust/.cargo/bin && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test-rt-linux && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test-server-linux"
sudo bash -c "ulimit -Sl 512 && ulimit -Hl 512 && PATH=$PATH:/usr/share/rust/.cargo/bin && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test && RUSTUP_TOOLCHAIN=${{ matrix.version }} cargo ci-test-linux"
- name: Clear the cargo caches
run: |
cargo install cargo-cache --version 0.6.2 --no-default-features --features ci-autoclean
cargo-cache
build_and_test_lower_msrv:
name: Linux / 1.46 (lower MSRV)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install 1.46.0 # MSRV for all but -server and -tls
uses: actions-rs/toolchain@v1
with:
toolchain: 1.46.0-x86_64-unknown-linux-gnu
profile: minimal
override: true
- name: Install cargo-hack
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-hack
- name: tests
run: |
sudo bash -c "ulimit -Sl 512 && ulimit -Hl 512 && PATH=$PATH:/usr/share/rust/.cargo/bin && RUSTUP_TOOLCHAIN=1.46 cargo ci-test-lower-msrv"
- name: Clear the cargo caches
run: |
cargo install cargo-cache --version 0.6.2 --no-default-features --features ci-autoclean
cargo-cache
coverage:
name: coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust (nightly)
uses: actions-rs/toolchain@v1
with:
toolchain: stable-x86_64-unknown-linux-gnu
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: Generate coverage file
if: github.ref == 'refs/heads/master'
run: |
cargo install cargo-tarpaulin
cargo tarpaulin --out Xml --verbose
- name: Upload to Codecov
if: github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v1
with: { file: cobertura.xml }
rustdoc:
name: rustdoc

View File

@@ -2,29 +2,25 @@
> A collection of lower-level libraries for composable network services.
![Apache 2.0 or MIT licensed](https://img.shields.io/crates/l/actix-server)
[![CI](https://github.com/actix/actix-net/actions/workflows/ci.yml/badge.svg?event=push&style=flat-square)](https://github.com/actix/actix-net/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/actix/actix-net/branch/master/graph/badge.svg)](https://codecov.io/gh/actix/actix-net)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)
[![Dependency Status](https://deps.rs/repo/github/actix/actix-net/status.svg)](https://deps.rs/repo/github/actix/actix-net)
## Build statuses
| Platform | Build Status |
| ---------------- | ------------ |
| Linux | [![build status](https://github.com/actix/actix-net/workflows/CI%20%28Linux%29/badge.svg?branch=master&event=push)](https://github.com/actix/actix-net/actions?query=workflow%3A"CI+(Linux)") |
| macOS | [![build status](https://github.com/actix/actix-net/workflows/CI%20%28macOS%29/badge.svg?branch=master&event=push)](https://github.com/actix/actix-net/actions?query=workflow%3A"CI+(macOS)") |
| Windows | [![build status](https://github.com/actix/actix-net/workflows/CI%20%28Windows%29/badge.svg?branch=master&event=push)](https://github.com/actix/actix-net/actions?query=workflow%3A"CI+(Windows)") |
| Windows (MinGW) | [![build status](https://github.com/actix/actix-net/workflows/CI%20%28Windows-mingw%29/badge.svg?branch=master&event=push)](https://github.com/actix/actix-net/actions?query=workflow%3A"CI+(Windows-mingw)") |
## Examples
## Example
See `actix-server/examples` and `actix-tls/examples` for some basic examples.
See example folders for [`actix-server`](./actix-server/examples) and [`actix-tls`](./actix-tls/examples).
### MSRV
This repo's Minimum Supported Rust Version (MSRV) is 1.46.0.
## MSRV
Most crates in this repo's have a Minimum Supported Rust Version (MSRV) of 1.49.0. Only `actix-tls` and `actix-server` have MSRV of 1.54.0. As a policy, we permit MSRV increases in non-breaking releases.
## License
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))
* MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
The crates in repo are 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))
- MIT license ([LICENSE-MIT](LICENSE-MIT) or [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT))
at your option.

View File

@@ -1,71 +1,89 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 0.5.1 - 2022-03-15
- Logs emitted now use the `tracing` crate with `log` compatibility. [#451]
- Minimum supported Rust version (MSRV) is now 1.49.
[#451]: https://github.com/actix/actix-net/pull/451
## 0.5.0 - 2022-02-15
- Updated `tokio-util` dependency to `0.7.0`. [#446]
[#446]: https://github.com/actix/actix-net/pull/446
## 0.4.2 - 2021-12-31
- No significant changes since `0.4.1`.
## 0.4.1 - 2021-11-05
* Added `LinesCodec.` [#338]
* `Framed::poll_ready` flushes when the buffer is full. [#409]
- Added `LinesCodec.` [#338]
- `Framed::poll_ready` flushes when the buffer is full. [#409]
[#338]: https://github.com/actix/actix-net/pull/338
[#409]: https://github.com/actix/actix-net/pull/409
## 0.4.0 - 2021-04-20
* No significant changes since v0.4.0-beta.1.
- No significant changes since v0.4.0-beta.1.
## 0.4.0-beta.1 - 2020-12-28
* Replace `pin-project` with `pin-project-lite`. [#237]
* Upgrade `tokio` dependency to `1`. [#237]
* Upgrade `tokio-util` dependency to `0.6`. [#237]
* Upgrade `bytes` dependency to `1`. [#237]
- Replace `pin-project` with `pin-project-lite`. [#237]
- Upgrade `tokio` dependency to `1`. [#237]
- Upgrade `tokio-util` dependency to `0.6`. [#237]
- Upgrade `bytes` dependency to `1`. [#237]
[#237]: https://github.com/actix/actix-net/pull/237
## 0.3.0 - 2020-08-23
* No changes from beta 2.
- No changes from beta 2.
## 0.3.0-beta.2 - 2020-08-19
* Remove unused type parameter from `Framed::replace_codec`.
- Remove unused type parameter from `Framed::replace_codec`.
## 0.3.0-beta.1 - 2020-08-19
* Use `.advance()` instead of `.split_to()`.
* Upgrade `tokio-util` to `0.3`.
* Improve `BytesCodec::encode()` performance.
* Simplify `BytesCodec::decode()`.
* Rename methods on `Framed` to better describe their use.
* Add method on `Framed` to get a pinned reference to the underlying I/O.
* Add method on `Framed` check emptiness of read buffer.
- Use `.advance()` instead of `.split_to()`.
- Upgrade `tokio-util` to `0.3`.
- Improve `BytesCodec::encode()` performance.
- Simplify `BytesCodec::decode()`.
- Rename methods on `Framed` to better describe their use.
- Add method on `Framed` to get a pinned reference to the underlying I/O.
- Add method on `Framed` check emptiness of read buffer.
## 0.2.0 - 2019-12-10
* Use specific futures dependencies.
- Use specific futures dependencies.
## 0.2.0-alpha.4
* Fix buffer remaining capacity calculation.
- Fix buffer remaining capacity calculation.
## 0.2.0-alpha.3
* Use tokio 0.2.
* Fix low/high watermark for write/read buffers.
- Use tokio 0.2.
- Fix low/high watermark for write/read buffers.
## 0.2.0-alpha.2
* Migrated to `std::future`.
- Migrated to `std::future`.
## 0.1.2 - 2019-03-27
* Added `Framed::map_io()` method.
- Added `Framed::map_io()` method.
## 0.1.1 - 2019-03-06
* Added `FramedParts::with_read_buffer()` method.
- Added `FramedParts::with_read_buffer()` method.
## 0.1.0 - 2018-12-09
* Move codec to separate crate.
- Move codec to separate crate.

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-codec"
version = "0.4.1"
version = "0.5.1"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@@ -17,15 +17,15 @@ name = "actix_codec"
path = "src/lib.rs"
[dependencies]
bitflags = "1.2.1"
bitflags = "1.2"
bytes = "1"
futures-core = { version = "0.3.7", default-features = false }
futures-sink = { version = "0.3.7", default-features = false }
log = "0.4"
memchr = "2.3"
pin-project-lite = "0.2"
tokio = "1.5.1"
tokio-util = { version = "0.6", features = ["codec", "io"] }
tokio = "1.13.1"
tokio-util = { version = "0.7", features = ["codec", "io"] }
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
[dev-dependencies]
criterion = { version = "0.3", features = ["html_reports"] }

View File

@@ -156,7 +156,7 @@ impl<T, U> Framed<T, U> {
}
impl<T, U> Framed<T, U> {
/// Serialize item and Write to the inner buffer
/// Serialize item and write to the inner buffer
pub fn write<I>(mut self: Pin<&mut Self>, item: I) -> Result<(), <U as Encoder<I>>::Error>
where
T: AsyncWrite,
@@ -193,18 +193,18 @@ impl<T, U> Framed<T, U> {
match this.codec.decode_eof(this.read_buf) {
Ok(Some(frame)) => return Poll::Ready(Some(Ok(frame))),
Ok(None) => return Poll::Ready(None),
Err(e) => return Poll::Ready(Some(Err(e))),
Err(err) => return Poll::Ready(Some(Err(err))),
}
}
log::trace!("attempting to decode a frame");
tracing::trace!("attempting to decode a frame");
match this.codec.decode(this.read_buf) {
Ok(Some(frame)) => {
log::trace!("frame decoded from buffer");
tracing::trace!("frame decoded from buffer");
return Poll::Ready(Some(Ok(frame)));
}
Err(e) => return Poll::Ready(Some(Err(e))),
Err(err) => return Poll::Ready(Some(Err(err))),
_ => (), // Need more data
}
@@ -221,7 +221,7 @@ impl<T, U> Framed<T, U> {
let cnt = match tokio_util::io::poll_read_buf(this.io, cx, this.read_buf) {
Poll::Pending => return Poll::Pending,
Poll::Ready(Err(e)) => return Poll::Ready(Some(Err(e.into()))),
Poll::Ready(Err(err)) => return Poll::Ready(Some(Err(err.into()))),
Poll::Ready(Ok(cnt)) => cnt,
};
@@ -242,10 +242,10 @@ impl<T, U> Framed<T, U> {
U: Encoder<I>,
{
let mut this = self.as_mut().project();
log::trace!("flushing framed transport");
tracing::trace!("flushing framed transport");
while !this.write_buf.is_empty() {
log::trace!("writing; remaining={}", this.write_buf.len());
tracing::trace!("writing; remaining={}", this.write_buf.len());
let n = ready!(this.io.as_mut().poll_write(cx, this.write_buf))?;
@@ -264,7 +264,7 @@ impl<T, U> Framed<T, U> {
// Try flushing the underlying IO
ready!(this.io.poll_flush(cx))?;
log::trace!("framed transport flushed");
tracing::trace!("framed transport flushed");
Poll::Ready(Ok(()))
}

View File

@@ -7,8 +7,8 @@
//! [`Sink`]: futures_sink::Sink
//! [`Stream`]: futures_core::Stream
#![deny(rust_2018_idioms, nonstandard_style, future_incompatible)]
#![warn(missing_docs)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible, missing_docs)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
@@ -16,10 +16,10 @@ mod bcodec;
mod framed;
mod lines;
pub use self::bcodec::BytesCodec;
pub use self::framed::{Framed, FramedParts};
pub use self::lines::LinesCodec;
pub use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
pub use tokio_util::codec::{Decoder, Encoder};
pub use tokio_util::io::poll_read_buf;
pub use self::bcodec::BytesCodec;
pub use self::framed::{Framed, FramedParts};
pub use self::lines::LinesCodec;

View File

@@ -7,8 +7,8 @@ use super::{Decoder, Encoder};
/// Lines codec. Reads/writes line delimited strings.
///
/// Will split input up by LF or CRLF delimiters. I.e. carriage return characters at the end of
/// lines are not preserved.
/// Will split input up by LF or CRLF delimiters. Carriage return characters at the end of lines are
/// not preserved.
#[derive(Debug, Copy, Clone, Default)]
#[non_exhaustive]
pub struct LinesCodec;

View File

@@ -1,12 +1,16 @@
use std::{
collections::VecDeque,
io::{self, Write},
pin::Pin,
task::{
Context,
Poll::{self, Pending, Ready},
},
};
use actix_codec::*;
use bytes::Buf;
use bytes::{BufMut, BytesMut};
use bytes::{Buf as _, BufMut as _, BytesMut};
use futures_sink::Sink;
use std::collections::VecDeque;
use std::io::{self, Write};
use std::pin::Pin;
use std::task::Poll::{Pending, Ready};
use std::task::{Context, Poll};
use tokio_test::{assert_ready, task};
macro_rules! bilateral {
@@ -50,7 +54,7 @@ impl Write for Bilateral {
assert_eq!(&data[..], &src[..data.len()]);
Ok(data.len())
}
Some(Err(e)) => Err(e),
Some(Err(err)) => Err(err),
None => panic!("unexpected write; {:?}", src),
}
}
@@ -67,13 +71,13 @@ impl AsyncWrite for Bilateral {
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
match Pin::get_mut(self).write(buf) {
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Pending,
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => Pending,
other => Ready(other),
}
}
fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
match Pin::get_mut(self).flush() {
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Pending,
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => Pending,
other => Ready(other),
}
}
@@ -99,8 +103,8 @@ impl AsyncRead for Bilateral {
buf.put_slice(&data);
Ready(Ok(()))
}
Some(Err(ref e)) if e.kind() == WouldBlock => Pending,
Some(Err(e)) => Ready(Err(e)),
Some(Err(ref err)) if err.kind() == WouldBlock => Pending,
Some(Err(err)) => Ready(Err(err)),
None => Ready(Ok(())),
}
}

View File

@@ -1,46 +1,47 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 0.2.3 - 2021-10-19
* Fix test macro in presence of other imports named "test". [#399]
- Fix test macro in presence of other imports named "test". [#399]
[#399]: https://github.com/actix/actix-net/pull/399
## 0.2.2 - 2021-10-14
* Improve error recovery potential when macro input is invalid. [#391]
* Allow custom `System`s on test macro. [#391]
- Improve error recovery potential when macro input is invalid. [#391]
- Allow custom `System`s on test macro. [#391]
[#391]: https://github.com/actix/actix-net/pull/391
## 0.2.1 - 2021-02-02
* Add optional argument `system` to `main` macro which can be used to specify the path to `actix_rt::System` (useful for re-exports). [#363]
- Add optional argument `system` to `main` macro which can be used to specify the path to `actix_rt::System` (useful for re-exports). [#363]
[#363]: https://github.com/actix/actix-net/pull/363
## 0.2.0 - 2021-02-02
* Update to latest `actix_rt::System::new` signature. [#261]
- Update to latest `actix_rt::System::new` signature. [#261]
[#261]: https://github.com/actix/actix-net/pull/261
## 0.2.0-beta.1 - 2021-01-09
* Remove `actix-reexport` feature. [#218]
- Remove `actix-reexport` feature. [#218]
[#218]: https://github.com/actix/actix-net/pull/218
## 0.1.3 - 2020-12-03
* Add `actix-reexport` feature. [#218]
- Add `actix-reexport` feature. [#218]
[#218]: https://github.com/actix/actix-net/pull/218
## 0.1.2 - 2020-05-18
* Forward actix_rt::test arguments to test function [#127]
- Forward actix_rt::test arguments to test function [#127]
[#127]: https://github.com/actix/actix-net/pull/127

View File

@@ -9,6 +9,7 @@
//! See docs for the [`#[test]`](macro@test) macro.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

View File

@@ -1,32 +1,55 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Add `#[track_caller]` attribute to `spawn` functions and methods. [#454]
- Minimum supported Rust version (MSRV) is now 1.57.
[#454]: https://github.com/actix/actix-net/pull/454
## 2.7.0 - 2022-03-08
- Update `tokio-uring` dependency to `0.3.0`. [#448]
- Minimum supported Rust version (MSRV) is now 1.49.
[#448]: https://github.com/actix/actix-net/pull/448
## 2.6.0 - 2022-01-12
- Update `tokio-uring` dependency to `0.2.0`. [#436]
[#436]: https://github.com/actix/actix-net/pull/436
## 2.5.1 - 2021-12-31
- Expose `System::with_tokio_rt` and `Arbiter::with_tokio_rt`. [#430]
[#430]: https://github.com/actix/actix-net/pull/430
## 2.5.0 - 2021-11-22
* Add `System::run_with_code` to allow retrieving the exit code on stop. [#411]
- Add `System::run_with_code` to allow retrieving the exit code on stop. [#411]
[#411]: https://github.com/actix/actix-net/pull/411
## 2.4.0 - 2021-11-05
* Add `Arbiter::try_current` for situations where thread may or may not have Arbiter context. [#408]
* Start io-uring with `System::new` when feature is enabled. [#395]
- Add `Arbiter::try_current` for situations where thread may or may not have Arbiter context. [#408]
- Start io-uring with `System::new` when feature is enabled. [#395]
[#395]: https://github.com/actix/actix-net/pull/395
[#408]: https://github.com/actix/actix-net/pull/408
## 2.3.0 - 2021-10-11
* The `spawn` method can now resolve with non-unit outputs. [#369]
* Add experimental (semver-exempt) `io-uring` feature for enabling async file I/O on linux. [#374]
- The `spawn` method can now resolve with non-unit outputs. [#369]
- Add experimental (semver-exempt) `io-uring` feature for enabling async file I/O on linux. [#374]
[#369]: https://github.com/actix/actix-net/pull/369
[#374]: https://github.com/actix/actix-net/pull/374
## 2.2.0 - 2021-03-29
* **BREAKING** `ActixStream::{poll_read_ready, poll_write_ready}` methods now return
- **BREAKING** `ActixStream::{poll_read_ready, poll_write_ready}` methods now return
`Ready` object in ok variant. [#293]
* Breakage is acceptable since `ActixStream` was not intended to be public.
@@ -34,51 +57,51 @@
## 2.1.0 - 2021-02-24
* Add `ActixStream` extension trait to include readiness methods. [#276]
* Re-export `tokio::net::TcpSocket` in `net` module [#282]
- Add `ActixStream` extension trait to include readiness methods. [#276]
- Re-export `tokio::net::TcpSocket` in `net` module [#282]
[#276]: https://github.com/actix/actix-net/pull/276
[#282]: https://github.com/actix/actix-net/pull/282
## 2.0.2 - 2021-02-06
* Add `Arbiter::handle` to get a handle of an owned Arbiter. [#274]
* Add `System::try_current` for situations where actix may or may not be running a System. [#275]
- Add `Arbiter::handle` to get a handle of an owned Arbiter. [#274]
- Add `System::try_current` for situations where actix may or may not be running a System. [#275]
[#274]: https://github.com/actix/actix-net/pull/274
[#275]: https://github.com/actix/actix-net/pull/275
## 2.0.1 - 2021-02-06
* Expose `JoinError` from Tokio. [#271]
- Expose `JoinError` from Tokio. [#271]
[#271]: https://github.com/actix/actix-net/pull/271
## 2.0.0 - 2021-02-02
* Remove all Arbiter-local storage methods. [#262]
* Re-export `tokio::pin`. [#262]
- Remove all Arbiter-local storage methods. [#262]
- Re-export `tokio::pin`. [#262]
[#262]: https://github.com/actix/actix-net/pull/262
## 2.0.0-beta.3 - 2021-01-31
* Remove `run_in_tokio`, `attach_to_tokio` and `AsyncSystemRunner`. [#253]
* Return `JoinHandle` from `actix_rt::spawn`. [#253]
* Remove old `Arbiter::spawn`. Implementation is now inlined into `actix_rt::spawn`. [#253]
* Rename `Arbiter::{send => spawn}` and `Arbiter::{exec_fn => spawn_fn}`. [#253]
* Remove `Arbiter::exec`. [#253]
* Remove deprecated `Arbiter::local_join` and `Arbiter::is_running`. [#253]
* `Arbiter::spawn` now accepts !Unpin futures. [#256]
* `System::new` no longer takes arguments. [#257]
* Remove `System::with_current`. [#257]
* Remove `Builder`. [#257]
* Add `System::with_init` as replacement for `Builder::run`. [#257]
* Rename `System::{is_set => is_registered}`. [#257]
* Add `ArbiterHandle` for sending messages to non-current-thread arbiters. [#257].
* `System::arbiter` now returns an `&ArbiterHandle`. [#257]
* `Arbiter::current` now returns an `ArbiterHandle` instead. [#257]
* `Arbiter::join` now takes self by value. [#257]
- Remove `run_in_tokio`, `attach_to_tokio` and `AsyncSystemRunner`. [#253]
- Return `JoinHandle` from `actix_rt::spawn`. [#253]
- Remove old `Arbiter::spawn`. Implementation is now inlined into `actix_rt::spawn`. [#253]
- Rename `Arbiter::{send => spawn}` and `Arbiter::{exec_fn => spawn_fn}`. [#253]
- Remove `Arbiter::exec`. [#253]
- Remove deprecated `Arbiter::local_join` and `Arbiter::is_running`. [#253]
- `Arbiter::spawn` now accepts !Unpin futures. [#256]
- `System::new` no longer takes arguments. [#257]
- Remove `System::with_current`. [#257]
- Remove `Builder`. [#257]
- Add `System::with_init` as replacement for `Builder::run`. [#257]
- Rename `System::{is_set => is_registered}`. [#257]
- Add `ArbiterHandle` for sending messages to non-current-thread arbiters. [#257].
- `System::arbiter` now returns an `&ArbiterHandle`. [#257]
- `Arbiter::current` now returns an `ArbiterHandle` instead. [#257]
- `Arbiter::join` now takes self by value. [#257]
[#253]: https://github.com/actix/actix-net/pull/253
[#254]: https://github.com/actix/actix-net/pull/254
@@ -87,37 +110,37 @@
## 2.0.0-beta.2 - 2021-01-09
* Add `task` mod with re-export of `tokio::task::{spawn_blocking, yield_now, JoinHandle}` [#245]
* Add default "macros" feature to allow faster compile times when using `default-features=false`.
- Add `task` mod with re-export of `tokio::task::{spawn_blocking, yield_now, JoinHandle}` [#245]
- Add default "macros" feature to allow faster compile times when using `default-features=false`.
[#245]: https://github.com/actix/actix-net/pull/245
## 2.0.0-beta.1 - 2020-12-28
* Add `System::attach_to_tokio` method. [#173]
* Update `tokio` dependency to `1.0`. [#236]
* Rename `time` module `delay_for` to `sleep`, `delay_until` to `sleep_until`, `Delay` to `Sleep`
- Add `System::attach_to_tokio` method. [#173]
- Update `tokio` dependency to `1.0`. [#236]
- Rename `time` module `delay_for` to `sleep`, `delay_until` to `sleep_until`, `Delay` to `Sleep`
to stay aligned with Tokio's naming. [#236]
* Remove `'static` lifetime requirement for `Runtime::block_on` and `SystemRunner::block_on`.
- Remove `'static` lifetime requirement for `Runtime::block_on` and `SystemRunner::block_on`.
* These methods now accept `&self` when calling. [#236]
* Remove `'static` lifetime requirement for `System::run` and `Builder::run`. [#236]
* `Arbiter::spawn` now panics when `System` is not in scope. [#207]
* Fix work load issue by removing `PENDING` thread local. [#207]
- Remove `'static` lifetime requirement for `System::run` and `Builder::run`. [#236]
- `Arbiter::spawn` now panics when `System` is not in scope. [#207]
- Fix work load issue by removing `PENDING` thread local. [#207]
[#207]: https://github.com/actix/actix-net/pull/207
[#236]: https://github.com/actix/actix-net/pull/236
## 1.1.1 - 2020-04-30
* Fix memory leak due to [#94] (see [#129] for more detail)
- Fix memory leak due to [#94] (see [#129] for more detail)
[#129]: https://github.com/actix/actix-net/issues/129
## 1.1.0 - 2020-04-08 _(YANKED)_
* Expose `System::is_set` to check if current system has ben started [#99]
* Add `Arbiter::is_running` to check if event loop is running [#124]
* Add `Arbiter::local_join` associated function
- Expose `System::is_set` to check if current system has ben started [#99]
- Add `Arbiter::is_running` to check if event loop is running [#124]
- Add `Arbiter::local_join` associated function
to get be able to `await` for spawned futures [#94]
[#94]: https://github.com/actix/actix-net/pull/94
@@ -126,55 +149,55 @@
## 1.0.0 - 2019-12-11
* Update dependencies
- Update dependencies
## 1.0.0-alpha.3 - 2019-12-07
* Migrate to tokio 0.2
* Fix compilation on non-unix platforms
- Migrate to tokio 0.2
- Fix compilation on non-unix platforms
## 1.0.0-alpha.2 - 2019-12-02
* Export `main` and `test` attribute macros
* Export `time` module (re-export of tokio-timer)
* Export `net` module (re-export of tokio-net)
- Export `main` and `test` attribute macros
- Export `time` module (re-export of tokio-timer)
- Export `net` module (re-export of tokio-net)
## 1.0.0-alpha.1 - 2019-11-22
* Migrate to std::future and tokio 0.2
- Migrate to std::future and tokio 0.2
## 0.2.6 - 2019-11-14
* Allow to join arbiter's thread. #60
* Fix arbiter's thread panic message.
- Allow to join arbiter's thread. #60
- Fix arbiter's thread panic message.
## 0.2.5 - 2019-09-02
* Add arbiter specific storage
- Add arbiter specific storage
## 0.2.4 - 2019-07-17
* Avoid a copy of the Future when initializing the Box. #29
- Avoid a copy of the Future when initializing the Box. #29
## 0.2.3 - 2019-06-22
* Allow to start System using existing CurrentThread Handle #22
- Allow to start System using existing CurrentThread Handle #22
## 0.2.2 - 2019-03-28
* Moved `blocking` module to `actix-threadpool` crate
- Moved `blocking` module to `actix-threadpool` crate
## 0.2.1 - 2019-03-11
* Added `blocking` module
* Added `Arbiter::exec_fn` - execute fn on the arbiter's thread
* Added `Arbiter::exec` - execute fn on the arbiter's thread and wait result
- Added `blocking` module
- Added `Arbiter::exec_fn` - execute fn on the arbiter's thread
- Added `Arbiter::exec` - execute fn on the arbiter's thread and wait result
## 0.2.0 - 2019-03-06
* `run` method returns `io::Result<()>`
* Removed `Handle`
- `run` method returns `io::Result<()>`
- Removed `Handle`
## 0.1.0 - 2018-12-09
* Initial release
- Initial release

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-rt"
version = "2.5.0"
version = "2.7.0"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@@ -27,11 +27,12 @@ io-uring = ["tokio-uring"]
actix-macros = { version = "0.2.3", optional = true }
futures-core = { version = "0.3", default-features = false }
tokio = { version = "1.5.1", features = ["rt", "net", "parking_lot", "signal", "sync", "time"] }
tokio = { version = "1.13.1", features = ["rt", "net", "parking_lot", "signal", "sync", "time"] }
# runtime for `io-uring` feature
[target.'cfg(target_os = "linux")'.dependencies]
tokio-uring = { version = "0.1", optional = true }
tokio-uring = { version = "0.3", optional = true }
[dev-dependencies]
tokio = { version = "1.5.1", features = ["full"] }
hyper = { version = "0.14", default-features = false, features = ["server", "tcp", "http1"] }
tokio = { version = "1.13.1", features = ["full"] }
hyper = { version = "0.14.10", default-features = false, features = ["server", "tcp", "http1"] }

View File

@@ -3,11 +3,11 @@
> Tokio-based single-threaded async runtime for the Actix ecosystem.
[![crates.io](https://img.shields.io/crates/v/actix-rt?label=latest)](https://crates.io/crates/actix-rt)
[![Documentation](https://docs.rs/actix-rt/badge.svg?version=2.5.0)](https://docs.rs/actix-rt/2.5.0)
[![Documentation](https://docs.rs/actix-rt/badge.svg?version=2.7.0)](https://docs.rs/actix-rt/2.7.0)
[![Version](https://img.shields.io/badge/rustc-1.46+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.46.html)
![MIT or Apache 2.0 licensed](https://img.shields.io/crates/l/actix-rt.svg)
<br />
[![dependency status](https://deps.rs/crate/actix-rt/2.5.0/status.svg)](https://deps.rs/crate/actix-rt/2.5.0)
[![dependency status](https://deps.rs/crate/actix-rt/2.7.0/status.svg)](https://deps.rs/crate/actix-rt/2.7.0)
![Download](https://img.shields.io/crates/d/actix-rt.svg)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/WghFtEH6Hb)

View File

@@ -1,7 +1,9 @@
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Request, Response, Server};
use std::convert::Infallible;
use std::net::SocketAddr;
use std::{convert::Infallible, net::SocketAddr};
use hyper::{
service::{make_service_fn, service_fn},
Body, Request, Response, Server,
};
async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("Hello World")))
@@ -21,8 +23,8 @@ fn main() {
let server =
Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000))).serve(make_service);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
if let Err(err) = server.await {
eprintln!("server error: {}", err);
}
})
}

View File

@@ -108,7 +108,6 @@ impl Arbiter {
///
/// [tokio-runtime]: tokio::runtime::Runtime
#[cfg(not(all(target_os = "linux", feature = "io-uring")))]
#[doc(hidden)]
pub fn with_tokio_rt<F>(runtime_factory: F) -> Arbiter
where
F: Fn() -> tokio::runtime::Runtime + Send + 'static,
@@ -261,6 +260,7 @@ impl Arbiter {
/// If you require a result, include a response channel in the future.
///
/// Returns true if future was sent successfully and false if the Arbiter has died.
#[track_caller]
pub fn spawn<Fut>(&self, future: Fut) -> bool
where
Fut: Future<Output = ()> + Send + 'static,
@@ -276,6 +276,7 @@ impl Arbiter {
/// channel in the function.
///
/// Returns true if function was sent successfully and false if the Arbiter has died.
#[track_caller]
pub fn spawn_fn<F>(&self, f: F) -> bool
where
F: FnOnce() + Send + 'static,

View File

@@ -41,7 +41,7 @@
//! In particular, when running a `System`, only `System::block_on` is supported.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
#![allow(clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
@@ -51,13 +51,10 @@ compile_error!("io_uring is a linux only feature.");
use std::future::Future;
use tokio::task::JoinHandle;
// Cannot define a main macro when compiled into test harness.
// Workaround for https://github.com/rust-lang/rust/issues/62127.
#[cfg(all(feature = "macros", not(test)))]
pub use actix_macros::main;
#[cfg(feature = "macros")]
pub use actix_macros::test;
@@ -65,12 +62,13 @@ mod arbiter;
mod runtime;
mod system;
pub use tokio::pin;
use tokio::task::JoinHandle;
pub use self::arbiter::{Arbiter, ArbiterHandle};
pub use self::runtime::Runtime;
pub use self::system::{System, SystemRunner};
pub use tokio::pin;
pub mod signal {
//! Asynchronous signal handling (Tokio re-exports).
@@ -95,7 +93,6 @@ pub mod net {
use tokio::io::{AsyncRead, AsyncWrite, Interest};
pub use tokio::net::UdpSocket;
pub use tokio::net::{TcpListener, TcpSocket, TcpStream};
#[cfg(unix)]
pub use tokio::net::{UnixDatagram, UnixListener, UnixStream};
@@ -198,6 +195,7 @@ pub mod task {
/// assert!(handle.await.unwrap_err().is_cancelled());
/// # });
/// ```
#[track_caller]
#[inline]
pub fn spawn<Fut>(f: Fut) -> JoinHandle<Fut::Output>
where

View File

@@ -53,6 +53,7 @@ impl Runtime {
/// # Panics
/// This function panics if the spawn fails. Failure occurs if the executor is currently at
/// capacity and is unable to spawn a new future.
#[track_caller]
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
where
F: Future + 'static,
@@ -73,6 +74,7 @@ impl Runtime {
///
/// The caller is responsible for ensuring that other spawned futures complete execution by
/// calling `block_on` or `run`.
#[track_caller]
pub fn block_on<F>(&self, f: F) -> F::Output
where
F: Future,

View File

@@ -46,7 +46,6 @@ impl System {
/// Create a new System using the [Tokio Runtime](tokio-runtime) returned from a closure.
///
/// [tokio-runtime]: tokio::runtime::Runtime
#[doc(hidden)]
pub fn with_tokio_rt<F>(runtime_factory: F) -> SystemRunner
where
F: Fn() -> tokio::runtime::Runtime,
@@ -205,6 +204,7 @@ impl SystemRunner {
}
/// Runs the provided future, blocking the current thread until the future completes.
#[track_caller]
#[inline]
pub fn block_on<F: Future>(&self, fut: F) -> F::Output {
self.rt.block_on(fut)

View File

@@ -4,7 +4,6 @@ use std::{
};
use actix_rt::{task::JoinError, Arbiter, System};
#[cfg(not(feature = "io-uring"))]
use {
std::{sync::mpsc::channel, thread},

View File

@@ -1,48 +1,82 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 2.1.1 - 2022-03-09
- No significant changes since `2.1.0`.
## 2.1.0 - 2022-03-08
- Update `tokio-uring` dependency to `0.3.0`. [#448]
- Logs emitted now use the `tracing` crate with `log` compatibility. [#448]
- Wait for accept thread to stop before sending completion signal. [#443]
[#443]: https://github.com/actix/actix-net/pull/443
[#448]: https://github.com/actix/actix-net/pull/448
## 2.0.0 - 2022-01-19
- No significant changes since `2.0.0-rc.4`.
## 2.0.0-rc.4 - 2022-01-12
- Update `tokio-uring` dependency to `0.2.0`. [#436]
[#436]: https://github.com/actix/actix-net/pull/436
## 2.0.0-rc.3 - 2021-12-31
- No significant changes since `2.0.0-rc.2`.
## 2.0.0-rc.2 - 2021-12-27
- Simplify `TestServer`. [#431]
[#431]: https://github.com/actix/actix-net/pull/431
## 2.0.0-rc.1 - 2021-12-05
* Hide implementation details of `Server`. [#424]
* `Server` now runs only after awaiting it. [#425]
- Hide implementation details of `Server`. [#424]
- `Server` now runs only after awaiting it. [#425]
[#424]: https://github.com/actix/actix-net/pull/424
[#425]: https://github.com/actix/actix-net/pull/425
## 2.0.0-beta.9 - 2021-11-15
* Restore `Arbiter` support lost in `beta.8`. [#417]
- Restore `Arbiter` support lost in `beta.8`. [#417]
[#417]: https://github.com/actix/actix-net/pull/417
## 2.0.0-beta.8 - 2021-11-05 _(YANKED)_
* Fix non-unix signal handler. [#410]
- Fix non-unix signal handler. [#410]
[#410]: https://github.com/actix/actix-net/pull/410
## 2.0.0-beta.7 - 2021-11-05 _(YANKED)_
* Server can be started in regular Tokio runtime. [#408]
* Expose new `Server` type whose `Future` impl resolves when server stops. [#408]
* Rename `Server` to `ServerHandle`. [#407]
* Add `Server::handle` to obtain handle to server. [#408]
* Rename `ServerBuilder::{maxconn => max_concurrent_connections}`. [#407]
* Deprecate crate-level `new` shortcut for server builder. [#408]
* Minimum supported Rust version (MSRV) is now 1.52.
- Server can be started in regular Tokio runtime. [#408]
- Expose new `Server` type whose `Future` impl resolves when server stops. [#408]
- Rename `Server` to `ServerHandle`. [#407]
- Add `Server::handle` to obtain handle to server. [#408]
- Rename `ServerBuilder::{maxconn => max_concurrent_connections}`. [#407]
- Deprecate crate-level `new` shortcut for server builder. [#408]
- Minimum supported Rust version (MSRV) is now 1.52.
[#407]: https://github.com/actix/actix-net/pull/407
[#408]: https://github.com/actix/actix-net/pull/408
## 2.0.0-beta.6 - 2021-10-11
* Add experimental (semver-exempt) `io-uring` feature for enabling async file I/O on linux. [#374]
* Server no long listens to `SIGHUP` signal. Previously, the received was not used but did block
- Add experimental (semver-exempt) `io-uring` feature for enabling async file I/O on linux. [#374]
- Server no long listens to `SIGHUP` signal. Previously, the received was not used but did block
subsequent exit signals from working. [#389]
* Remove `config` module. `ServiceConfig`, `ServiceRuntime` public types are removed due to
- Remove `config` module. `ServiceConfig`, `ServiceRuntime` public types are removed due to
this change. [#349]
* Remove `ServerBuilder::configure` [#349]
- Remove `ServerBuilder::configure` [#349]
[#374]: https://github.com/actix/actix-net/pull/374
[#349]: https://github.com/actix/actix-net/pull/349
@@ -50,23 +84,23 @@
## 2.0.0-beta.5 - 2021-04-20
* Server shutdown notifies all workers to exit regardless if shutdown is graceful. This causes all
- Server shutdown notifies all workers to exit regardless if shutdown is graceful. This causes all
workers to shutdown immediately in force shutdown case. [#333]
[#333]: https://github.com/actix/actix-net/pull/333
## 2.0.0-beta.4 - 2021-04-01
* Prevent panic when `shutdown_timeout` is very large. [f9262db]
- Prevent panic when `shutdown_timeout` is very large. [f9262db]
[f9262db]: https://github.com/actix/actix-net/commit/f9262db
## 2.0.0-beta.3 - 2021-02-06
* Hidden `ServerBuilder::start` method has been removed. Use `ServerBuilder::run`. [#246]
* Add retry for EINTR signal (`io::Interrupted`) in `Accept`'s poll loop. [#264]
* Add `ServerBuilder::worker_max_blocking_threads` to customize blocking thread pool size. [#265]
* Update `actix-rt` to `2.0.0`. [#273]
- Hidden `ServerBuilder::start` method has been removed. Use `ServerBuilder::run`. [#246]
- Add retry for EINTR signal (`io::Interrupted`) in `Accept`'s poll loop. [#264]
- Add `ServerBuilder::worker_max_blocking_threads` to customize blocking thread pool size. [#265]
- Update `actix-rt` to `2.0.0`. [#273]
[#246]: https://github.com/actix/actix-net/pull/246
[#264]: https://github.com/actix/actix-net/pull/264
@@ -75,21 +109,21 @@
## 2.0.0-beta.2 - 2021-01-03
* Merge `actix-testing` to `actix-server` as `test_server` mod. [#242]
- Merge `actix-testing` to `actix-server` as `test_server` mod. [#242]
[#242]: https://github.com/actix/actix-net/pull/242
## 2.0.0-beta.1 - 2020-12-28
* Added explicit info log message on accept queue pause. [#215]
* Prevent double registration of sockets when back-pressure is resolved. [#223]
* Update `mio` dependency to `0.7.3`. [#239]
* Remove `socket2` dependency. [#239]
* `ServerBuilder::backlog` now accepts `u32` instead of `i32`. [#239]
* Remove `AcceptNotify` type and pass `WakerQueue` to `Worker` to wake up `Accept`'s `Poll`. [#239]
* Convert `mio::net::TcpStream` to `actix_rt::net::TcpStream`(`UnixStream` for uds) using
- Added explicit info log message on accept queue pause. [#215]
- Prevent double registration of sockets when back-pressure is resolved. [#223]
- Update `mio` dependency to `0.7.3`. [#239]
- Remove `socket2` dependency. [#239]
- `ServerBuilder::backlog` now accepts `u32` instead of `i32`. [#239]
- Remove `AcceptNotify` type and pass `WakerQueue` to `Worker` to wake up `Accept`'s `Poll`. [#239]
- Convert `mio::net::TcpStream` to `actix_rt::net::TcpStream`(`UnixStream` for uds) using
`FromRawFd` and `IntoRawFd`(`FromRawSocket` and `IntoRawSocket` on windows). [#239]
* Remove `AsyncRead` and `AsyncWrite` trait bound for `socket::FromStream` trait. [#239]
- Remove `AsyncRead` and `AsyncWrite` trait bound for `socket::FromStream` trait. [#239]
[#215]: https://github.com/actix/actix-net/pull/215
[#223]: https://github.com/actix/actix-net/pull/223
@@ -97,125 +131,125 @@
## 1.0.4 - 2020-09-12
* Update actix-codec to 0.3.0.
* Workers must be greater than 0. [#167]
- Update actix-codec to 0.3.0.
- Workers must be greater than 0. [#167]
[#167]: https://github.com/actix/actix-net/pull/167
## 1.0.3 - 2020-05-19
* Replace deprecated `net2` crate with `socket2` [#140]
- Replace deprecated `net2` crate with `socket2` [#140]
[#140]: https://github.com/actix/actix-net/pull/140
## 1.0.2 - 2020-02-26
* Avoid error by calling `reregister()` on Windows [#103]
- Avoid error by calling `reregister()` on Windows [#103]
[#103]: https://github.com/actix/actix-net/pull/103
## 1.0.1 - 2019-12-29
* Rename `.start()` method to `.run()`
- Rename `.start()` method to `.run()`
## 1.0.0 - 2019-12-11
* Use actix-net releases
- Use actix-net releases
## 1.0.0-alpha.4 - 2019-12-08
* Use actix-service 1.0.0-alpha.4
- Use actix-service 1.0.0-alpha.4
## 1.0.0-alpha.3 - 2019-12-07
* Migrate to tokio 0.2
* Fix compilation on non-unix platforms
* Better handling server configuration
- Migrate to tokio 0.2
- Fix compilation on non-unix platforms
- Better handling server configuration
## 1.0.0-alpha.2 - 2019-12-02
* Simplify server service (remove actix-server-config)
* Allow to wait on `Server` until server stops
- Simplify server service (remove actix-server-config)
- Allow to wait on `Server` until server stops
## 0.8.0-alpha.1 - 2019-11-22
* Migrate to `std::future`
- Migrate to `std::future`
## 0.7.0 - 2019-10-04
* Update `rustls` to 0.16
* Minimum required Rust version upped to 1.37.0
- Update `rustls` to 0.16
- Minimum required Rust version upped to 1.37.0
## 0.6.1 - 2019-09-25
* Add UDS listening support to `ServerBuilder`
- Add UDS listening support to `ServerBuilder`
## 0.6.0 - 2019-07-18
* Support Unix domain sockets #3
- Support Unix domain sockets #3
## 0.5.1 - 2019-05-18
* ServerBuilder::shutdown_timeout() accepts u64
- ServerBuilder::shutdown_timeout() accepts u64
## 0.5.0 - 2019-05-12
* Add `Debug` impl for `SslError`
* Derive debug for `Server` and `ServerCommand`
* Upgrade to actix-service 0.4
- Add `Debug` impl for `SslError`
- Derive debug for `Server` and `ServerCommand`
- Upgrade to actix-service 0.4
## 0.4.3 - 2019-04-16
* Re-export `IoStream` trait
* Depend on `ssl` and `rust-tls` features from actix-server-config
- Re-export `IoStream` trait
- Depend on `ssl` and `rust-tls` features from actix-server-config
## 0.4.2 - 2019-03-30
* Fix SIGINT force shutdown
- Fix SIGINT force shutdown
## 0.4.1 - 2019-03-14
* `SystemRuntime::on_start()` - allow to run future before server service initialization
- `SystemRuntime::on_start()` - allow to run future before server service initialization
## 0.4.0 - 2019-03-12
* Use `ServerConfig` for service factory
* Wrap tcp socket to `Io` type
* Upgrade actix-service
- Use `ServerConfig` for service factory
- Wrap tcp socket to `Io` type
- Upgrade actix-service
## 0.3.1 - 2019-03-04
* Add `ServerBuilder::maxconnrate` sets the maximum per-worker number of concurrent connections
* Add helper ssl error `SslError`
* Rename `StreamServiceFactory` to `ServiceFactory`
* Deprecate `StreamServiceFactory`
- Add `ServerBuilder::maxconnrate` sets the maximum per-worker number of concurrent connections
- Add helper ssl error `SslError`
- Rename `StreamServiceFactory` to `ServiceFactory`
- Deprecate `StreamServiceFactory`
## 0.3.0 - 2019-03-02
* Use new `NewService` trait
- Use new `NewService` trait
## 0.2.1 - 2019-02-09
* Drop service response
- Drop service response
## 0.2.0 - 2019-02-01
* Migrate to actix-service 0.2
* Updated rustls dependency
- Migrate to actix-service 0.2
- Updated rustls dependency
## 0.1.3 - 2018-12-21
* Fix max concurrent connections handling
- Fix max concurrent connections handling
## 0.1.2 - 2018-12-12
* rename ServiceConfig::rt() to ServiceConfig::apply()
* Fix back-pressure for concurrent ssl handshakes
- rename ServiceConfig::rt() to ServiceConfig::apply()
- Fix back-pressure for concurrent ssl handshakes
## 0.1.1 - 2018-12-11
* Fix signal handling on windows
- Fix signal handling on windows
## 0.1.0 - 2018-12-09
* Move server to separate crate
- Move server to separate crate

View File

@@ -1,14 +1,17 @@
[package]
name = "actix-server"
version = "2.0.0-rc.1"
version = "2.1.1"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"fakeshadow <24548779@qq.com>",
"Rob Ede <robjtede@icloud.com>",
"Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com>",
]
description = "General purpose TCP server built for the Actix ecosystem"
keywords = ["network", "framework", "async", "futures"]
repository = "https://github.com/actix/actix-net.git"
keywords = ["network", "tcp", "server", "framework", "async"]
categories = ["network-programming", "asynchronous"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-net.git"
license = "MIT OR Apache-2.0"
edition = "2018"
@@ -21,26 +24,27 @@ default = []
io-uring = ["tokio-uring", "actix-rt/io-uring"]
[dependencies]
actix-rt = { version = "2.4.0", default-features = false }
actix-service = "2.0.0"
actix-utils = "3.0.0"
actix-rt = { version = "2.7", default-features = false }
actix-service = "2"
actix-utils = "3"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] }
log = "0.4"
mio = { version = "0.8", features = ["os-poll", "net"] }
num_cpus = "1.13"
socket2 = "0.4.2"
tokio = { version = "1.5.1", features = ["sync"] }
tokio = { version = "1.13.1", features = ["sync"] }
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
# runtime for io-uring feature
tokio-uring = { version = "0.1", optional = true }
# runtime for `io-uring` feature
[target.'cfg(target_os = "linux")'.dependencies]
tokio-uring = { version = "0.3", optional = true }
[dev-dependencies]
actix-codec = "0.4.0"
actix-rt = "2.4.0"
actix-codec = "0.5.0"
actix-rt = "2.6.0"
bytes = "1"
env_logger = "0.9"
futures-util = { version = "0.3.7", default-features = false, features = ["sink", "async-await-macro"] }
tokio = { version = "1.5.1", features = ["io-util", "rt-multi-thread", "macros"] }
tokio = { version = "1.13.1", features = ["io-util", "rt-multi-thread", "macros", "fs"] }

15
actix-server/README.md Normal file
View File

@@ -0,0 +1,15 @@
# actix-server
> General purpose TCP server built for the Actix ecosystem.
[![crates.io](https://img.shields.io/crates/v/actix-server?label=latest)](https://crates.io/crates/actix-server)
[![Documentation](https://docs.rs/actix-server/badge.svg?version=2.1.1)](https://docs.rs/actix-server/2.1.1)
[![Version](https://img.shields.io/badge/rustc-1.52+-ab6000.svg)](https://blog.rust-lang.org/2021/05/06/Rust-1.52.0.html)
![License](https://img.shields.io/crates/l/actix-server.svg)
[![Dependency Status](https://deps.rs/crate/actix-server/2.1.1/status.svg)](https://deps.rs/crate/actix-server/2.1.1)
![Download](https://img.shields.io/crates/d/actix-server.svg)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)
## Resources
- [Library Documentation](https://docs.rs/actix-server)
- [Examples](/actix-server/examples)

View File

@@ -0,0 +1,95 @@
//! Simple file-reader TCP server with framed stream.
//!
//! Using the following command:
//!
//! ```sh
//! nc 127.0.0.1 8080
//! ```
//!
//! Follow the prompt and enter a file path, relative or absolute.
use std::io;
use actix_codec::{Framed, LinesCodec};
use actix_rt::net::TcpStream;
use actix_server::Server;
use actix_service::{fn_service, ServiceFactoryExt as _};
use futures_util::{SinkExt as _, StreamExt as _};
use tokio::{fs::File, io::AsyncReadExt as _};
async fn run() -> io::Result<()> {
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
let addr = ("127.0.0.1", 8080);
tracing::info!("starting server on port: {}", &addr.0);
// Bind socket address and start worker(s). By default, the server uses the number of physical
// CPU cores as the worker count. For this reason, the closure passed to bind needs to return
// a service *factory*; so it can be created once per worker.
Server::build()
.bind("file-reader", addr, move || {
fn_service(move |stream: TcpStream| async move {
// set up codec to use with I/O resource
let mut framed = Framed::new(stream, LinesCodec::default());
loop {
// prompt for file name
framed.send("Type file name to return:").await?;
// wait for next line
match framed.next().await {
Some(Ok(line)) => {
match File::open(&line).await {
Ok(mut file) => {
tracing::info!("reading file: {}", &line);
// read file into String buffer
let mut buf = String::new();
file.read_to_string(&mut buf).await?;
// send String into framed object
framed.send(buf).await?;
// break out of loop and
break;
}
Err(err) => {
tracing::error!("{}", err);
framed
.send("File not found or not readable. Try again.")
.await?;
continue;
}
};
}
// not being able to read a line from the stream is unrecoverable
Some(Err(err)) => return Err(err),
// This EOF won't be hit.
None => continue,
}
}
// close connection after file has been copied to TCP stream
Ok(())
})
.map_err(|err| tracing::error!("service error: {:?}", err))
})?
.workers(2)
.run()
.await
}
#[tokio::main]
async fn main() -> io::Result<()> {
run().await?;
Ok(())
}
// alternatively:
// #[actix_rt::main]
// async fn main() -> io::Result<()> {
// run().await?;
// Ok(())
// }

View File

@@ -22,20 +22,19 @@ use actix_server::Server;
use actix_service::{fn_service, ServiceFactoryExt as _};
use bytes::BytesMut;
use futures_util::future::ok;
use log::{error, info};
use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
async fn run() -> io::Result<()> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));
let count = Arc::new(AtomicUsize::new(0));
let addr = ("127.0.0.1", 8080);
info!("starting server on port: {}", &addr.0);
tracing::info!("starting server on port: {}", &addr.0);
// Bind socket address and start worker(s). By default, the server uses the number of available
// logical CPU cores as the worker count. For this reason, the closure passed to bind needs
// to return a service *factory*; so it can be created once per worker.
// Bind socket address and start worker(s). By default, the server uses the number of physical
// CPU cores as the worker count. For this reason, the closure passed to bind needs to return
// a service *factory*; so it can be created once per worker.
Server::build()
.bind("echo", addr, move || {
let count = Arc::clone(&count);
@@ -58,14 +57,14 @@ async fn run() -> io::Result<()> {
// more bytes to process
Ok(bytes_read) => {
info!("[{}] read {} bytes", num, bytes_read);
tracing::info!("[{}] read {} bytes", num, bytes_read);
stream.write_all(&buf[size..]).await.unwrap();
size += bytes_read;
}
// stream error; bail from loop with error
Err(err) => {
error!("Stream Error: {:?}", err);
tracing::error!("stream error: {:?}", err);
return Err(());
}
}
@@ -75,10 +74,10 @@ async fn run() -> io::Result<()> {
Ok((buf.freeze(), size))
}
})
.map_err(|err| error!("Service Error: {:?}", err))
.map_err(|err| tracing::error!("service error: {:?}", err))
.and_then(move |(_, size)| {
let num = num2.load(Ordering::SeqCst);
info!("[{}] total bytes read: {}", num, size);
tracing::info!("[{}] total bytes read: {}", num, size);
ok(size)
})
})?

View File

@@ -1,8 +1,8 @@
use std::{io, thread, time::Duration};
use actix_rt::time::Instant;
use log::{debug, error, info};
use mio::{Interest, Poll, Token as MioToken};
use tracing::{debug, error, info};
use crate::{
availability::Availability,
@@ -24,7 +24,7 @@ struct ServerSocketInfo {
timeout: Option<actix_rt::time::Instant>,
}
/// poll instance of the server.
/// Poll instance of the server.
pub(crate) struct Accept {
poll: Poll,
waker_queue: WakerQueue,
@@ -41,7 +41,7 @@ impl Accept {
pub(crate) fn start(
sockets: Vec<(usize, MioListener)>,
builder: &ServerBuilder,
) -> io::Result<(WakerQueue, Vec<WorkerHandleServer>)> {
) -> io::Result<(WakerQueue, Vec<WorkerHandleServer>, thread::JoinHandle<()>)> {
let handle_server = ServerHandle::new(builder.cmd_tx.clone());
// construct poll instance and its waker
@@ -73,12 +73,12 @@ impl Accept {
handle_server,
)?;
thread::Builder::new()
let accept_handle = thread::Builder::new()
.name("actix-server acceptor".to_owned())
.spawn(move || accept.poll_with(&mut sockets))
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
Ok((waker_queue, handles_server))
Ok((waker_queue, handles_server, accept_handle))
}
fn new_with_sockets(
@@ -127,10 +127,10 @@ impl Accept {
let mut events = mio::Events::with_capacity(256);
loop {
if let Err(e) = self.poll.poll(&mut events, self.timeout) {
match e.kind() {
if let Err(err) = self.poll.poll(&mut events, self.timeout) {
match err.kind() {
io::ErrorKind::Interrupted => {}
_ => panic!("Poll error: {}", e),
_ => panic!("Poll error: {}", err),
}
}
@@ -140,7 +140,7 @@ impl Accept {
WAKER_TOKEN => {
let exit = self.handle_waker(sockets);
if exit {
info!("Accept thread stopped");
info!("accept thread stopped");
return;
}
}
@@ -161,11 +161,13 @@ impl Accept {
// a loop that would try to drain the command channel. It's yet unknown
// if it's necessary/good practice to actively drain the waker queue.
loop {
// take guard with every iteration so no new interest can be added
// until the current task is done.
// Take guard with every iteration so no new interests can be added until the current
// task is done. Take care not to take the guard again inside this loop.
let mut guard = self.waker_queue.guard();
#[allow(clippy::significant_drop_in_scrutinee)]
match guard.pop_front() {
// worker notify it becomes available.
// Worker notified it became available.
Some(WakerInterest::WorkerAvailable(idx)) => {
drop(guard);
@@ -176,7 +178,7 @@ impl Accept {
}
}
// a new worker thread is made and it's handle would be added to Accept
// A new worker thread has been created so store its handle.
Some(WakerInterest::Worker(handle)) => {
drop(guard);
@@ -297,16 +299,16 @@ impl Accept {
fn register_logged(&self, info: &mut ServerSocketInfo) {
match self.register(info) {
Ok(_) => debug!("Resume accepting connections on {}", info.lst.local_addr()),
Err(e) => error!("Can not register server socket {}", e),
Ok(_) => debug!("resume accepting connections on {}", info.lst.local_addr()),
Err(err) => error!("can not register server socket {}", err),
}
}
fn deregister_logged(&self, info: &mut ServerSocketInfo) {
match self.poll.registry().deregister(&mut info.lst) {
Ok(_) => debug!("Paused accepting connections on {}", info.lst.local_addr()),
Err(e) => {
error!("Can not deregister server socket {}", e)
Ok(_) => debug!("paused accepting connections on {}", info.lst.local_addr()),
Err(err) => {
error!("can not deregister server socket {}", err)
}
}
}
@@ -350,7 +352,7 @@ impl Accept {
self.remove_next();
if self.handles.is_empty() {
error!("No workers");
error!("no workers");
// All workers are gone and Conn is nowhere to be sent.
// Treat this situation as Ok and drop Conn.
return Ok(());
@@ -396,10 +398,10 @@ impl Accept {
let conn = Conn { io, token };
self.accept_one(conn);
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return,
Err(ref e) if connection_error(e) => continue,
Err(e) => {
error!("Error accepting connection: {}", e);
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => return,
Err(ref err) if connection_error(err) => continue,
Err(err) => {
error!("error accepting connection: {}", err);
// deregister listener temporary
self.deregister_logged(info);

View File

@@ -1,12 +1,12 @@
use std::{io, time::Duration};
use actix_rt::net::TcpStream;
use log::{info, trace};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use tracing::{info, trace};
use crate::{
server::ServerCommand,
service::{InternalServiceFactory, ServiceFactory, StreamNewService},
service::{InternalServiceFactory, ServerServiceFactory, StreamNewService},
socket::{
create_mio_tcp_listener, MioListener, MioTcpListener, StdTcpListener, ToSocketAddrs,
},
@@ -40,7 +40,7 @@ impl ServerBuilder {
let (cmd_tx, cmd_rx) = unbounded_channel();
ServerBuilder {
threads: num_cpus::get(),
threads: num_cpus::get_physical(),
token: 0,
factories: Vec::new(),
sockets: Vec::new(),
@@ -55,8 +55,11 @@ impl ServerBuilder {
/// Set number of workers to start.
///
/// By default server uses number of available logical CPU as workers count. Workers must be
/// greater than 0.
/// `num` must be greater than 0.
///
/// The default worker count is the number of physical CPU cores available. If your benchmark
/// testing indicates that simultaneous multi-threading is beneficial to your app, you can use
/// the [`num_cpus`] crate to acquire the _logical_ core count instead.
pub fn workers(mut self, num: usize) -> Self {
assert_ne!(num, 0, "workers must be greater than 0");
self.threads = num;
@@ -137,10 +140,11 @@ impl ServerBuilder {
}
/// Add new service to the server.
pub fn bind<F, U, N: AsRef<str>>(mut self, name: N, addr: U, factory: F) -> io::Result<Self>
pub fn bind<F, U, N>(mut self, name: N, addr: U, factory: F) -> io::Result<Self>
where
F: ServiceFactory<TcpStream>,
F: ServerServiceFactory<TcpStream>,
U: ToSocketAddrs,
N: AsRef<str>,
{
let sockets = bind_addr(addr, self.backlog)?;
@@ -169,7 +173,7 @@ impl ServerBuilder {
factory: F,
) -> io::Result<Self>
where
F: ServiceFactory<TcpStream>,
F: ServerServiceFactory<TcpStream>,
{
lst.set_nonblocking(true)?;
let addr = lst.local_addr()?;
@@ -193,7 +197,7 @@ impl ServerBuilder {
if self.sockets.is_empty() {
panic!("Server should have at least one bound socket");
} else {
info!("Starting {} workers", self.threads);
info!("starting {} workers", self.threads);
Server::new(self)
}
}
@@ -210,16 +214,16 @@ impl ServerBuilder {
/// Add new unix domain service to the server.
pub fn bind_uds<F, U, N>(self, name: N, addr: U, factory: F) -> io::Result<Self>
where
F: ServiceFactory<actix_rt::net::UnixStream>,
F: ServerServiceFactory<actix_rt::net::UnixStream>,
N: AsRef<str>,
U: AsRef<std::path::Path>,
{
// The path must not exist when we try to bind.
// Try to remove it to avoid bind error.
if let Err(e) = std::fs::remove_file(addr.as_ref()) {
if let Err(err) = std::fs::remove_file(addr.as_ref()) {
// NotFound is expected and not an issue. Anything else is.
if e.kind() != std::io::ErrorKind::NotFound {
return Err(e);
if err.kind() != std::io::ErrorKind::NotFound {
return Err(err);
}
}
@@ -237,7 +241,7 @@ impl ServerBuilder {
factory: F,
) -> io::Result<Self>
where
F: ServiceFactory<actix_rt::net::UnixStream>,
F: ServerServiceFactory<actix_rt::net::UnixStream>,
{
use std::net::{IpAddr, Ipv4Addr};
lst.set_nonblocking(true)?;
@@ -260,22 +264,23 @@ pub(super) fn bind_addr<S: ToSocketAddrs>(
addr: S,
backlog: u32,
) -> io::Result<Vec<MioTcpListener>> {
let mut err = None;
let mut opt_err = None;
let mut success = false;
let mut sockets = Vec::new();
for addr in addr.to_socket_addrs()? {
match create_mio_tcp_listener(addr, backlog) {
Ok(lst) => {
success = true;
sockets.push(lst);
}
Err(e) => err = Some(e),
Err(err) => opt_err = Some(err),
}
}
if success {
Ok(sockets)
} else if let Some(err) = err.take() {
} else if let Some(err) = opt_err.take() {
Err(err)
} else {
Err(io::Error::new(

View File

@@ -63,10 +63,10 @@ impl<T> Future for JoinAll<T> {
#[cfg(test)]
mod test {
use super::*;
use actix_utils::future::ready;
use super::*;
#[actix_rt::test]
async fn test_join_all() {
let futs = vec![ready(Ok(1)), ready(Err(3)), ready(Ok(9))];

View File

@@ -1,6 +1,7 @@
//! General purpose TCP server.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
@@ -20,11 +21,10 @@ mod worker;
pub use self::builder::ServerBuilder;
pub use self::handle::ServerHandle;
pub use self::server::Server;
pub use self::service::ServiceFactory;
pub use self::test_server::TestServer;
pub use self::service::ServerServiceFactory;
#[doc(hidden)]
pub use self::socket::FromStream;
pub use self::test_server::TestServer;
/// Start server building process
#[doc(hidden)]

View File

@@ -3,14 +3,15 @@ use std::{
io, mem,
pin::Pin,
task::{Context, Poll},
thread,
time::Duration,
};
use actix_rt::{time::sleep, System};
use futures_core::{future::BoxFuture, Stream};
use futures_util::stream::StreamExt as _;
use log::{error, info};
use tokio::sync::{mpsc::UnboundedReceiver, oneshot};
use tracing::{error, info};
use crate::{
accept::Accept,
@@ -65,7 +66,7 @@ pub(crate) enum ServerCommand {
/// server has fully shut down.
///
/// # Shutdown Signals
/// On UNIX systems, `SIGQUIT` will start a graceful shutdown and `SIGTERM` or `SIGINT` will start a
/// On UNIX systems, `SIGTERM` will start a graceful shutdown and `SIGQUIT` or `SIGINT` will start a
/// forced shutdown. On Windows, a Ctrl-C signal will start a forced shutdown.
///
/// A graceful shutdown will wait for all workers to stop first.
@@ -158,6 +159,7 @@ impl Future for Server {
pub struct ServerInner {
worker_handles: Vec<WorkerHandleServer>,
accept_handle: Option<thread::JoinHandle<()>>,
worker_config: ServerWorkerConfig,
services: Vec<Box<dyn InternalServiceFactory>>,
waker_queue: WakerQueue,
@@ -198,14 +200,14 @@ impl ServerInner {
for (_, name, lst) in &builder.sockets {
info!(
r#"Starting service: "{}", workers: {}, listening on: {}"#,
r#"starting service: "{}", workers: {}, listening on: {}"#,
name,
builder.threads,
lst.local_addr()
);
}
let (waker_queue, worker_handles) = Accept::start(sockets, &builder)?;
let (waker_queue, worker_handles, accept_handle) = Accept::start(sockets, &builder)?;
let mux = ServerEventMultiplexer {
signal_fut: (builder.listen_os_signals).then(Signals::new),
@@ -214,6 +216,7 @@ impl ServerInner {
let server = ServerInner {
waker_queue,
accept_handle: Some(accept_handle),
worker_handles,
worker_config: builder.worker_config,
services: builder.factories,
@@ -243,7 +246,8 @@ impl ServerInner {
} => {
self.stopping = true;
// stop accept thread
// Signal accept thread to stop.
// Signal is non-blocking; we wait for thread to stop later.
self.waker_queue.wake(WakerInterest::Stop);
// send stop signal to workers
@@ -258,6 +262,13 @@ impl ServerInner {
let _ = join_all(workers_stop).await;
}
// wait for accept thread stop
self.accept_handle
.take()
.unwrap()
.join()
.expect("Accept thread must not panic in any case");
if let Some(tx) = completion {
let _ = tx.send(());
}
@@ -272,7 +283,7 @@ impl ServerInner {
// TODO: maybe just return with warning log if not found ?
assert!(self.worker_handles.iter().any(|wrk| wrk.idx == idx));
error!("Worker {} has died; restarting", idx);
error!("worker {} has died; restarting", idx);
let factories = self
.services

View File

@@ -1,16 +1,21 @@
use std::marker::PhantomData;
use std::net::SocketAddr;
use std::task::{Context, Poll};
use std::{
marker::PhantomData,
net::SocketAddr,
task::{Context, Poll},
};
use actix_service::{Service, ServiceFactory as BaseServiceFactory};
use actix_utils::future::{ready, Ready};
use futures_core::future::LocalBoxFuture;
use log::error;
use tracing::error;
use crate::socket::{FromStream, MioStream};
use crate::worker::WorkerCounterGuard;
use crate::{
socket::{FromStream, MioStream},
worker::WorkerCounterGuard,
};
pub trait ServiceFactory<Stream: FromStream>: Send + Clone + 'static {
#[doc(hidden)]
pub trait ServerServiceFactory<Stream: FromStream>: Send + Clone + 'static {
type Factory: BaseServiceFactory<Stream, Config = ()>;
fn create(&self) -> Self::Factory;
@@ -72,15 +77,15 @@ where
});
Ok(())
}
Err(e) => {
error!("Can not convert to an async tcp stream: {}", e);
Err(err) => {
error!("can not convert to an async TCP stream: {}", err);
Err(())
}
})
}
}
pub(crate) struct StreamNewService<F: ServiceFactory<Io>, Io: FromStream> {
pub(crate) struct StreamNewService<F: ServerServiceFactory<Io>, Io: FromStream> {
name: String,
inner: F,
token: usize,
@@ -90,7 +95,7 @@ pub(crate) struct StreamNewService<F: ServiceFactory<Io>, Io: FromStream> {
impl<F, Io> StreamNewService<F, Io>
where
F: ServiceFactory<Io>,
F: ServerServiceFactory<Io>,
Io: FromStream + Send + 'static,
{
pub(crate) fn create(
@@ -111,7 +116,7 @@ where
impl<F, Io> InternalServiceFactory for StreamNewService<F, Io>
where
F: ServiceFactory<Io>,
F: ServerServiceFactory<Io>,
Io: FromStream + Send + 'static,
{
fn name(&self, _: usize) -> &str {
@@ -143,7 +148,7 @@ where
}
}
impl<F, T, I> ServiceFactory<I> for F
impl<F, T, I> ServerServiceFactory<I> for F
where
F: Fn() -> T + Send + Clone + 'static,
T: BaseServiceFactory<I, Config = ()>,

View File

@@ -5,7 +5,7 @@ use std::{
task::{Context, Poll},
};
use log::trace;
use tracing::trace;
/// Types of process signals.
// #[allow(dead_code)]
@@ -69,8 +69,8 @@ impl Signals {
unix::signal(*kind)
.map(|tokio_sig| (*sig, tokio_sig))
.map_err(|e| {
log::error!(
"Can not initialize stream handler for {:?} err: {}",
tracing::error!(
"can not initialize stream handler for {:?} err: {}",
sig,
e
)

View File

@@ -1,19 +1,17 @@
pub(crate) use std::net::{
SocketAddr as StdSocketAddr, TcpListener as StdTcpListener, ToSocketAddrs,
};
use std::{fmt, io};
use actix_rt::net::TcpStream;
pub(crate) use mio::net::TcpListener as MioTcpListener;
use mio::{event::Source, Interest, Registry, Token};
#[cfg(unix)]
pub(crate) use {
mio::net::UnixListener as MioUnixListener,
std::os::unix::net::UnixListener as StdUnixListener,
};
use std::{fmt, io};
use actix_rt::net::TcpStream;
use mio::{event::Source, Interest, Registry, Token};
pub(crate) enum MioListener {
Tcp(MioTcpListener),
#[cfg(unix)]

View File

@@ -2,7 +2,7 @@ use std::{io, net, sync::mpsc, thread};
use actix_rt::{net::TcpStream, System};
use crate::{Server, ServerBuilder, ServerHandle, ServiceFactory};
use crate::{Server, ServerBuilder, ServerHandle, ServerServiceFactory};
/// A testing server.
///
@@ -16,7 +16,7 @@ use crate::{Server, ServerBuilder, ServerHandle, ServiceFactory};
///
/// #[actix_rt::main]
/// async fn main() {
/// let srv = TestServer::with(|| fn_service(
/// let srv = TestServer::start(|| fn_service(
/// |sock| async move {
/// println!("New connection: {:?}", sock);
/// Ok::<_, ()>(())
@@ -28,8 +28,8 @@ use crate::{Server, ServerBuilder, ServerHandle, ServiceFactory};
/// ```
pub struct TestServer;
/// Test server runtime
pub struct TestServerRuntime {
/// Test server handle.
pub struct TestServerHandle {
addr: net::SocketAddr,
host: String,
port: u16,
@@ -38,46 +38,26 @@ pub struct TestServerRuntime {
}
impl TestServer {
/// Start new server with server builder.
pub fn start<F>(mut factory: F) -> TestServerRuntime
where
F: FnMut(ServerBuilder) -> ServerBuilder + Send + 'static,
{
let (tx, rx) = mpsc::channel();
// run server in separate thread
let thread_handle = thread::spawn(move || {
System::new().block_on(async {
let server = factory(Server::build()).workers(1).disable_signals().run();
tx.send(server.handle()).unwrap();
server.await
})
});
let server_handle = rx.recv().unwrap();
TestServerRuntime {
addr: "127.0.0.1:0".parse().unwrap(),
host: "127.0.0.1".to_string(),
port: 0,
server_handle,
thread_handle: Some(thread_handle),
}
/// Start new `TestServer` using application factory and default server config.
pub fn start(factory: impl ServerServiceFactory<TcpStream>) -> TestServerHandle {
Self::start_with_builder(Server::build(), factory)
}
/// Start new test server with application factory.
pub fn with<F: ServiceFactory<TcpStream>>(factory: F) -> TestServerRuntime {
/// Start new `TestServer` using application factory and server builder.
pub fn start_with_builder(
server_builder: ServerBuilder,
factory: impl ServerServiceFactory<TcpStream>,
) -> TestServerHandle {
let (tx, rx) = mpsc::channel();
// run server in separate thread
let thread_handle = thread::spawn(move || {
let sys = System::new();
let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
let local_addr = tcp.local_addr().unwrap();
let lst = net::TcpListener::bind("127.0.0.1:0").unwrap();
let local_addr = lst.local_addr().unwrap();
sys.block_on(async {
let server = Server::build()
.listen("test", tcp, factory)
System::new().block_on(async {
let server = server_builder
.listen("test", lst, factory)
.unwrap()
.workers(1)
.disable_signals()
@@ -93,7 +73,7 @@ impl TestServer {
let host = format!("{}", addr.ip());
let port = addr.port();
TestServerRuntime {
TestServerHandle {
addr,
host,
port,
@@ -107,17 +87,19 @@ impl TestServer {
use socket2::{Domain, Protocol, Socket, Type};
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
let socket =
Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP)).unwrap();
let domain = Domain::for_address(addr);
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP)).unwrap();
socket.set_reuse_address(true).unwrap();
socket.set_nonblocking(true).unwrap();
socket.bind(&addr.into()).unwrap();
socket.listen(1024).unwrap();
net::TcpListener::from(socket).local_addr().unwrap()
}
}
impl TestServerRuntime {
impl TestServerHandle {
/// Test server host.
pub fn host(&self) -> &str {
&self.host
@@ -140,12 +122,12 @@ impl TestServerRuntime {
}
/// Connect to server, returning a Tokio `TcpStream`.
pub fn connect(&self) -> std::io::Result<TcpStream> {
pub fn connect(&self) -> io::Result<TcpStream> {
TcpStream::from_std(net::TcpStream::connect(self.addr)?)
}
}
impl Drop for TestServerRuntime {
impl Drop for TestServerHandle {
fn drop(&mut self) {
self.stop()
}
@@ -158,8 +140,14 @@ mod tests {
use super::*;
#[tokio::test]
async fn plain_tokio_runtime() {
let srv = TestServer::with(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
async fn connect_in_tokio_runtime() {
let srv = TestServer::start(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
assert!(srv.connect().is_ok());
}
#[actix_rt::test]
async fn connect_in_actix_runtime() {
let srv = TestServer::start(|| fn_service(|_sock| async move { Ok::<_, ()>(()) }));
assert!(srv.connect().is_ok());
}
}

View File

@@ -17,11 +17,11 @@ use actix_rt::{
Arbiter, ArbiterHandle, System,
};
use futures_core::{future::LocalBoxFuture, ready};
use log::{error, info, trace};
use tokio::sync::{
mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
oneshot,
};
use tracing::{error, info, trace};
use crate::{
service::{BoxedServerService, InternalServiceFactory},
@@ -250,7 +250,7 @@ pub(crate) struct ServerWorkerConfig {
impl Default for ServerWorkerConfig {
fn default() -> Self {
// 512 is the default max blocking thread count of tokio runtime.
let max_blocking_threads = std::cmp::max(512 / num_cpus::get(), 1);
let max_blocking_threads = std::cmp::max(512 / num_cpus::get_physical(), 1);
Self {
shutdown_timeout: Duration::from_secs(30),
max_blocking_threads,
@@ -337,7 +337,7 @@ impl ServerWorker {
Ok((token, svc)) => services.push((idx, token, svc)),
Err(err) => {
error!("Can not start worker: {:?}", err);
error!("can not start worker: {:?}", err);
return Err(io::Error::new(
io::ErrorKind::Other,
format!("can not start server service {}", idx),
@@ -436,7 +436,7 @@ impl ServerWorker {
Ok((token, svc)) => services.push((idx, token, svc)),
Err(err) => {
error!("Can not start worker: {:?}", err);
error!("can not start worker: {:?}", err);
Arbiter::current().stop();
factory_tx
.send(Err(io::Error::new(
@@ -476,7 +476,7 @@ impl ServerWorker {
fn restart_service(&mut self, idx: usize, factory_id: usize) {
let factory = &self.factories[factory_id];
trace!("Service {:?} failed, restarting", factory.name(idx));
trace!("service {:?} failed, restarting", factory.name(idx));
self.services[idx].status = WorkerServiceStatus::Restarting;
self.state = WorkerState::Restarting(Restart {
factory_id,
@@ -508,7 +508,7 @@ impl ServerWorker {
Poll::Ready(Ok(_)) => {
if srv.status == WorkerServiceStatus::Unavailable {
trace!(
"Service {:?} is available",
"service {:?} is available",
self.factories[srv.factory_idx].name(idx)
);
srv.status = WorkerServiceStatus::Available;
@@ -519,7 +519,7 @@ impl ServerWorker {
if srv.status == WorkerServiceStatus::Available {
trace!(
"Service {:?} is unavailable",
"service {:?} is unavailable",
self.factories[srv.factory_idx].name(idx)
);
srv.status = WorkerServiceStatus::Unavailable;
@@ -527,7 +527,7 @@ impl ServerWorker {
}
Poll::Ready(Err(_)) => {
error!(
"Service {:?} readiness check returned error, restarting",
"service {:?} readiness check returned error, restarting",
self.factories[srv.factory_idx].name(idx)
);
srv.status = WorkerServiceStatus::Failed;
@@ -590,11 +590,11 @@ impl Future for ServerWorker {
{
let num = this.counter.total();
if num == 0 {
info!("Shutting down idle worker");
info!("shutting down idle worker");
let _ = tx.send(true);
return Poll::Ready(());
} else if graceful {
info!("Graceful worker shutdown; finishing {} connections", num);
info!("graceful worker shutdown; finishing {} connections", num);
this.shutdown(false);
this.state = WorkerState::Shutdown(Shutdown {
@@ -603,7 +603,7 @@ impl Future for ServerWorker {
tx,
});
} else {
info!("Force shutdown worker, closing {} connections", num);
info!("force shutdown worker, closing {} connections", num);
this.shutdown(true);
let _ = tx.send(false);
@@ -638,7 +638,7 @@ impl Future for ServerWorker {
assert_eq!(token, token_new);
trace!(
"Service {:?} has been restarted",
"service {:?} has been restarted",
this.factories[factory_id].name(token)
);
@@ -685,7 +685,7 @@ impl Future for ServerWorker {
match this.check_readiness(cx) {
Ok(true) => {}
Ok(false) => {
trace!("Worker is unavailable");
trace!("worker is unavailable");
this.state = WorkerState::Unavailable;
return self.poll(cx);
}

View File

@@ -26,20 +26,54 @@ fn test_bind() {
let srv = Server::build()
.workers(1)
.disable_signals()
.shutdown_timeout(3600)
.bind("test", addr, move || {
fn_service(|_| async { Ok::<_, ()>(()) })
})?
.run();
let _ = tx.send(srv.handle());
tx.send(srv.handle()).unwrap();
srv.await
})
});
let srv = rx.recv().unwrap();
thread::sleep(Duration::from_millis(500));
assert!(net::TcpStream::connect(addr).is_ok());
net::TcpStream::connect(addr).unwrap();
let _ = srv.stop(true);
h.join().unwrap().unwrap();
}
#[test]
fn test_listen() {
let addr = unused_addr();
let (tx, rx) = mpsc::channel();
let lst = net::TcpListener::bind(addr).unwrap();
let h = thread::spawn(move || {
actix_rt::System::new().block_on(async {
let srv = Server::build()
.workers(1)
.disable_signals()
.shutdown_timeout(3600)
.listen("test", lst, move || {
fn_service(|_| async { Ok::<_, ()>(()) })
})?
.run();
tx.send(srv.handle()).unwrap();
srv.await
})
});
let srv = rx.recv().unwrap();
thread::sleep(Duration::from_millis(500));
net::TcpStream::connect(addr).unwrap();
let _ = srv.stop(true);
h.join().unwrap().unwrap();
@@ -80,38 +114,6 @@ fn plain_tokio_runtime() {
h.join().unwrap().unwrap();
}
#[test]
fn test_listen() {
let addr = unused_addr();
let lst = net::TcpListener::bind(addr).unwrap();
let (tx, rx) = mpsc::channel();
let h = thread::spawn(move || {
actix_rt::System::new().block_on(async {
let srv = Server::build()
.disable_signals()
.workers(1)
.listen("test", lst, move || {
fn_service(|_| async { Ok::<_, ()>(()) })
})?
.run();
let _ = tx.send(srv.handle());
srv.await
})
});
let srv = rx.recv().unwrap();
thread::sleep(Duration::from_millis(500));
assert!(net::TcpStream::connect(addr).is_ok());
let _ = srv.stop(true);
h.join().unwrap().unwrap();
}
#[test]
#[cfg(unix)]
fn test_start() {
@@ -184,9 +186,9 @@ fn test_start() {
#[actix_rt::test]
async fn test_max_concurrent_connections() {
// Note:
// A tcp listener would accept connects based on it's backlog setting.
// A TCP listener would accept connects based on it's backlog setting.
//
// The limit test on the other hand is only for concurrent tcp stream limiting a work
// The limit test on the other hand is only for concurrent TCP stream limiting a work
// thread accept.
use tokio::io::AsyncWriteExt;
@@ -252,6 +254,7 @@ async fn test_max_concurrent_connections() {
h.join().unwrap().unwrap();
}
// TODO: race-y failures detected due to integer underflow when calling Counter::total
#[actix_rt::test]
async fn test_service_restart() {
use std::task::{Context, Poll};

View File

@@ -0,0 +1,73 @@
use std::net;
use actix_rt::net::TcpStream;
use actix_server::{Server, TestServer};
use actix_service::fn_service;
use bytes::BytesMut;
use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
macro_rules! await_timeout_ms {
($fut:expr, $limit:expr) => {
::actix_rt::time::timeout(::std::time::Duration::from_millis($limit), $fut)
.await
.unwrap()
.unwrap();
};
}
#[tokio::test]
async fn testing_server_echo() {
let srv = TestServer::start(|| {
fn_service(move |mut stream: TcpStream| async move {
let mut size = 0;
let mut buf = BytesMut::new();
match stream.read_buf(&mut buf).await {
Ok(0) => return Err(()),
Ok(bytes_read) => {
stream.write_all(&buf[size..]).await.unwrap();
size += bytes_read;
}
Err(_) => return Err(()),
}
Ok((buf.freeze(), size))
})
});
let mut conn = srv.connect().unwrap();
await_timeout_ms!(conn.write_all(b"test"), 200);
let mut buf = Vec::new();
await_timeout_ms!(conn.read_to_end(&mut buf), 200);
assert_eq!(&buf, b"test".as_ref());
}
#[tokio::test]
async fn new_with_builder() {
let alt_addr = TestServer::unused_addr();
let srv = TestServer::start_with_builder(
Server::build()
.bind("alt", alt_addr, || {
fn_service(|_| async { Ok::<_, ()>(()) })
})
.unwrap(),
|| {
fn_service(|mut sock: TcpStream| async move {
let mut buf = [0u8; 16];
sock.read_exact(&mut buf).await
})
},
);
// connect to test server
srv.connect().unwrap();
// connect to alt service defined in custom ServerBuilder
TcpStream::from_std(net::TcpStream::connect(alt_addr).unwrap()).unwrap();
}

View File

@@ -1,57 +1,63 @@
# Changes
## Unreleased - 2021-xx-xx
* Service types can now be `Send` and `'static` regardless of request, response, and config types, etc.. [#397]
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 2.0.2 - 2021-12-18
- Service types can now be `Send` and `'static` regardless of request, response, and config types, etc. [#397]
[#397]: https://github.com/actix/actix-net/pull/397
## 2.0.1 - 2021-10-11
* Documentation fix.
- Documentation fix. [#388]
[#388]: https://github.com/actix/actix-net/pull/388
## 2.0.0 - 2021-04-16
* Removed pipeline and related structs/functions. [#335]
- Removed pipeline and related structs/functions. [#335]
[#335]: https://github.com/actix/actix-net/pull/335
## 2.0.0-beta.5 - 2021-03-15
* Add default `Service` trait impl for `Rc<S: Service>` and `&S: Service`. [#288]
* Add `boxed::rc_service` function for constructing `boxed::RcService` type [#290]
- Add default `Service` trait impl for `Rc<S: Service>` and `&S: Service`. [#288]
- Add `boxed::rc_service` function for constructing `boxed::RcService` type [#290]
[#288]: https://github.com/actix/actix-net/pull/288
[#290]: https://github.com/actix/actix-net/pull/290
## 2.0.0-beta.4 - 2021-02-04
* `Service::poll_ready` and `Service::call` receive `&self`. [#247]
* `apply_fn` and `apply_fn_factory` now receive `Fn(Req, &Service)` function type. [#247]
* `apply_cfg` and `apply_cfg_factory` now receive `Fn(Req, &Service)` function type. [#247]
* `fn_service` and friends now receive `Fn(Req)` function type. [#247]
- `Service::poll_ready` and `Service::call` receive `&self`. [#247]
- `apply_fn` and `apply_fn_factory` now receive `Fn(Req, &Service)` function type. [#247]
- `apply_cfg` and `apply_cfg_factory` now receive `Fn(Req, &Service)` function type. [#247]
- `fn_service` and friends now receive `Fn(Req)` function type. [#247]
[#247]: https://github.com/actix/actix-net/pull/247
## 2.0.0-beta.3 - 2021-01-09
* The `forward_ready!` macro converts errors. [#246]
- The `forward_ready!` macro converts errors. [#246]
[#246]: https://github.com/actix/actix-net/pull/246
## 2.0.0-beta.2 - 2021-01-03
* Remove redundant type parameter from `map_config`.
- Remove redundant type parameter from `map_config`.
## 2.0.0-beta.1 - 2020-12-28
* `Service`, other traits, and many type signatures now take the the request type as a type
- `Service`, other traits, and many type signatures now take the the request type as a type
parameter instead of an associated type. [#232]
* Add `always_ready!` and `forward_ready!` macros. [#233]
* Crate is now `no_std`. [#233]
* Migrate pin projections to `pin-project-lite`. [#233]
* Remove `AndThenApplyFn` and Pipeline `and_then_apply_fn`. Use the
- Add `always_ready!` and `forward_ready!` macros. [#233]
- Crate is now `no_std`. [#233]
- Migrate pin projections to `pin-project-lite`. [#233]
- Remove `AndThenApplyFn` and Pipeline `and_then_apply_fn`. Use the
`.and_then(apply_fn(...))` construction. [#233]
* Move non-vital methods to `ServiceExt` and `ServiceFactoryExt` extension traits. [#235]
- Move non-vital methods to `ServiceExt` and `ServiceFactoryExt` extension traits. [#235]
[#232]: https://github.com/actix/actix-net/pull/232
[#233]: https://github.com/actix/actix-net/pull/233
@@ -59,123 +65,123 @@
## 1.0.6 - 2020-08-09
* Removed unsound custom Cell implementation that allowed obtaining several mutable references to
- Removed unsound custom Cell implementation that allowed obtaining several mutable references to
the same data, which is undefined behavior in Rust and could lead to violations of memory safety. External code could obtain several mutable references to the same data through
service combinators. Attempts to acquire several mutable references to the same data will instead
result in a panic.
## 1.0.5 - 2020-01-16
* Fixed unsoundness in .and_then()/.then() service combinators.
- Fixed unsoundness in .and_then()/.then() service combinators.
## 1.0.4 - 2020-01-15
* Revert 1.0.3 change
- Revert 1.0.3 change
## 1.0.3 - 2020-01-15
* Fixed unsoundness in `AndThenService` impl.
- Fixed unsoundness in `AndThenService` impl.
## 1.0.2 - 2020-01-08
* Add `into_service` helper function.
- Add `into_service` helper function.
## 1.0.1 - 2019-12-22
* `map_config()` and `unit_config()` now accept `IntoServiceFactory` type.
- `map_config()` and `unit_config()` now accept `IntoServiceFactory` type.
## 1.0.0 - 2019-12-11
* Add Clone impl for Apply service
- Add Clone impl for Apply service
## 1.0.0-alpha.4 - 2019-12-08
* Renamed `service_fn` to `fn_service`
* Renamed `factory_fn` to `fn_factory`
* Renamed `factory_fn_cfg` to `fn_factory_with_config`
- Renamed `service_fn` to `fn_service`
- Renamed `factory_fn` to `fn_factory`
- Renamed `factory_fn_cfg` to `fn_factory_with_config`
## 1.0.0-alpha.3 - 2019-12-06
* Add missing Clone impls
* Restore `Transform::map_init_err()` combinator
* Restore `Service/Factory::apply_fn()` in form of `Pipeline/Factory::and_then_apply_fn()`
* Optimize service combinators and futures memory layout
- Add missing Clone impls
- Restore `Transform::map_init_err()` combinator
- Restore `Service/Factory::apply_fn()` in form of `Pipeline/Factory::and_then_apply_fn()`
- Optimize service combinators and futures memory layout
## 1.0.0-alpha.2 - 2019-12-02
* Use owned config value for service factory
* Renamed BoxedNewService/BoxedService to BoxServiceFactory/BoxService
- Use owned config value for service factory
- Renamed BoxedNewService/BoxedService to BoxServiceFactory/BoxService
## 1.0.0-alpha.1 - 2019-11-25
* Migrated to `std::future`
* `NewService` renamed to `ServiceFactory`
* Added `pipeline` and `pipeline_factory` function
- Migrated to `std::future`
- `NewService` renamed to `ServiceFactory`
- Added `pipeline` and `pipeline_factory` function
## 0.4.2 - 2019-08-27
* Check service readiness for `new_apply_cfg` combinator
- Check service readiness for `new_apply_cfg` combinator
## 0.4.1 - 2019-06-06
* Add `new_apply_cfg` function
- Add `new_apply_cfg` function
## 0.4.0 - 2019-05-12
* Add `NewService::map_config` and `NewService::unit_config` combinators.
* Use associated type for `NewService` config.
* Change `apply_cfg` function.
* Renamed helper functions.
- Add `NewService::map_config` and `NewService::unit_config` combinators.
- Use associated type for `NewService` config.
- Change `apply_cfg` function.
- Renamed helper functions.
## 0.3.6 - 2019-04-07
* Poll boxed service call result immediately
- Poll boxed service call result immediately
## 0.3.5 - 2019-03-29
* Add `impl<S: Service> Service for Rc<RefCell<S>>`.
- Add `impl<S: Service> Service for Rc<RefCell<S>>`.
## 0.3.4 - 2019-03-12
* Add `Transform::from_err()` combinator
* Add `apply_fn` helper
* Add `apply_fn_factory` helper
* Add `apply_transform` helper
* Add `apply_cfg` helper
- Add `Transform::from_err()` combinator
- Add `apply_fn` helper
- Add `apply_fn_factory` helper
- Add `apply_transform` helper
- Add `apply_cfg` helper
## 0.3.3 - 2019-03-09
* Add `ApplyTransform` new service for transform and new service.
* Add `NewService::apply_cfg()` combinator, allows to use nested `NewService` with different config parameter.
* Revert IntoFuture change
- Add `ApplyTransform` new service for transform and new service.
- Add `NewService::apply_cfg()` combinator, allows to use nested `NewService` with different config parameter.
- Revert IntoFuture change
## 0.3.2 - 2019-03-04
* Change `NewService::Future` and `Transform::Future` to the `IntoFuture` trait.
* Export `AndThenTransform` type
- Change `NewService::Future` and `Transform::Future` to the `IntoFuture` trait.
- Export `AndThenTransform` type
## 0.3.1 - 2019-03-04
* Simplify Transform trait
- Simplify Transform trait
## 0.3.0 - 2019-03-02
* Added boxed NewService and Service.
* Added `Config` parameter to `NewService` trait.
* Added `Config` parameter to `NewTransform` trait.
- Added boxed NewService and Service.
- Added `Config` parameter to `NewService` trait.
- Added `Config` parameter to `NewTransform` trait.
## 0.2.2 - 2019-02-19
* Added `NewService` impl for `Rc<S> where S: NewService`
* Added `NewService` impl for `Arc<S> where S: NewService`
- Added `NewService` impl for `Rc<S> where S: NewService`
- Added `NewService` impl for `Arc<S> where S: NewService`
## 0.2.1 - 2019-02-03
* Generalize `.apply` combinator with Transform trait
- Generalize `.apply` combinator with Transform trait
## 0.2.0 - 2019-02-01
* Use associated type instead of generic for Service definition.
- Use associated type instead of generic for Service definition.
* Before:
```rust
impl Service<Request> for Client {
@@ -194,29 +200,29 @@
## 0.1.6 - 2019-01-24
* Use `FnMut` instead of `Fn` for .apply() and .map() combinators and `FnService` type
* Change `.apply()` error semantic, new service's error is `From<Self::Error>`
- Use `FnMut` instead of `Fn` for .apply() and .map() combinators and `FnService` type
- Change `.apply()` error semantic, new service's error is `From<Self::Error>`
## 0.1.5 - 2019-01-13
* Make `Out::Error` convertible from `T::Error` for apply combinator
- Make `Out::Error` convertible from `T::Error` for apply combinator
## 0.1.4 - 2019-01-11
* Use `FnMut` instead of `Fn` for `FnService`
- Use `FnMut` instead of `Fn` for `FnService`
## 0.1.3 - 2018-12-12
* Split service combinators to separate trait
- Split service combinators to separate trait
## 0.1.2 - 2018-12-12
* Release future early for `.and_then()` and `.then()` combinators
- Release future early for `.and_then()` and `.then()` combinators
## 0.1.1 - 2018-12-09
* Added Service impl for `Box<S: Service>`
- Added Service impl for `Box<S: Service>`
## 0.1.0 - 2018-12-09
* Initial import
- Initial import

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-service"
version = "2.0.1"
version = "2.0.2"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@@ -23,6 +23,6 @@ paste = "1"
pin-project-lite = "0.2"
[dev-dependencies]
actix-rt = "2.0.0"
actix-utils = "3.0.0"
actix-rt = "2"
actix-utils = "3"
futures-util = { version = "0.3.7", default-features = false }

View File

@@ -3,10 +3,10 @@
> Service trait and combinators for representing asynchronous request/response operations.
[![crates.io](https://img.shields.io/crates/v/actix-service?label=latest)](https://crates.io/crates/actix-service)
[![Documentation](https://docs.rs/actix-service/badge.svg?version=2.0.1)](https://docs.rs/actix-service/2.0.1)
[![Documentation](https://docs.rs/actix-service/badge.svg?version=2.0.2)](https://docs.rs/actix-service/2.0.2)
[![Version](https://img.shields.io/badge/rustc-1.46+-ab6000.svg)](https://blog.rust-lang.org/2020/03/12/Rust-1.46.html)
![License](https://img.shields.io/crates/l/actix-service.svg)
[![Dependency Status](https://deps.rs/crate/actix-service/2.0.1/status.svg)](https://deps.rs/crate/actix-service/2.0.1)
[![Dependency Status](https://deps.rs/crate/actix-service/2.0.2/status.svg)](https://deps.rs/crate/actix-service/2.0.2)
![Download](https://img.shields.io/crates/d/actix-service.svg)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)

View File

@@ -394,9 +394,10 @@ mod tests {
#[actix_rt::test]
async fn test_auto_impl_send() {
use crate::{map_config, ServiceExt, ServiceFactoryExt};
use alloc::rc::Rc;
use crate::{map_config, ServiceExt, ServiceFactoryExt};
let srv_1 = fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8)));
let fac_1 = fn_factory_with_config(|_: Rc<u8>| {

View File

@@ -1,8 +1,8 @@
//! See [`Service`] docs for information on this crate's foundational trait.
#![no_std]
#![deny(rust_2018_idioms, nonstandard_style, future_incompatible)]
#![warn(missing_docs)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible, missing_docs)]
#![allow(clippy::type_complexity)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
@@ -38,10 +38,9 @@ pub use self::apply_cfg::{apply_cfg, apply_cfg_factory};
pub use self::ext::{ServiceExt, ServiceFactoryExt, TransformExt};
pub use self::fn_service::{fn_factory, fn_factory_with_config, fn_service};
pub use self::map_config::{map_config, unit_config};
pub use self::transform::{apply, ApplyTransform, Transform};
#[allow(unused_imports)]
use self::ready::{err, ok, ready, Ready};
pub use self::transform::{apply, ApplyTransform, Transform};
/// An asynchronous operation from `Request` to a `Response`.
///

View File

@@ -25,6 +25,8 @@
/// }
/// }
/// ```
///
/// [`forward_ready!`]: crate::forward_ready
#[macro_export]
macro_rules! always_ready {
() => {

View File

@@ -97,7 +97,7 @@ where
match this.fut.poll(cx) {
Poll::Ready(Ok(resp)) => Poll::Ready(Ok((this.f)(resp))),
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
Poll::Pending => Poll::Pending,
}
}

View File

@@ -1,82 +1,113 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 3.0.4 - 2022-03-15
- Logs emitted now use the `tracing` crate with `log` compatibility. [#451]
[#451]: https://github.com/actix/actix-net/pull/451
## 3.0.3 - 2022-02-15
- No significant changes since `3.0.2`.
## 3.0.2 - 2022-01-28
- Expose `connect::Connection::new`. [#439]
[#439]: https://github.com/actix/actix-net/pull/439
## 3.0.1 - 2022-01-11
- No significant changes since `3.0.0`.
## 3.0.0 - 2021-12-26
- No significant changes since `3.0.0-rc.2`.
## 3.0.0-rc.2 - 2021-12-10
- Re-export `openssl::SslConnectorBuilder` in `connect::openssl::reexports`. [#429]
[#429]: https://github.com/actix/actix-net/pull/429
## 3.0.0-rc.1 - 2021-11-29
### Added
* Derive `Debug` for `connect::Connection`. [#422]
* Implement `Display` for `accept::TlsError`. [#422]
* Implement `Error` for `accept::TlsError` where both types also implement `Error`. [#422]
* Implement `Default` for `connect::Resolver`. [#422]
* Implement `Error` for `connect::ConnectError`. [#422]
* Implement `Default` for `connect::tcp::{TcpConnector, TcpConnectorService}`. [#423]
* Implement `Default` for `connect::ConnectorService`. [#423]
- Derive `Debug` for `connect::Connection`. [#422]
- Implement `Display` for `accept::TlsError`. [#422]
- Implement `Error` for `accept::TlsError` where both types also implement `Error`. [#422]
- Implement `Default` for `connect::Resolver`. [#422]
- Implement `Error` for `connect::ConnectError`. [#422]
- Implement `Default` for `connect::tcp::{TcpConnector, TcpConnectorService}`. [#423]
- Implement `Default` for `connect::ConnectorService`. [#423]
### Changed
* The crate's default features flags no longer include `uri`. [#422]
* Useful re-exports from underlying TLS crates are exposed in a `reexports` modules in all acceptors and connectors.
* Convert `connect::ResolverService` from enum to struct. [#422]
* Make `ConnectAddrsIter` private. [#422]
* Mark `tcp::{TcpConnector, TcpConnectorService}` structs `#[non_exhaustive]`. [#423]
* Rename `accept::native_tls::{NativeTlsAcceptorService => AcceptorService}`. [#422]
* Rename `connect::{Address => Host}` trait. [#422]
* Rename method `connect::Connection::{host => hostname}`. [#422]
* Rename struct `connect::{Connect => ConnectInfo}`. [#422]
* Rename struct `connect::{ConnectService => ConnectorService}`. [#422]
* Rename struct `connect::{ConnectServiceFactory => Connector}`. [#422]
* Rename TLS acceptor service future types and hide from docs. [#422]
* Unbox some service futures types. [#422]
* Inline modules in `connect::tls` to `connect` module. [#422]
- The crate's default features flags no longer include `uri`. [#422]
- Useful re-exports from underlying TLS crates are exposed in a `reexports` modules in all acceptors and connectors.
- Convert `connect::ResolverService` from enum to struct. [#422]
- Make `ConnectAddrsIter` private. [#422]
- Mark `tcp::{TcpConnector, TcpConnectorService}` structs `#[non_exhaustive]`. [#423]
- Rename `accept::native_tls::{NativeTlsAcceptorService => AcceptorService}`. [#422]
- Rename `connect::{Address => Host}` trait. [#422]
- Rename method `connect::Connection::{host => hostname}`. [#422]
- Rename struct `connect::{Connect => ConnectInfo}`. [#422]
- Rename struct `connect::{ConnectService => ConnectorService}`. [#422]
- Rename struct `connect::{ConnectServiceFactory => Connector}`. [#422]
- Rename TLS acceptor service future types and hide from docs. [#422]
- Unbox some service futures types. [#422]
- Inline modules in `connect::tls` to `connect` module. [#422]
### Removed
* Remove `connect::{new_connector, new_connector_factory, default_connector, default_connector_factory}` methods. [#422]
* Remove `connect::native_tls::Connector::service` method. [#422]
* Remove redundant `connect::Connection::from_parts` method. [#422]
- Remove `connect::{new_connector, new_connector_factory, default_connector, default_connector_factory}` methods. [#422]
- Remove `connect::native_tls::Connector::service` method. [#422]
- Remove redundant `connect::Connection::from_parts` method. [#422]
[#422]: https://github.com/actix/actix-net/pull/422
[#423]: https://github.com/actix/actix-net/pull/423
## 3.0.0-beta.9 - 2021-11-22
* Add configurable timeout for accepting TLS connection. [#393]
* Added `TlsError::Timeout` variant. [#393]
* All TLS acceptor services now use `TlsError` for their error types. [#393]
* Added `TlsError::into_service_error`. [#420]
- Add configurable timeout for accepting TLS connection. [#393]
- Added `TlsError::Timeout` variant. [#393]
- All TLS acceptor services now use `TlsError` for their error types. [#393]
- Added `TlsError::into_service_error`. [#420]
[#393]: https://github.com/actix/actix-net/pull/393
[#420]: https://github.com/actix/actix-net/pull/420
## 3.0.0-beta.8 - 2021-11-15
* Add `Connect::request` for getting a reference to the connection request. [#415]
- Add `Connect::request` for getting a reference to the connection request. [#415]
[#415]: https://github.com/actix/actix-net/pull/415
## 3.0.0-beta.7 - 2021-10-20
* Add `webpki_roots_cert_store()` to get rustls compatible webpki roots cert store. [#401]
* Alias `connect::ssl` to `connect::tls`. [#401]
- Add `webpki_roots_cert_store()` to get rustls compatible webpki roots cert store. [#401]
- Alias `connect::ssl` to `connect::tls`. [#401]
[#401]: https://github.com/actix/actix-net/pull/401
## 3.0.0-beta.6 - 2021-10-19
* Update `tokio-rustls` to `0.23` which uses `rustls` `0.20`. [#396]
* Removed a re-export of `Session` from `rustls` as it no longer exist. [#396]
* Minimum supported Rust version (MSRV) is now 1.52.
- Update `tokio-rustls` to `0.23` which uses `rustls` `0.20`. [#396]
- Removed a re-export of `Session` from `rustls` as it no longer exist. [#396]
- Minimum supported Rust version (MSRV) is now 1.52.
[#396]: https://github.com/actix/actix-net/pull/396
## 3.0.0-beta.5 - 2021-03-29
* Changed `connect::ssl::rustls::RustlsConnectorService` to return error when `DNSNameRef`
- Changed `connect::ssl::rustls::RustlsConnectorService` to return error when `DNSNameRef`
generation failed instead of panic. [#296]
* Remove `connect::ssl::openssl::OpensslConnectServiceFactory`. [#297]
* Remove `connect::ssl::openssl::OpensslConnectService`. [#297]
* Add `connect::ssl::native_tls` module for native tls support. [#295]
* Rename `accept::{nativetls => native_tls}`. [#295]
* Remove `connect::TcpConnectService` type. Service caller expecting a `TcpStream` should use `connect::ConnectService` instead and call `Connection<T, TcpStream>::into_parts`. [#299]
- Remove `connect::ssl::openssl::OpensslConnectServiceFactory`. [#297]
- Remove `connect::ssl::openssl::OpensslConnectService`. [#297]
- Add `connect::ssl::native_tls` module for native tls support. [#295]
- Rename `accept::{nativetls => native_tls}`. [#295]
- Remove `connect::TcpConnectService` type. Service caller expecting a `TcpStream` should use `connect::ConnectService` instead and call `Connection<T, TcpStream>::into_parts`. [#299]
[#295]: https://github.com/actix/actix-net/pull/295
[#296]: https://github.com/actix/actix-net/pull/296
@@ -85,72 +116,72 @@
## 3.0.0-beta.4 - 2021-02-24
* Rename `accept::openssl::{SslStream => TlsStream}`.
* Add `connect::Connect::set_local_addr` to attach local `IpAddr`. [#282]
* `connector::TcpConnector` service will try to bind to local_addr of `IpAddr` when given. [#282]
- Rename `accept::openssl::{SslStream => TlsStream}`.
- Add `connect::Connect::set_local_addr` to attach local `IpAddr`. [#282]
- `connector::TcpConnector` service will try to bind to local_addr of `IpAddr` when given. [#282]
[#282]: https://github.com/actix/actix-net/pull/282
## 3.0.0-beta.3 - 2021-02-06
* Remove `trust-dns-proto` and `trust-dns-resolver`. [#248]
* Use `std::net::ToSocketAddrs` as simple and basic default resolver. [#248]
* Add `Resolve` trait for custom DNS resolvers. [#248]
* Add `Resolver::new_custom` function to construct custom resolvers. [#248]
* Export `webpki_roots::TLS_SERVER_ROOTS` in `actix_tls::connect` mod and remove
- Remove `trust-dns-proto` and `trust-dns-resolver`. [#248]
- Use `std::net::ToSocketAddrs` as simple and basic default resolver. [#248]
- Add `Resolve` trait for custom DNS resolvers. [#248]
- Add `Resolver::new_custom` function to construct custom resolvers. [#248]
- Export `webpki_roots::TLS_SERVER_ROOTS` in `actix_tls::connect` mod and remove
the export from `actix_tls::accept` [#248]
* Remove `ConnectTakeAddrsIter`. `Connect::take_addrs` now returns `ConnectAddrsIter<'static>`
- Remove `ConnectTakeAddrsIter`. `Connect::take_addrs` now returns `ConnectAddrsIter<'static>`
as owned iterator. [#248]
* Rename `Address::{host => hostname}` to more accurately describe which URL segment is returned.
* Update `actix-rt` to `2.0.0`. [#273]
- Rename `Address::{host => hostname}` to more accurately describe which URL segment is returned.
- Update `actix-rt` to `2.0.0`. [#273]
[#248]: https://github.com/actix/actix-net/pull/248
[#273]: https://github.com/actix/actix-net/pull/273
## 3.0.0-beta.2 - 2021-xx-xx
* Depend on stable trust-dns packages. [#204]
## 3.0.0-beta.2 - 2022-xx-xx
- Depend on stable trust-dns packages. [#204]
[#204]: https://github.com/actix/actix-net/pull/204
## 3.0.0-beta.1 - 2020-12-29
* Move acceptors under `accept` module. [#238]
* Merge `actix-connect` crate under `connect` module. [#238]
* Add feature flags to enable acceptors and/or connectors individually. [#238]
- Move acceptors under `accept` module. [#238]
- Merge `actix-connect` crate under `connect` module. [#238]
- Add feature flags to enable acceptors and/or connectors individually. [#238]
[#238]: https://github.com/actix/actix-net/pull/238
## 2.0.0 - 2020-09-03
* `nativetls::NativeTlsAcceptor` is renamed to `nativetls::Acceptor`.
* Where possible, "SSL" terminology is replaced with "TLS".
- `nativetls::NativeTlsAcceptor` is renamed to `nativetls::Acceptor`.
- Where possible, "SSL" terminology is replaced with "TLS".
* `SslError` is renamed to `TlsError`.
* `TlsError::Ssl` enum variant is renamed to `TlsError::Tls`.
* `max_concurrent_ssl_connect` is renamed to `max_concurrent_tls_connect`.
## 2.0.0-alpha.2 - 2020-08-17
* Update `rustls` dependency to 0.18
* Update `tokio-rustls` dependency to 0.14
* Update `webpki-roots` dependency to 0.20
- Update `rustls` dependency to 0.18
- Update `tokio-rustls` dependency to 0.14
- Update `webpki-roots` dependency to 0.20
## [2.0.0-alpha.1] - 2020-03-03
* Update `rustls` dependency to 0.17
* Update `tokio-rustls` dependency to 0.13
* Update `webpki-roots` dependency to 0.19
- Update `rustls` dependency to 0.17
- Update `tokio-rustls` dependency to 0.13
- Update `webpki-roots` dependency to 0.19
## [1.0.0] - 2019-12-11
* 1.0.0 release
- 1.0.0 release
## [1.0.0-alpha.3] - 2019-12-07
* Migrate to tokio 0.2
* Enable rustls acceptor service
* Enable native-tls acceptor service
- Migrate to tokio 0.2
- Enable rustls acceptor service
- Enable native-tls acceptor service
## [1.0.0-alpha.1] - 2019-12-02
* Split openssl acceptor from actix-server package
- Split openssl acceptor from actix-server package

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-tls"
version = "3.0.0-rc.1"
version = "3.0.4"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@@ -8,7 +8,7 @@ authors = [
description = "TLS acceptor and connector services for Actix ecosystem"
keywords = ["network", "tls", "ssl", "async", "transport"]
repository = "https://github.com/actix/actix-net.git"
categories = ["network-programming", "asynchronous"]
categories = ["network-programming", "asynchronous", "cryptography"]
license = "MIT OR Apache-2.0"
edition = "2018"
@@ -30,28 +30,28 @@ accept = []
connect = []
# use openssl impls
openssl = ["tls-openssl", "tokio-openssl"]
openssl = ["tls-openssl", "tokio-openssl", "actix-codec"]
# use rustls impls
rustls = ["tokio-rustls", "webpki-roots"]
rustls = ["tokio-rustls", "webpki-roots", "actix-codec"]
# use native-tls impls
native-tls = ["tokio-native-tls"]
native-tls = ["tokio-native-tls", "actix-codec"]
# support http::Uri as connect address
uri = ["http"]
[dependencies]
actix-codec = "0.4.0"
actix-codec = { version = "0.5.0", optional = true }
actix-rt = { version = "2.2.0", default-features = false }
actix-service = "2.0.0"
actix-utils = "3.0.0"
actix-service = "2"
actix-utils = "3"
derive_more = "0.99.5"
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
log = "0.4"
impl-more = "0.1"
pin-project-lite = "0.2.7"
tokio-util = { version = "0.6.3", default-features = false }
tokio-util = "0.7"
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
# uri
http = { version = "0.2.3", optional = true }
@@ -68,8 +68,9 @@ webpki-roots = { version = "0.22", optional = true }
tokio-native-tls = { version = "0.3", optional = true }
[dev-dependencies]
actix-codec = "0.5.0"
actix-rt = "2.2.0"
actix-server = "2.0.0-rc.1"
actix-server = "2"
bytes = "1"
env_logger = "0.9"
futures-util = { version = "0.3.7", default-features = false, features = ["sink"] }
@@ -77,7 +78,7 @@ log = "0.4"
rcgen = "0.8"
rustls-pemfile = "0.2.1"
tokio-rustls = { version = "0.23", features = ["dangerous_configuration"] }
trust-dns-resolver = "0.20.0"
trust-dns-resolver = "0.20"
[[example]]
name = "accept-rustls"

View File

@@ -15,8 +15,9 @@
//! http --verify=false https://127.0.0.1:8443
//! ```
// this use only exists because of how we have organised the crate
// it is not necessary for your actual code
#[rustfmt::skip]
// this `use` is only exists because of how we have organised the crate
// it is not necessary for your actual code; you should import from `rustls` directly
use tokio_rustls::rustls;
use std::{
@@ -34,9 +35,9 @@ use actix_server::Server;
use actix_service::ServiceFactoryExt as _;
use actix_tls::accept::rustls::{Acceptor as RustlsAcceptor, TlsStream};
use futures_util::future::ok;
use log::info;
use rustls::{server::ServerConfig, Certificate, PrivateKey};
use rustls_pemfile::{certs, rsa_private_keys};
use tracing::info;
#[actix_rt::main]
async fn main() -> io::Result<()> {

View File

@@ -2,11 +2,12 @@
use std::{
convert::Infallible,
error::Error,
fmt,
sync::atomic::{AtomicUsize, Ordering},
};
use actix_utils::counter::Counter;
use derive_more::{Display, Error};
#[cfg(feature = "openssl")]
#[cfg_attr(docsrs, doc(cfg(feature = "openssl")))]
@@ -43,23 +44,45 @@ pub fn max_concurrent_tls_connect(num: usize) {
/// TLS handshake error, TLS timeout, or inner service error.
///
/// All TLS acceptors from this crate will return the `SvcErr` type parameter as [`Infallible`],
/// which can be cast to your own service type, inferred or otherwise,
/// using [`into_service_error`](Self::into_service_error).
#[derive(Debug, Display, Error)]
/// which can be cast to your own service type, inferred or otherwise, using [`into_service_error`].
///
/// [`into_service_error`]: Self::into_service_error
#[derive(Debug)]
pub enum TlsError<TlsErr, SvcErr> {
/// TLS handshake has timed-out.
#[display(fmt = "TLS handshake has timed-out")]
Timeout,
/// Wraps TLS service errors.
#[display(fmt = "TLS handshake error")]
Tls(TlsErr),
/// Wraps service errors.
#[display(fmt = "Service error")]
Service(SvcErr),
}
impl<TlsErr, SvcErr> fmt::Display for TlsError<TlsErr, SvcErr> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Timeout => f.write_str("TLS handshake has timed-out"),
Self::Tls(_) => f.write_str("TLS handshake error"),
Self::Service(_) => f.write_str("Service error"),
}
}
}
impl<TlsErr, SvcErr> Error for TlsError<TlsErr, SvcErr>
where
TlsErr: Error + 'static,
SvcErr: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TlsError::Tls(err) => Some(err),
TlsError::Service(err) => Some(err),
TlsError::Timeout => None,
}
}
}
impl<TlsErr> TlsError<TlsErr, Infallible> {
/// Casts the infallible service error type returned from acceptors into caller's type.
///

View File

@@ -20,7 +20,6 @@ use actix_utils::{
counter::Counter,
future::{ready, Ready as FutReady},
};
use derive_more::{Deref, DerefMut, From};
use futures_core::future::LocalBoxFuture;
use tokio_native_tls::{native_tls::Error, TlsAcceptor};
@@ -33,9 +32,11 @@ pub mod reexports {
}
/// Wraps a `native-tls` based async TLS stream in order to implement [`ActixStream`].
#[derive(Deref, DerefMut, From)]
pub struct TlsStream<IO>(tokio_native_tls::TlsStream<IO>);
impl_more::impl_from!(<IO> in tokio_native_tls::TlsStream<IO> => TlsStream<IO>);
impl_more::impl_deref_and_mut!(<IO> in TlsStream<IO> => tokio_native_tls::TlsStream<IO>);
impl<IO: ActixStream> AsyncRead for TlsStream<IO> {
fn poll_read(
self: Pin<&mut Self>,

View File

@@ -21,7 +21,6 @@ use actix_utils::{
counter::{Counter, CounterGuard},
future::{ready, Ready as FutReady},
};
use derive_more::{Deref, DerefMut, From};
use openssl::ssl::{Error, Ssl, SslAcceptor};
use pin_project_lite::pin_project;
@@ -36,9 +35,11 @@ pub mod reexports {
}
/// Wraps an `openssl` based async TLS stream in order to implement [`ActixStream`].
#[derive(Deref, DerefMut, From)]
pub struct TlsStream<IO>(tokio_openssl::SslStream<IO>);
impl_more::impl_from!(<IO> in tokio_openssl::SslStream<IO> => TlsStream<IO>);
impl_more::impl_deref_and_mut!(<IO> in TlsStream<IO> => tokio_openssl::SslStream<IO>);
impl<IO: ActixStream> AsyncRead for TlsStream<IO> {
fn poll_read(
self: Pin<&mut Self>,

View File

@@ -22,7 +22,6 @@ use actix_utils::{
counter::{Counter, CounterGuard},
future::{ready, Ready as FutReady},
};
use derive_more::{Deref, DerefMut, From};
use pin_project_lite::pin_project;
use tokio_rustls::rustls::ServerConfig;
use tokio_rustls::{Accept, TlsAcceptor};
@@ -36,9 +35,11 @@ pub mod reexports {
}
/// Wraps a `rustls` based async TLS stream in order to implement [`ActixStream`].
#[derive(Deref, DerefMut, From)]
pub struct TlsStream<IO>(tokio_rustls::server::TlsStream<IO>);
impl_more::impl_from!(<IO> in tokio_rustls::server::TlsStream<IO> => TlsStream<IO>);
impl_more::impl_deref_and_mut!(<IO> in TlsStream<IO> => tokio_rustls::server::TlsStream<IO>);
impl<IO: ActixStream> AsyncRead for TlsStream<IO> {
fn poll_read(
self: Pin<&mut Self>,

View File

@@ -1,20 +1,17 @@
use derive_more::{Deref, DerefMut};
use super::Host;
/// Wraps underlying I/O and the connection request that initiated it.
#[derive(Debug, Deref, DerefMut)]
#[derive(Debug)]
pub struct Connection<R, IO> {
pub(crate) req: R,
#[deref]
#[deref_mut]
pub(crate) io: IO,
}
impl_more::impl_deref_and_mut!(<R, IO> in Connection<R, IO> => io: IO);
impl<R, IO> Connection<R, IO> {
/// Construct new `Connection` from request and IO parts.
pub(crate) fn new(req: R, io: IO) -> Self {
pub fn new(req: R, io: IO) -> Self {
Self { req, io }
}
}

View File

@@ -1,30 +1,38 @@
use std::{error::Error, io};
use derive_more::Display;
use std::{error::Error, fmt, io};
/// Errors that can result from using a connector service.
#[derive(Debug, Display)]
#[derive(Debug)]
pub enum ConnectError {
/// Failed to resolve the hostname
#[display(fmt = "Failed resolving hostname")]
/// Failed to resolve the hostname.
Resolver(Box<dyn std::error::Error>),
/// No DNS records
#[display(fmt = "No DNS records found for the input")]
/// No DNS records.
NoRecords,
/// Invalid input
/// Invalid input.
InvalidInput,
/// Unresolved host name
#[display(fmt = "Connector received `Connect` method with unresolved host")]
/// Unresolved host name.
Unresolved,
/// Connection IO error
#[display(fmt = "{}", _0)]
/// Connection IO error.
Io(io::Error),
}
impl fmt::Display for ConnectError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NoRecords => f.write_str("No DNS records found for the input"),
Self::InvalidInput => f.write_str("Invalid input"),
Self::Unresolved => {
f.write_str("Connector received `Connect` method with unresolved host")
}
Self::Resolver(_) => f.write_str("Failed to resolve hostname"),
Self::Io(_) => f.write_str("I/O error"),
}
}
}
impl Error for ConnectError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {

View File

@@ -8,11 +8,11 @@ use actix_rt::net::ActixStream;
use actix_service::{Service, ServiceFactory};
use actix_utils::future::{ok, Ready};
use futures_core::future::LocalBoxFuture;
use log::trace;
use tokio_native_tls::{
native_tls::TlsConnector as NativeTlsConnector, TlsConnector as AsyncNativeTlsConnector,
TlsStream as AsyncTlsStream,
};
use tracing::trace;
use crate::connect::{Connection, Host};
@@ -20,7 +20,6 @@ pub mod reexports {
//! Re-exports from `native-tls` and `tokio-native-tls` that are useful for connectors.
pub use tokio_native_tls::native_tls::TlsConnector;
pub use tokio_native_tls::TlsStream as AsyncTlsStream;
}
@@ -75,16 +74,16 @@ where
let connector = self.connector.clone();
Box::pin(async move {
trace!("SSL Handshake start for: {:?}", stream.hostname());
trace!("TLS handshake start for: {:?}", stream.hostname());
connector
.connect(stream.hostname(), io)
.await
.map(|res| {
trace!("SSL Handshake success: {:?}", stream.hostname());
trace!("TLS handshake success: {:?}", stream.hostname());
stream.replace_io(res).1
})
.map_err(|e| {
trace!("SSL Handshake error: {:?}", e);
trace!("TLS handshake error: {:?}", e);
io::Error::new(io::ErrorKind::Other, format!("{}", e))
})
})

View File

@@ -13,17 +13,18 @@ use actix_rt::net::ActixStream;
use actix_service::{Service, ServiceFactory};
use actix_utils::future::{ok, Ready};
use futures_core::ready;
use log::trace;
use openssl::ssl::SslConnector;
use tokio_openssl::SslStream as AsyncSslStream;
use tracing::trace;
use crate::connect::{Connection, Host};
pub mod reexports {
//! Re-exports from `openssl` and `tokio-openssl` that are useful for connectors.
pub use openssl::ssl::{Error, HandshakeError, SslConnector, SslMethod};
pub use openssl::ssl::{
Error, HandshakeError, SslConnector, SslConnectorBuilder, SslMethod,
};
pub use tokio_openssl::SslStream as AsyncSslStream;
}
@@ -96,7 +97,8 @@ where
actix_service::always_ready!();
fn call(&self, stream: Connection<R, IO>) -> Self::Future {
trace!("SSL Handshake start for: {:?}", stream.hostname());
trace!("TLS handshake start for: {:?}", stream.hostname());
let (io, stream) = stream.replace_io(());
let host = stream.hostname();
@@ -136,12 +138,15 @@ where
match ready!(Pin::new(this.io.as_mut().unwrap()).poll_connect(cx)) {
Ok(_) => {
let stream = this.stream.take().unwrap();
trace!("SSL Handshake success: {:?}", stream.hostname());
trace!("TLS handshake success: {:?}", stream.hostname());
Poll::Ready(Ok(stream.replace_io(this.io.take().unwrap()).1))
}
Err(e) => {
trace!("SSL Handshake error: {:?}", e);
Poll::Ready(Err(io::Error::new(io::ErrorKind::Other, format!("{}", e))))
Err(err) => {
trace!("TLS handshake error: {:?}", err);
Poll::Ready(Err(io::Error::new(
io::ErrorKind::Other,
format!("{}", err),
)))
}
}
}

View File

@@ -12,7 +12,7 @@ use actix_rt::task::{spawn_blocking, JoinHandle};
use actix_service::{Service, ServiceFactory};
use actix_utils::future::{ok, Ready};
use futures_core::{future::LocalBoxFuture, ready};
use log::trace;
use tracing::trace;
use super::{ConnectError, ConnectInfo, Host, Resolve};
@@ -164,8 +164,8 @@ impl<R: Host> Future for ResolverFut<R> {
Self::LookUp(fut, req) => {
let res = match ready!(Pin::new(fut).poll(cx)) {
Ok(Ok(res)) => Ok(res),
Ok(Err(e)) => Err(ConnectError::Resolver(Box::new(e))),
Err(e) => Err(ConnectError::Io(e.into())),
Ok(Err(err)) => Err(ConnectError::Resolver(Box::new(err))),
Err(err) => Err(ConnectError::Io(err.into())),
};
let req = req.take().unwrap();

View File

@@ -15,10 +15,10 @@ use actix_rt::net::ActixStream;
use actix_service::{Service, ServiceFactory};
use actix_utils::future::{ok, Ready};
use futures_core::ready;
use log::trace;
use tokio_rustls::rustls::{client::ServerName, OwnedTrustAnchor, RootCertStore};
use tokio_rustls::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig};
use tokio_rustls::{Connect as RustlsConnect, TlsConnector as RustlsTlsConnector};
use tracing::trace;
use webpki_roots::TLS_SERVER_ROOTS;
use crate::connect::{Connection, Host};
@@ -26,10 +26,8 @@ use crate::connect::{Connection, Host};
pub mod reexports {
//! Re-exports from `rustls` and `webpki_roots` that are useful for connectors.
pub use tokio_rustls::rustls::ClientConfig;
pub use tokio_rustls::client::TlsStream as AsyncTlsStream;
pub use tokio_rustls::rustls::ClientConfig;
pub use webpki_roots::TLS_SERVER_ROOTS;
}
@@ -103,7 +101,7 @@ where
actix_service::always_ready!();
fn call(&self, connection: Connection<R, IO>) -> Self::Future {
trace!("SSL Handshake start for: {:?}", connection.hostname());
trace!("TLS handshake start for: {:?}", connection.hostname());
let (stream, connection) = connection.replace_io(());
match ServerName::try_from(connection.hostname()) {
@@ -142,7 +140,7 @@ where
Self::Future { connect, connection } => {
let stream = ready!(Pin::new(connect).poll(cx))?;
let connection = connection.take().unwrap();
trace!("SSL Handshake success: {:?}", connection.hostname());
trace!("TLS handshake success: {:?}", connection.hostname());
Poll::Ready(Ok(connection.replace_io(stream).1))
}
}

View File

@@ -15,8 +15,8 @@ use actix_rt::net::{TcpSocket, TcpStream};
use actix_service::{Service, ServiceFactory};
use actix_utils::future::{ok, Ready};
use futures_core::ready;
use log::{error, trace};
use tokio_util::sync::ReusableBoxFuture;
use tracing::{error, trace};
use super::{connect_addrs::ConnectAddrs, error::ConnectError, ConnectInfo, Connection, Host};
@@ -79,7 +79,7 @@ pub enum TcpConnectorFut<R> {
port: u16,
local_addr: Option<IpAddr>,
addrs: Option<VecDeque<SocketAddr>>,
stream: ReusableBoxFuture<Result<TcpStream, io::Error>>,
stream: ReusableBoxFuture<'static, Result<TcpStream, io::Error>>,
},
Error(Option<ConnectError>),
@@ -114,8 +114,8 @@ impl<R: Host> TcpConnectorFut<R> {
stream: ReusableBoxFuture::new(connect(addr, local_addr)),
},
// when resolver returns multiple socket addr for request they would be popped from
// front end of queue and returns with the first successful tcp connection.
// When resolver returns multiple socket addr for request they would be popped from
// front end of queue and returns with the first successful TCP connection.
ConnectAddrs::Multi(mut addrs) => {
let addr = addrs.pop_front().unwrap();

View File

@@ -1,9 +1,10 @@
//! TLS acceptor and connector services for the Actix ecosystem.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
// enable unstable doc_cfg feature only on on docs.rs where nightly compiler is used
#![cfg_attr(docsrs, feature(doc_cfg))]
#[cfg(feature = "openssl")]

View File

@@ -51,13 +51,13 @@ fn openssl_acceptor(cert: String, key: String) -> tls_openssl::ssl::SslAcceptor
mod danger {
use std::time::SystemTime;
use super::*;
use tokio_rustls::rustls::{
self,
client::{ServerCertVerified, ServerCertVerifier},
};
use super::*;
pub struct NoCertificateVerification;
impl ServerCertVerifier for NoCertificateVerification {
@@ -94,7 +94,7 @@ fn rustls_connector(_cert: String, _key: String) -> ClientConfig {
async fn accepts_connections() {
let (cert, key) = new_cert_and_key();
let srv = TestServer::with({
let srv = TestServer::start({
let cert = cert.clone();
let key = key.clone();

View File

@@ -74,7 +74,7 @@ fn openssl_connector(cert: String, key: String) -> SslConnector {
async fn accepts_connections() {
let (cert, key) = new_cert_and_key();
let srv = TestServer::with({
let srv = TestServer::start({
let cert = cert.clone();
let key = key.clone();

View File

@@ -9,15 +9,14 @@ use actix_codec::{BytesCodec, Framed};
use actix_rt::net::TcpStream;
use actix_server::TestServer;
use actix_service::{fn_service, Service, ServiceFactory};
use actix_tls::connect::{ConnectError, ConnectInfo, Connection, Connector, Host};
use bytes::Bytes;
use futures_util::sink::SinkExt;
use actix_tls::connect::{ConnectError, ConnectInfo, Connection, Connector, Host};
#[cfg(feature = "openssl")]
#[actix_rt::test]
async fn test_string() {
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -34,7 +33,7 @@ async fn test_string() {
#[cfg(feature = "rustls")]
#[actix_rt::test]
async fn test_rustls_string() {
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -50,7 +49,7 @@ async fn test_rustls_string() {
#[actix_rt::test]
async fn test_static_str() {
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -81,7 +80,7 @@ async fn service_factory() {
Connector::default()
}
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -101,7 +100,7 @@ async fn service_factory() {
async fn test_openssl_uri() {
use std::convert::TryFrom;
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -120,7 +119,7 @@ async fn test_openssl_uri() {
async fn test_rustls_uri() {
use std::convert::TryFrom;
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -136,7 +135,7 @@ async fn test_rustls_uri() {
#[actix_rt::test]
async fn test_local_addr() {
let srv = TestServer::with(|| {
let srv = TestServer::start(|| {
fn_service(|io: TcpStream| async {
let mut framed = Framed::new(io, BytesCodec);
framed.send(Bytes::from_static(b"test")).await?;
@@ -144,6 +143,9 @@ async fn test_local_addr() {
})
});
// if you've arrived here because of a failing test on macOS run this in your terminal:
// sudo ifconfig lo0 alias 127.0.0.3
let conn = Connector::default().service();
let local = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 3));

View File

@@ -8,11 +8,10 @@ use std::{
use actix_rt::net::TcpStream;
use actix_server::TestServer;
use actix_service::{fn_service, Service, ServiceFactory};
use futures_core::future::LocalBoxFuture;
use actix_tls::connect::{
ConnectError, ConnectInfo, Connection, Connector, Host, Resolve, Resolver,
};
use futures_core::future::LocalBoxFuture;
#[actix_rt::test]
async fn custom_resolver() {
@@ -53,7 +52,7 @@ async fn custom_resolver_connect() {
use trust_dns_resolver::TokioAsyncResolver;
let srv =
TestServer::with(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
TestServer::start(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
struct MyResolver {
trust_dns: TokioAsyncResolver,

View File

@@ -1,5 +1,8 @@
# Changes
## [0.1.0] - 2020-01-15
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
* Initial release
## 0.1.0 - 2020-01-15
- Initial release

View File

@@ -16,12 +16,12 @@ name = "actix_tracing"
path = "src/lib.rs"
[dependencies]
actix-service = "2.0.0"
actix-utils = "3.0.0"
actix-service = "2"
actix-utils = "3"
tracing = "0.1"
tracing = "0.1.35"
tracing-futures = "0.2"
[dev_dependencies]
actix-rt = "2.0.0"
actix-rt = "2"
slab = "0.4"

View File

@@ -1,6 +1,7 @@
//! Actix tracing - support for tokio tracing with Actix services.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
@@ -117,8 +118,6 @@ where
#[cfg(test)]
mod test {
use super::*;
use std::cell::RefCell;
use std::collections::{BTreeMap, BTreeSet};
use std::sync::{Arc, RwLock};
@@ -127,6 +126,8 @@ mod test {
use slab::Slab;
use tracing::{span, Event, Level, Metadata, Subscriber};
use super::*;
thread_local! {
static SPAN: RefCell<Vec<span::Id>> = RefCell::new(Vec::new());
}

View File

@@ -1,182 +1,186 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
## 3.0.1 - 2022-10-21
- Minimum supported Rust version (MSRV) is now 1.57.
## 3.0.0 - 2021-04-16
* No significant changes from `3.0.0-beta.4`.
- No significant changes from `3.0.0-beta.4`.
## 3.0.0-beta.4 - 2021-04-01
* Add `future::Either` type. [#305]
- Add `future::Either` type. [#305]
[#305]: https://github.com/actix/actix-net/pull/305
## 3.0.0-beta.3 - 2021-04-01
* Moved `mpsc` to own crate `local-channel`. [#301]
* Moved `task::LocalWaker` to own crate `local-waker`. [#301]
* Remove `timeout` module. [#301]
* Remove `dispatcher` module. [#301]
* Expose `future` mod with `ready` and `poll_fn` helpers. [#301]
- Moved `mpsc` to own crate `local-channel`. [#301]
- Moved `task::LocalWaker` to own crate `local-waker`. [#301]
- Remove `timeout` module. [#301]
- Remove `dispatcher` module. [#301]
- Expose `future` mod with `ready` and `poll_fn` helpers. [#301]
[#301]: https://github.com/actix/actix-net/pull/301
## 3.0.0-beta.2 - 2021-02-06
* Update `actix-rt` to `2.0.0`. [#273]
- Update `actix-rt` to `2.0.0`. [#273]
[#273]: https://github.com/actix/actix-net/pull/273
## 3.0.0-beta.1 - 2020-12-28
* Update `bytes` dependency to `1`. [#237]
* Use `pin-project-lite` to replace `pin-project`. [#229]
* Remove `condition`,`either`,`inflight`,`keepalive`,`oneshot`,`order`,`stream` and `time` mods. [#229]
- Update `bytes` dependency to `1`. [#237]
- Use `pin-project-lite` to replace `pin-project`. [#229]
- Remove `condition`,`either`,`inflight`,`keepalive`,`oneshot`,`order`,`stream` and `time` mods. [#229]
[#229]: https://github.com/actix/actix-net/pull/229
[#237]: https://github.com/actix/actix-net/pull/237
## 2.0.0 - 2020-08-23
* No changes from beta 1.
- No changes from beta 1.
## 2.0.0-beta.1 - 2020-08-19
* Upgrade `tokio-util` to `0.3`.
* Remove unsound custom Cell and use `std::cell::RefCell` instead, as well as `actix-service`.
* Rename method to correctly spelled `LocalWaker::is_registered`.
- Upgrade `tokio-util` to `0.3`.
- Remove unsound custom Cell and use `std::cell::RefCell` instead, as well as `actix-service`.
- Rename method to correctly spelled `LocalWaker::is_registered`.
## 1.0.6 - 2020-01-08
* Add `Clone` impl for `condition::Waiter`.
- Add `Clone` impl for `condition::Waiter`.
## 1.0.5 - 2020-01-08
* Add `Condition` type.
* Add `Pool` of one-shot's.
- Add `Condition` type.
- Add `Pool` of one-shot's.
## 1.0.4 - 2019-12-20
* Add methods to check `LocalWaker` registration state.
- Add methods to check `LocalWaker` registration state.
## 1.0.3 - 2019-12-11
* Revert InOrder service changes
- Revert InOrder service changes
## 1.0.2 - 2019-12-11
* Allow to create `framed::Dispatcher` with custom `mpsc::Receiver`.
* Add `oneshot::Sender::is_canceled()` method.
- Allow to create `framed::Dispatcher` with custom `mpsc::Receiver`.
- Add `oneshot::Sender::is_canceled()` method.
## 1.0.1 - 2019-12-11
* Optimize InOrder service.
- Optimize InOrder service.
## 1.0.0 - 2019-12-11
* Simplify oneshot and mpsc implementations.
- Simplify oneshot and mpsc implementations.
## 1.0.0-alpha.3 - 2019-12-07
* Migrate to tokio 0.2.
* Fix oneshot.
- Migrate to tokio 0.2.
- Fix oneshot.
## 1.0.0-alpha.2 - 2019-12-02
* Migrate to `std::future`.
- Migrate to `std::future`.
## 0.4.7 - 2019-10-14
* Re-register task on every framed transport poll.
- Re-register task on every framed transport poll.
## 0.4.6 - 2019-10-08
* Refactor `Counter` type. register current task in available method.
- Refactor `Counter` type. register current task in available method.
## 0.4.5 - 2019-07-19
* Deprecated `CloneableService` as it is not safe.
- Deprecated `CloneableService` as it is not safe.
## 0.4.4 - 2019-07-17
* Undeprecate `FramedTransport` as it is actually useful.
- Undeprecate `FramedTransport` as it is actually useful.
## 0.4.3 - 2019-07-17
* Deprecate `CloneableService` as it is not safe and in general not very useful.
* Deprecate `FramedTransport` in favor of `actix-ioframe`.
- Deprecate `CloneableService` as it is not safe and in general not very useful.
- Deprecate `FramedTransport` in favor of `actix-ioframe`.
## 0.4.2 - 2019-06-26
* Do not block on sink drop for FramedTransport.
- Do not block on sink drop for FramedTransport.
## 0.4.1 - 2019-05-15
* Change `Either` constructor.
- Change `Either` constructor.
## 0.4.0 - 2019-05-11
* Change `Either` to handle two nexted services.
* Upgrade actix-service 0.4.
* Removed framed related services.
* Removed stream related services.
- Change `Either` to handle two nexted services.
- Upgrade actix-service 0.4.
- Removed framed related services.
- Removed stream related services.
## 0.3.5 - 2019-04-04
* Allow to send messages to `FramedTransport` via mpsc channel.
* Remove `'static` constraint from Clonable service.
- Allow to send messages to `FramedTransport` via mpsc channel.
- Remove `'static` constraint from Clonable service.
## 0.3.4 - 2019-03-12
* `TimeoutService`, `InOrderService`, `InFlightService` accepts generic IntoService services.
* Fix `InFlightService::poll_ready()` nested service readiness check.
* Fix `InOrderService::poll_ready()` nested service readiness check.
- `TimeoutService`, `InOrderService`, `InFlightService` accepts generic IntoService services.
- Fix `InFlightService::poll_ready()` nested service readiness check.
- Fix `InOrderService::poll_ready()` nested service readiness check.
## 0.3.3 - 2019-03-09
* Revert IntoFuture change.
* Add generic config param for IntoFramed and TakeOne new services.
- Revert IntoFuture change.
- Add generic config param for IntoFramed and TakeOne new services.
## 0.3.2 - 2019-03-04
* Use IntoFuture for new services.
- Use IntoFuture for new services.
## 0.3.1 - 2019-03-04
* Use new type of transform trait.
- Use new type of transform trait.
## 0.3.0 - 2019-03-02
* Use new `NewService` trait
* BoxedNewService` and `BoxedService` types moved to actix-service crate.
- Use new `NewService` trait
- BoxedNewService` and `BoxedService` types moved to actix-service crate.
## 0.2.4 - 2019-02-21
* Custom `BoxedNewService` implementation.
- Custom `BoxedNewService` implementation.
## 0.2.3 - 2019-02-21
* Add `BoxedNewService` and `BoxedService`.
- Add `BoxedNewService` and `BoxedService`.
## 0.2.2 - 2019-02-11
* Add `Display` impl for `TimeoutError`.
* Add `Display` impl for `InOrderError`.
- Add `Display` impl for `TimeoutError`.
- Add `Display` impl for `InOrderError`.
## 0.2.1 - 2019-02-06
* Add `InOrder` service. the service yields responses as they become available,
- Add `InOrder` service. the service yields responses as they become available,
in the order that their originating requests were submitted to the service.
* Convert `Timeout` and `InFlight` services to a transforms.
- Convert `Timeout` and `InFlight` services to a transforms.
## 0.2.0 - 2019-02-01
* Fix framed transport error handling.
* Added Clone impl for Either service.
* Added Clone impl for Timeout service factory.
* Added Service and NewService for Stream dispatcher.
* Switch to actix-service 0.2.
- Fix framed transport error handling.
- Added Clone impl for Either service.
- Added Clone impl for Timeout service factory.
- Added Service and NewService for Stream dispatcher.
- Switch to actix-service 0.2.
## 0.1.0 - 2018-12-09
* Move utils services to separate crate.
- Move utils services to separate crate.

View File

@@ -1,6 +1,6 @@
[package]
name = "actix-utils"
version = "3.0.0"
version = "3.0.1"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",

View File

@@ -22,16 +22,19 @@ impl Counter {
}
/// Create new counter guard, incrementing the counter.
#[inline]
pub fn get(&self) -> CounterGuard {
CounterGuard::new(self.0.clone())
}
/// Returns true if counter is below capacity. Otherwise, register to wake task when it is.
#[inline]
pub fn available(&self, cx: &mut task::Context<'_>) -> bool {
self.0.available(cx)
}
/// Get total number of acquired guards.
#[inline]
pub fn total(&self) -> usize {
self.0.count.get()
}

View File

@@ -40,11 +40,13 @@ pin_project! {
impl<L, R> Either<L, R> {
/// Creates new `Either` using left variant.
#[inline]
pub fn left(value: L) -> Either<L, R> {
Either::Left { value }
}
/// Creates new `Either` using right variant.
#[inline]
pub fn right(value: R) -> Either<L, R> {
Either::Right { value }
}
@@ -52,6 +54,7 @@ impl<L, R> Either<L, R> {
impl<T> Either<T, T> {
/// Unwraps into inner value when left and right have a common type.
#[inline]
pub fn into_inner(self) -> T {
match self {
Either::Left { value } => value,
@@ -67,6 +70,7 @@ where
{
type Output = L::Output;
#[inline]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherProj::Left { value } => value.poll(cx),

View File

@@ -1,4 +1,4 @@
//! Asynchronous values.
//! Helpers for constructing futures.
mod either;
mod poll_fn;

View File

@@ -8,6 +8,32 @@ use core::{
};
/// Creates a future driven by the provided function that receives a task context.
///
/// # Examples
/// ```
/// # use std::task::Poll;
/// # use actix_utils::future::poll_fn;
/// # async fn test_poll_fn() {
/// let res = poll_fn(|_| Poll::Ready(42)).await;
/// assert_eq!(res, 42);
///
/// let mut i = 5;
/// let res = poll_fn(|cx| {
/// i -= 1;
///
/// if i > 0 {
/// cx.waker().wake_by_ref();
/// Poll::Pending
/// } else {
/// Poll::Ready(42)
/// }
/// })
/// .await;
/// assert_eq!(res, 42);
/// # }
/// # actix_rt::Runtime::new().unwrap().block_on(test_poll_fn());
/// ```
#[inline]
pub fn poll_fn<F, T>(f: F) -> PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
@@ -15,13 +41,11 @@ where
PollFn { f }
}
/// A Future driven by the inner function.
/// Future for the [`poll_fn`] function.
pub struct PollFn<F> {
f: F,
}
impl<F> Unpin for PollFn<F> {}
impl<F> fmt::Debug for PollFn<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("PollFn").finish()
@@ -34,15 +58,23 @@ where
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
(self.f)(cx)
#[inline]
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
// SAFETY: we are not moving out of the pinned field
// see https://github.com/rust-lang/rust/pull/102737
(unsafe { &mut self.get_unchecked_mut().f })(cx)
}
}
#[cfg(test)]
mod tests {
use std::marker::PhantomPinned;
use super::*;
static_assertions::assert_impl_all!(PollFn<()>: Unpin);
static_assertions::assert_not_impl_all!(PollFn<PhantomPinned>: Unpin);
#[actix_rt::test]
async fn test_poll_fn() {
let res = poll_fn(|_| Poll::Ready(42)).await;
@@ -62,4 +94,29 @@ mod tests {
.await;
assert_eq!(res, 42);
}
// following soundness tests taken from https://github.com/tokio-rs/tokio/pull/5087
#[allow(dead_code)]
fn require_send<T: Send>(_t: &T) {}
#[allow(dead_code)]
fn require_sync<T: Sync>(_t: &T) {}
trait AmbiguousIfUnpin<A> {
fn some_item(&self) {}
}
impl<T: ?Sized> AmbiguousIfUnpin<()> for T {}
impl<T: ?Sized + Unpin> AmbiguousIfUnpin<[u8; 0]> for T {}
const _: fn() = || {
let pinned = std::marker::PhantomPinned;
let f = poll_fn(move |_| {
// Use `pinned` to take ownership of it.
let _ = &pinned;
std::task::Poll::Pending::<()>
});
require_send(&f);
require_sync(&f);
AmbiguousIfUnpin::some_item(&f);
};
}

View File

@@ -1,4 +1,4 @@
//! When MSRV is 1.48, replace with `core::future::Ready` and `core::future::ready()`.
//! When `core::future::Ready` has a `into_inner()` method, this can be deprecated.
use core::{
future::Future,
@@ -6,7 +6,7 @@ use core::{
task::{Context, Poll},
};
/// Future for the [`ready`](ready()) function.
/// Future for the [`ready`] function.
///
/// Panic will occur if polled more than once.
///
@@ -65,6 +65,7 @@ impl<T> Future for Ready<T> {
/// let a = ready(1);
/// assert_eq!(a.into_inner(), 1);
/// ```
#[inline]
pub fn ready<T>(val: T) -> Ready<T> {
Ready { val: Some(val) }
}
@@ -80,6 +81,7 @@ pub fn ready<T>(val: T) -> Ready<T> {
/// assert_eq!(a.await, Ok(1));
/// # }
/// ```
#[inline]
pub fn ok<T, E>(val: T) -> Ready<Result<T, E>> {
Ready { val: Some(Ok(val)) }
}
@@ -95,6 +97,7 @@ pub fn ok<T, E>(val: T) -> Ready<Result<T, E>> {
/// assert_eq!(a.await, Err(1));
/// # }
/// ```
#[inline]
pub fn err<T, E>(err: E) -> Ready<Result<T, E>> {
Ready {
val: Some(Err(err)),
@@ -106,12 +109,13 @@ mod tests {
use std::rc::Rc;
use futures_util::task::noop_waker;
use static_assertions::{assert_impl_all, assert_not_impl_all};
use static_assertions::{assert_impl_all, assert_not_impl_any};
use super::*;
assert_impl_all!(Ready<()>: Send, Sync, Clone);
assert_not_impl_all!(Ready<Rc<()>>: Send, Sync);
assert_impl_all!(Ready<()>: Send, Sync, Unpin, Clone);
assert_impl_all!(Ready<Rc<()>>: Unpin, Clone);
assert_not_impl_any!(Ready<Rc<()>>: Send, Sync);
#[test]
#[should_panic]

View File

@@ -1,7 +1,7 @@
//! Various utilities used in the Actix ecosystem.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]

View File

@@ -1,36 +1,45 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 1.1.0 - 2022-06-11
- Implement `From<Box<str>>` for `ByteString`. [#458]
- Implement `Into<String>` for `ByteString`. [#458]
- Minimum supported Rust version (MSRV) is now 1.49.
[#458]: https://github.com/actix/actix-net/pull/458
## 1.0.0 - 2020-12-31
* Update `bytes` dependency to `1`.
* Add array and slice of `u8` impls of `TryFrom` up to 32 in length.
* Rename `get_ref` to `as_bytes` and rename `into_inner` to `into_bytes`.
* `ByteString::new` is now a `const fn`.
* Crate is now `#[no_std]` compatible.
- Update `bytes` dependency to `1`.
- Add array and slice of `u8` impls of `TryFrom` up to 32 in length.
- Rename `get_ref` to `as_bytes` and rename `into_inner` to `into_bytes`.
- `ByteString::new` is now a `const fn`.
- Crate is now `#[no_std]` compatible.
## 0.1.5 - 2020-03-30
* Serde support
- Serde support
## 0.1.4 - 2020-01-14
* Fix `AsRef<str>` impl
- Fix `AsRef<str>` impl
## 0.1.3 - 2020-01-13
* Add `PartialEq<T: AsRef<str>>`, `AsRef<[u8]>` impls
- Add `PartialEq<T: AsRef<str>>`, `AsRef<[u8]>` impls
## 0.1.2 - 2019-12-22
* Fix `new()` method
* Make `ByteString::from_static()` and `ByteString::from_bytes_unchecked()` methods const.
- Fix `new()` method
- Make `ByteString::from_static()` and `ByteString::from_bytes_unchecked()` methods const.
## 0.1.1 - 2019-12-07
* Fix hash impl
- Fix hash impl
## 0.1.0 - 2019-12-07
* Initial release
- Initial release

View File

@@ -1,6 +1,6 @@
[package]
name = "bytestring"
version = "1.0.0"
version = "1.1.0"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
"Rob Ede <robjtede@icloud.com>",
@@ -18,7 +18,7 @@ name = "bytestring"
path = "src/lib.rs"
[dependencies]
bytes = "1"
bytes = "1.2"
serde = { version = "1.0", optional = true }
[dev-dependencies]

View File

@@ -2,11 +2,15 @@
#![no_std]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
extern crate alloc;
use alloc::{string::String, vec::Vec};
use alloc::{
boxed::Box,
string::{String, ToString},
vec::Vec,
};
use core::{borrow, convert::TryFrom, fmt, hash, ops, str};
use bytes::Bytes;
@@ -68,7 +72,7 @@ impl AsRef<[u8]> for ByteString {
impl AsRef<str> for ByteString {
fn as_ref(&self) -> &str {
&*self
self
}
}
@@ -92,7 +96,7 @@ impl ops::Deref for ByteString {
impl borrow::Borrow<str> for ByteString {
fn borrow(&self) -> &str {
&*self
self
}
}
@@ -110,6 +114,20 @@ impl From<&str> for ByteString {
}
}
impl From<Box<str>> for ByteString {
#[inline]
fn from(value: Box<str>) -> Self {
Self(Bytes::from(value.into_boxed_bytes()))
}
}
impl From<ByteString> for String {
#[inline]
fn from(value: ByteString) -> Self {
value.to_string()
}
}
impl TryFrom<&[u8]> for ByteString {
type Error = str::Utf8Error;
@@ -219,11 +237,11 @@ mod serde {
#[cfg(test)]
mod serde_impl_tests {
use super::*;
use serde::de::DeserializeOwned;
use static_assertions::assert_impl_all;
use super::*;
assert_impl_all!(ByteString: Serialize, DeserializeOwned);
}
}

View File

@@ -1 +1 @@
msrv = "1.48"
msrv = "1.57"

View File

@@ -1,7 +1,16 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 0.1.3 - 2022-05-03
- Minimum supported Rust version (MSRV) is now 1.49.
## 0.1.2 - 2021-04-01
- No significant changes from `0.1.1`.
## 0.1.1 - 2021-03-29
* Move local mpsc channel to it's own crate.
- Move local mpsc channel to it's own crate.

View File

@@ -1,6 +1,6 @@
[package]
name = "local-channel"
version = "0.1.2"
version = "0.1.3"
description = "A non-threadsafe multi-producer, single-consumer, futures-aware, FIFO queue"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",
@@ -18,4 +18,4 @@ futures-util = { version = "0.3.7", default-features = false }
local-waker = "0.1"
[dev-dependencies]
tokio = { version = "1.5.1", features = ["rt", "macros"] }
tokio = { version = "1.13.1", features = ["rt", "macros"] }

View File

@@ -0,0 +1 @@
../LICENSE-APACHE

1
local-channel/LICENSE-MIT Symbolic link
View File

@@ -0,0 +1 @@
../LICENSE-MIT

View File

@@ -1,7 +1,7 @@
//! Non-thread-safe channels.
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
extern crate alloc;

View File

@@ -1,11 +1,16 @@
# Changes
## Unreleased - 2021-xx-xx
## Unreleased - 2022-xx-xx
- Minimum supported Rust version (MSRV) is now 1.57.
## 0.1.2 - 2021-04-01
* Fix crate metadata.
## 0.1.3 - 2022-05-03
- Minimum supported Rust version (MSRV) is now 1.49.
## 0.1.2 - 2021-12-18
- Fix crate metadata.
## 0.1.1 - 2021-03-29
* Move `LocalWaker` to it's own crate.
- Move `LocalWaker` to it's own crate.

View File

@@ -1,6 +1,6 @@
[package]
name = "local-waker"
version = "0.1.1"
version = "0.1.3"
description = "A synchronization primitive for thread-local task wakeup"
authors = [
"Nikolay Kim <fafhrd91@gmail.com>",

1
local-waker/LICENSE-APACHE Symbolic link
View File

@@ -0,0 +1 @@
../LICENSE-APACHE

1
local-waker/LICENSE-MIT Symbolic link
View File

@@ -0,0 +1 @@
../LICENSE-MIT

View File

@@ -4,7 +4,7 @@
#![no_std]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(missing_docs)]
#![warn(future_incompatible, missing_docs)]
use core::{cell::Cell, fmt, marker::PhantomData, task::Waker};

View File

@@ -1,5 +1,2 @@
max_width = 96
reorder_imports = true
#wrap_comments = true
#fn_args_density = "Compressed"
#use_small_heuristics = false
group_imports = "StdExternalCrate"