mirror of
https://github.com/fafhrd91/actix-net
synced 2025-08-18 16:15:42 +02:00
Compare commits
16 Commits
bytestring
...
macros-v0.
Author | SHA1 | Date | |
---|---|---|---|
|
3eba5b152e | ||
|
3c4b0c2755 | ||
|
462ab6a4f0 | ||
|
e539f83615 | ||
|
755b231e00 | ||
|
8d5d1dbf6f | ||
|
177590a7d8 | ||
|
4cbe741230 | ||
|
80320a0325 | ||
|
6d0dc9628b | ||
|
dbce150993 | ||
|
54ec06cd23 | ||
|
c0693da9ba | ||
|
28f36e4e30 | ||
|
c6ebbcf21b | ||
|
c60d2f9ddb |
@@ -4,6 +4,13 @@ on:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build_and_test_nightly:
|
||||
strategy:
|
||||
@@ -21,8 +28,7 @@ jobs:
|
||||
name: ${{ matrix.target.name }} / ${{ matrix.version }}
|
||||
runs-on: ${{ matrix.target.os }}
|
||||
|
||||
env:
|
||||
VCPKGRS_DYNAMIC: 1
|
||||
env: {}
|
||||
|
||||
steps:
|
||||
- name: Setup Routing
|
||||
@@ -31,39 +37,22 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# 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 }}
|
||||
if: matrix.target.os == 'windows-latest'
|
||||
run: choco install openssl -y --forcex64 --no-progress
|
||||
- name: Set OpenSSL dir in env
|
||||
if: matrix.target.os == 'windows-latest'
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install ${{ matrix.version }}-${{ matrix.target.triple }}
|
||||
rustup override set ${{ matrix.version }}-${{ matrix.target.triple }}
|
||||
echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
# - 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: Install Rust (${{ matrix.version }})
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.version }}
|
||||
|
||||
# - name: Generate Cargo.lock
|
||||
# run: cargo generate-lockfile
|
||||
# - name: Cache Dependencies
|
||||
# uses: Swatinem/rust-cache@v2.2.0
|
||||
|
||||
- name: Install cargo-hack
|
||||
run: cargo install cargo-hack
|
||||
- uses: taiki-e/install-action@v2
|
||||
with: { tool: cargo-hack }
|
||||
|
||||
- name: check lib
|
||||
if: >
|
||||
@@ -109,15 +98,8 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust (nightly)
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install nightly
|
||||
rustup override set nightly
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
run: cargo generate-lockfile
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v2.2.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: { toolchain: nightly }
|
||||
|
||||
- name: Generate coverage file
|
||||
if: github.ref == 'refs/heads/master'
|
||||
@@ -136,21 +118,11 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust (nightly)
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install nightly
|
||||
rustup override set nightly
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: { toolchain: nightly }
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
run: cargo generate-lockfile
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v2.2.0
|
||||
|
||||
- name: Install cargo-minimal-versions
|
||||
run: cargo install cargo-minimal-versions
|
||||
|
||||
- name: Install cargo-hack
|
||||
run: cargo install cargo-hack
|
||||
- uses: taiki-e/install-action@v1
|
||||
with: { tool: cargo-hack, cargo-minimal-versions }
|
||||
|
||||
- name: Check With Minimal Versions
|
||||
run: cargo minimal-versions check
|
||||
@@ -162,15 +134,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install stable
|
||||
rustup override set stable
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
run: cargo generate-lockfile
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v2.2.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
|
||||
- name: Install cargo-nextest
|
||||
run: cargo install cargo-nextest
|
88
.github/workflows/ci.yml
vendored
88
.github/workflows/ci.yml
vendored
@@ -1,10 +1,15 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
push:
|
||||
branches: [master]
|
||||
on:
|
||||
pull_request: {}
|
||||
push: { branches: [master] }
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build_and_test:
|
||||
@@ -18,14 +23,13 @@ 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.59.0
|
||||
- 1.65.0 # MSRV
|
||||
- stable
|
||||
|
||||
name: ${{ matrix.target.name }} / ${{ matrix.version }}
|
||||
runs-on: ${{ matrix.target.os }}
|
||||
|
||||
env:
|
||||
VCPKGRS_DYNAMIC: 1
|
||||
env: {}
|
||||
|
||||
steps:
|
||||
- name: Setup Routing
|
||||
@@ -34,52 +38,22 @@ jobs:
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# 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 }}
|
||||
if: matrix.target.os == 'windows-latest'
|
||||
run: choco install openssl -y --forcex64 --no-progress
|
||||
- name: Set OpenSSL dir in env
|
||||
if: matrix.target.os == 'windows-latest'
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install ${{ matrix.version }}-${{ matrix.target.triple }}
|
||||
rustup override set ${{ matrix.version }}-${{ matrix.target.triple }}
|
||||
echo 'OPENSSL_DIR=C:\Program Files\OpenSSL-Win64' | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo 'OPENSSL_DIR=C:\Program Files\OpenSSL' | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
# - 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: Install Rust (${{ matrix.version }})
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.version }}
|
||||
|
||||
# - name: Generate Cargo.lock
|
||||
# run: cargo generate-lockfile
|
||||
# - name: Cache Dependencies
|
||||
# uses: Swatinem/rust-cache@v2.2.0
|
||||
|
||||
- name: Install cargo-hack
|
||||
if: matrix.version != '1.59.0'
|
||||
run: cargo install cargo-hack
|
||||
|
||||
# newer cargo-hack versions require 1.60 or above
|
||||
- name: Install cargo-hack (1.59.0)
|
||||
if: matrix.version == '1.59.0'
|
||||
run: cargo install cargo-hack --version=0.5.21
|
||||
|
||||
- name: workaround MSRV issues
|
||||
if: matrix.version == '1.59.0'
|
||||
run: |
|
||||
cargo install cargo-edit --version=0.8.0
|
||||
cargo add env_logger@0.9 --dev -p=actix-tls
|
||||
cargo add env_logger@0.9 --dev -p=actix-server
|
||||
- uses: taiki-e/install-action@v1
|
||||
with: { tool: cargo-hack }
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
run: cargo generate-lockfile
|
||||
@@ -87,7 +61,7 @@ jobs:
|
||||
- name: workaround MSRV issues
|
||||
if: matrix.version != 'stable'
|
||||
run: |
|
||||
cargo update -p=time --precise=0.3.13 # time is only a dev dep so shouldn't affect msrv
|
||||
cargo update -p=time --precise=0.3.16 # time is only a dev dep so shouldn't affect msrv
|
||||
|
||||
- name: check lib
|
||||
if: >
|
||||
@@ -125,7 +99,6 @@ jobs:
|
||||
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
|
||||
if: matrix.version == 'stable' # MSRV(1.58) cargo-cache now fails to install on 1.59
|
||||
run: |
|
||||
cargo install cargo-cache --version 0.6.2 --no-default-features --features ci-autoclean
|
||||
cargo-cache
|
||||
@@ -138,15 +111,8 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust (nightly)
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install nightly
|
||||
rustup override set nightly
|
||||
|
||||
- name: Generate Cargo.lock
|
||||
run: cargo generate-lockfile
|
||||
- name: Cache Dependencies
|
||||
uses: Swatinem/rust-cache@v2.2.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: { toolchain: nightly }
|
||||
|
||||
- name: doc tests io-uring
|
||||
run: |
|
||||
|
38
.github/workflows/clippy-fmt.yml
vendored
38
.github/workflows/clippy-fmt.yml
vendored
@@ -1,37 +1,43 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install stable
|
||||
rustup override set stable
|
||||
rustup component add rustfmt
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
components: rustfmt
|
||||
|
||||
- name: Rustfmt Check
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
clippy:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install stable
|
||||
rustup override set stable
|
||||
rustup component add clippy
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: { components: clippy }
|
||||
|
||||
- uses: giraffate/clippy-action@v1
|
||||
with:
|
||||
reporter: "github-pr-check"
|
||||
reporter: 'github-pr-check'
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
clippy_flags: --workspace --all-features --tests --examples --bins -- -Dclippy::todo
|
||||
|
20
.github/workflows/upload-doc.yml
vendored
20
.github/workflows/upload-doc.yml
vendored
@@ -1,21 +1,27 @@
|
||||
name: Upload documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
push: { branches: [master] }
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup set profile minimal
|
||||
rustup install nightly
|
||||
rustup override set nightly
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with: { toolchain: nightly }
|
||||
|
||||
- name: Build Docs
|
||||
run: cargo doc --workspace --all-features --no-deps
|
||||
|
3
.rustfmt.toml
Normal file
3
.rustfmt.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
group_imports = "StdExternalCrate"
|
||||
imports_granularity = "Crate"
|
||||
use_field_init_shorthand = true
|
@@ -12,6 +12,11 @@ members = [
|
||||
"local-channel",
|
||||
"local-waker",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
[patch.crates-io]
|
||||
actix-codec = { path = "actix-codec" }
|
||||
|
@@ -13,7 +13,7 @@ See example folders for [`actix-server`](./actix-server/examples) and [`actix-tl
|
||||
|
||||
## MSRV
|
||||
|
||||
Crates in this repo currently have a Minimum Supported Rust Version (MSRV) of 1.59. As a policy, we permit MSRV increases in non-breaking releases.
|
||||
Crates in this repo currently have a Minimum Supported Rust Version (MSRV) of 1.65. As a policy, we permit MSRV increases in non-breaking releases.
|
||||
|
||||
## License
|
||||
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 0.5.1 - 2022-03-15
|
||||
|
||||
|
@@ -10,20 +10,17 @@ keywords = ["network", "framework", "async", "futures"]
|
||||
repository = "https://github.com/actix/actix-net"
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_codec"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2"
|
||||
bitflags = "2"
|
||||
bytes = "1"
|
||||
futures-core = { version = "0.3.7", default-features = false }
|
||||
futures-sink = { version = "0.3.7", default-features = false }
|
||||
memchr = "2.3"
|
||||
pin-project-lite = "0.2"
|
||||
tokio = "1.18.4"
|
||||
tokio = "1.23.1"
|
||||
tokio-util = { version = "0.7", features = ["codec", "io"] }
|
||||
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
|
||||
|
||||
|
@@ -18,6 +18,7 @@ const LW: usize = 1024;
|
||||
const HW: usize = 8 * 1024;
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Flags: u8 {
|
||||
const EOF = 0b0001;
|
||||
const READABLE = 0b0010;
|
||||
@@ -233,10 +234,7 @@ impl<T, U> Framed<T, U> {
|
||||
}
|
||||
|
||||
/// Flush write buffer to underlying I/O stream.
|
||||
pub fn flush<I>(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), U::Error>>
|
||||
pub fn flush<I>(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
|
||||
where
|
||||
T: AsyncWrite,
|
||||
U: Encoder<I>,
|
||||
@@ -269,10 +267,7 @@ impl<T, U> Framed<T, U> {
|
||||
}
|
||||
|
||||
/// Flush write buffer and shutdown underlying I/O stream.
|
||||
pub fn close<I>(
|
||||
mut self: Pin<&mut Self>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), U::Error>>
|
||||
pub fn close<I>(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), U::Error>>
|
||||
where
|
||||
T: AsyncWrite,
|
||||
U: Encoder<I>,
|
||||
|
@@ -11,14 +11,18 @@
|
||||
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
|
||||
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
||||
|
||||
pub use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||
pub use tokio_util::{
|
||||
codec::{Decoder, Encoder},
|
||||
io::poll_read_buf,
|
||||
};
|
||||
|
||||
mod bcodec;
|
||||
mod framed;
|
||||
mod lines;
|
||||
|
||||
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;
|
||||
pub use self::{
|
||||
bcodec::BytesCodec,
|
||||
framed::{Framed, FramedParts},
|
||||
lines::LinesCodec,
|
||||
};
|
||||
|
@@ -81,10 +81,7 @@ impl AsyncWrite for Bilateral {
|
||||
other => Ready(other),
|
||||
}
|
||||
}
|
||||
fn poll_shutdown(
|
||||
self: Pin<&mut Self>,
|
||||
_cx: &mut Context<'_>,
|
||||
) -> Poll<Result<(), io::Error>> {
|
||||
fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
@@ -1,47 +1,50 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
## 0.2.4
|
||||
|
||||
## 0.2.3 - 2021-10-19
|
||||
- Update `syn` dependency to `2`.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 0.2.3
|
||||
|
||||
- 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
|
||||
## 0.2.2
|
||||
|
||||
- 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
|
||||
## 0.2.1
|
||||
|
||||
- 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
|
||||
## 0.2.0
|
||||
|
||||
- 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
|
||||
## 0.2.0-beta.1
|
||||
|
||||
- Remove `actix-reexport` feature. [#218]
|
||||
|
||||
[#218]: https://github.com/actix/actix-net/pull/218
|
||||
|
||||
## 0.1.3 - 2020-12-03
|
||||
## 0.1.3
|
||||
|
||||
- Add `actix-reexport` feature. [#218]
|
||||
|
||||
[#218]: https://github.com/actix/actix-net/pull/218
|
||||
|
||||
## 0.1.2 - 2020-05-18
|
||||
## 0.1.2
|
||||
|
||||
- Forward actix_rt::test arguments to test function [#127]
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-macros"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
authors = [
|
||||
"Nikolay Kim <fafhrd91@gmail.com>",
|
||||
"Ibraheem Ahmed <ibrah1440@gmail.com>",
|
||||
@@ -10,14 +10,15 @@ description = "Macros for Actix system and runtime"
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = "1"
|
||||
syn = { version = "1", features = ["full"] }
|
||||
syn = { version = "2", features = ["full"] }
|
||||
|
||||
[dev-dependencies]
|
||||
actix-rt = "2"
|
||||
|
@@ -15,6 +15,9 @@
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::parse::Parser as _;
|
||||
|
||||
type AttributeArgs = syn::punctuated::Punctuated<syn::Meta, syn::Token![,]>;
|
||||
|
||||
/// Marks async entry-point function to be executed by Actix system.
|
||||
///
|
||||
@@ -25,9 +28,9 @@ use quote::quote;
|
||||
/// println!("Hello world");
|
||||
/// }
|
||||
/// ```
|
||||
#[allow(clippy::needless_doctest_main)]
|
||||
// #[allow(clippy::needless_doctest_main)]
|
||||
// #[cfg(not(test))] // Work around for rust-lang/rust#62127
|
||||
#[proc_macro_attribute]
|
||||
#[cfg(not(test))] // Work around for rust-lang/rust#62127
|
||||
pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut input = match syn::parse::<syn::ItemFn>(item.clone()) {
|
||||
Ok(input) => input,
|
||||
@@ -35,7 +38,11 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
Err(err) => return input_and_compile_error(item, err),
|
||||
};
|
||||
|
||||
let args = syn::parse_macro_input!(args as syn::AttributeArgs);
|
||||
let parser = AttributeArgs::parse_terminated;
|
||||
let args = match parser.parse(args.clone()) {
|
||||
Ok(args) => args,
|
||||
Err(err) => return input_and_compile_error(args, err),
|
||||
};
|
||||
|
||||
let attrs = &input.attrs;
|
||||
let vis = &input.vis;
|
||||
@@ -55,11 +62,15 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
for arg in &args {
|
||||
match arg {
|
||||
syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue {
|
||||
lit: syn::Lit::Str(lit),
|
||||
syn::Meta::NameValue(syn::MetaNameValue {
|
||||
path,
|
||||
value:
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit),
|
||||
..
|
||||
}),
|
||||
..
|
||||
})) => match path
|
||||
}) => match path
|
||||
.get_ident()
|
||||
.map(|i| i.to_string().to_lowercase())
|
||||
.as_deref()
|
||||
@@ -78,6 +89,7 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
.into();
|
||||
}
|
||||
},
|
||||
|
||||
_ => {
|
||||
return syn::Error::new_spanned(arg, "Unknown attribute specified")
|
||||
.to_compile_error()
|
||||
@@ -114,7 +126,11 @@ pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
Err(err) => return input_and_compile_error(item, err),
|
||||
};
|
||||
|
||||
let args = syn::parse_macro_input!(args as syn::AttributeArgs);
|
||||
let parser = AttributeArgs::parse_terminated;
|
||||
let args = match parser.parse(args.clone()) {
|
||||
Ok(args) => args,
|
||||
Err(err) => return input_and_compile_error(args, err),
|
||||
};
|
||||
|
||||
let attrs = &input.attrs;
|
||||
let vis = &input.vis;
|
||||
@@ -123,7 +139,7 @@ pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut has_test_attr = false;
|
||||
|
||||
for attr in attrs {
|
||||
if attr.path.is_ident("test") {
|
||||
if attr.path().is_ident("test") {
|
||||
has_test_attr = true;
|
||||
}
|
||||
}
|
||||
@@ -149,11 +165,15 @@ pub fn test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||
|
||||
for arg in &args {
|
||||
match arg {
|
||||
syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue {
|
||||
lit: syn::Lit::Str(lit),
|
||||
syn::Meta::NameValue(syn::MetaNameValue {
|
||||
path,
|
||||
value:
|
||||
syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit),
|
||||
..
|
||||
}),
|
||||
..
|
||||
})) => match path
|
||||
}) => match path
|
||||
.get_ident()
|
||||
.map(|i| i.to_string().to_lowercase())
|
||||
.as_deref()
|
||||
|
@@ -1,7 +1,8 @@
|
||||
#[rustversion::stable(1.59)] // MSRV
|
||||
#[rustversion::stable(1.65)] // MSRV
|
||||
#[test]
|
||||
fn compile_macros() {
|
||||
let t = trybuild::TestCases::new();
|
||||
|
||||
t.pass("tests/trybuild/main-01-basic.rs");
|
||||
t.compile_fail("tests/trybuild/main-02-only-async.rs");
|
||||
t.pass("tests/trybuild/main-03-fn-params.rs");
|
||||
|
@@ -1,14 +1,11 @@
|
||||
error: the async keyword is missing from the function declaration
|
||||
--> $DIR/main-02-only-async.rs:2:1
|
||||
--> tests/trybuild/main-02-only-async.rs:2:1
|
||||
|
|
||||
2 | fn main() {
|
||||
| ^^
|
||||
|
||||
error[E0601]: `main` function not found in crate `$CRATE`
|
||||
--> $DIR/main-02-only-async.rs:1:1
|
||||
--> tests/trybuild/main-02-only-async.rs:4:2
|
||||
|
|
||||
1 | / #[actix_rt::main]
|
||||
2 | | fn main() {
|
||||
3 | | futures_util::future::ready(()).await
|
||||
4 | | }
|
||||
| |_^ consider adding a `main` function to `$DIR/tests/trybuild/main-02-only-async.rs`
|
||||
4 | }
|
||||
| ^ consider adding a `main` function to `$DIR/tests/trybuild/main-02-only-async.rs`
|
||||
|
@@ -1,6 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 2.8.0 - 2022-12-21
|
||||
|
||||
|
@@ -11,11 +11,8 @@ homepage = "https://actix.rs"
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_rt"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["macros"]
|
||||
@@ -26,12 +23,12 @@ io-uring = ["tokio-uring"]
|
||||
actix-macros = { version = "0.2.3", optional = true }
|
||||
|
||||
futures-core = { version = "0.3", default-features = false }
|
||||
tokio = { version = "1.18.4", features = ["rt", "net", "parking_lot", "signal", "sync", "time"] }
|
||||
tokio = { version = "1.23.1", features = ["rt", "net", "parking_lot", "signal", "sync", "time"] }
|
||||
|
||||
# runtime for `io-uring` feature
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
tokio-uring = { version = "0.4", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.18.4", features = ["full"] }
|
||||
tokio = { version = "1.23.1", features = ["full"] }
|
||||
hyper = { version = "0.14.10", default-features = false, features = ["server", "tcp", "http1"] }
|
||||
|
@@ -20,8 +20,7 @@ fn main() {
|
||||
let make_service =
|
||||
make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
|
||||
|
||||
let server =
|
||||
Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000))).serve(make_service);
|
||||
let server = Server::bind(&SocketAddr::from(([127, 0, 0, 1], 3000))).serve(make_service);
|
||||
|
||||
if let Err(err) = server.await {
|
||||
eprintln!("server error: {}", err);
|
||||
|
@@ -99,8 +99,7 @@ impl Arbiter {
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Arbiter {
|
||||
Self::with_tokio_rt(|| {
|
||||
crate::runtime::default_tokio_runtime()
|
||||
.expect("Cannot create new Arbiter's Runtime.")
|
||||
crate::runtime::default_tokio_runtime().expect("Cannot create new Arbiter's Runtime.")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -149,9 +148,7 @@ impl Arbiter {
|
||||
.send(SystemCommand::DeregisterArbiter(arb_id));
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
panic!("Cannot spawn Arbiter's thread: {:?}. {:?}", &name, err)
|
||||
});
|
||||
.unwrap_or_else(|err| panic!("Cannot spawn Arbiter's thread: {name:?}: {err:?}"));
|
||||
|
||||
ready_rx.recv().unwrap();
|
||||
|
||||
@@ -201,9 +198,7 @@ impl Arbiter {
|
||||
.send(SystemCommand::DeregisterArbiter(arb_id));
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|err| {
|
||||
panic!("Cannot spawn Arbiter's thread: {:?}. {:?}", &name, err)
|
||||
});
|
||||
.unwrap_or_else(|err| panic!("Cannot spawn Arbiter's thread: {name:?}: {err:?}"));
|
||||
|
||||
ready_rx.recv().unwrap();
|
||||
|
||||
|
@@ -65,9 +65,11 @@ 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 self::{
|
||||
arbiter::{Arbiter, ArbiterHandle},
|
||||
runtime::Runtime,
|
||||
system::{System, SystemRunner},
|
||||
};
|
||||
|
||||
pub mod signal {
|
||||
//! Asynchronous signal handling (Tokio re-exports).
|
||||
@@ -89,12 +91,13 @@ pub mod net {
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
pub use tokio::io::Ready;
|
||||
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};
|
||||
pub use tokio::{
|
||||
io::Ready,
|
||||
net::{TcpListener, TcpSocket, TcpStream, UdpSocket},
|
||||
};
|
||||
|
||||
/// Extension trait over async read+write types that can also signal readiness.
|
||||
#[doc(hidden)]
|
||||
@@ -153,10 +156,9 @@ pub mod net {
|
||||
pub mod time {
|
||||
//! Utilities for tracking time (Tokio re-exports).
|
||||
|
||||
pub use tokio::time::Instant;
|
||||
pub use tokio::time::{interval, interval_at, Interval};
|
||||
pub use tokio::time::{sleep, sleep_until, Sleep};
|
||||
pub use tokio::time::{timeout, Timeout};
|
||||
pub use tokio::time::{
|
||||
interval, interval_at, sleep, sleep_until, timeout, Instant, Interval, Sleep, Timeout,
|
||||
};
|
||||
}
|
||||
|
||||
pub mod task {
|
||||
|
@@ -226,9 +226,7 @@ impl SystemRunner {
|
||||
|
||||
/// Runs the event loop until [stopped](System::stop_with_code), returning the exit code.
|
||||
pub fn run_with_code(self) -> io::Result<i32> {
|
||||
unimplemented!(
|
||||
"SystemRunner::run_with_code is not implemented for io-uring feature yet"
|
||||
);
|
||||
unimplemented!("SystemRunner::run_with_code is not implemented for io-uring feature yet");
|
||||
}
|
||||
|
||||
/// Runs the provided future, blocking the current thread until the future completes.
|
||||
|
@@ -1,6 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Add support for MultiPath TCP (MPTCP) with `MpTcp` enum and `ServerBuilder::mptcp()` method.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 2.2.0 - 2022-12-21
|
||||
|
||||
|
@@ -12,11 +12,8 @@ categories = ["network-programming", "asynchronous"]
|
||||
homepage = "https://actix.rs"
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_server"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
@@ -31,8 +28,8 @@ futures-core = { version = "0.3.17", default-features = false, features = ["allo
|
||||
futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] }
|
||||
mio = { version = "0.8", features = ["os-poll", "net"] }
|
||||
num_cpus = "1.13"
|
||||
socket2 = "0.4.2"
|
||||
tokio = { version = "1.18.4", features = ["sync"] }
|
||||
socket2 = "0.5"
|
||||
tokio = { version = "1.23.1", features = ["sync"] }
|
||||
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
|
||||
|
||||
# runtime for `io-uring` feature
|
||||
@@ -46,4 +43,4 @@ actix-rt = "2.8"
|
||||
bytes = "1"
|
||||
env_logger = "0.10"
|
||||
futures-util = { version = "0.3.17", default-features = false, features = ["sink", "async-await-macro"] }
|
||||
tokio = { version = "1.18.4", features = ["io-util", "rt-multi-thread", "macros", "fs"] }
|
||||
tokio = { version = "1.23.1", features = ["io-util", "rt-multi-thread", "macros", "fs"] }
|
||||
|
@@ -7,13 +7,27 @@ use tracing::{info, trace};
|
||||
use crate::{
|
||||
server::ServerCommand,
|
||||
service::{InternalServiceFactory, ServerServiceFactory, StreamNewService},
|
||||
socket::{
|
||||
create_mio_tcp_listener, MioListener, MioTcpListener, StdTcpListener, ToSocketAddrs,
|
||||
},
|
||||
socket::{create_mio_tcp_listener, MioListener, MioTcpListener, StdTcpListener, ToSocketAddrs},
|
||||
worker::ServerWorkerConfig,
|
||||
Server,
|
||||
};
|
||||
|
||||
/// Multipath TCP (MPTCP) preference.
|
||||
///
|
||||
/// Also see [`ServerBuilder::mptcp()`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MpTcp {
|
||||
/// MPTCP will not be used when binding sockets.
|
||||
Disabled,
|
||||
|
||||
/// MPTCP will be attempted when binding sockets. If errors occur, regular TCP will be
|
||||
/// attempted, too.
|
||||
TcpFallback,
|
||||
|
||||
/// MPTCP will be used when binding sockets (with no fallback).
|
||||
NoFallback,
|
||||
}
|
||||
|
||||
/// [Server] builder.
|
||||
pub struct ServerBuilder {
|
||||
pub(crate) threads: usize,
|
||||
@@ -21,6 +35,7 @@ pub struct ServerBuilder {
|
||||
pub(crate) backlog: u32,
|
||||
pub(crate) factories: Vec<Box<dyn InternalServiceFactory>>,
|
||||
pub(crate) sockets: Vec<(usize, String, MioListener)>,
|
||||
pub(crate) mptcp: MpTcp,
|
||||
pub(crate) exit: bool,
|
||||
pub(crate) listen_os_signals: bool,
|
||||
pub(crate) cmd_tx: UnboundedSender<ServerCommand>,
|
||||
@@ -45,6 +60,7 @@ impl ServerBuilder {
|
||||
factories: Vec::new(),
|
||||
sockets: Vec::new(),
|
||||
backlog: 2048,
|
||||
mptcp: MpTcp::Disabled,
|
||||
exit: false,
|
||||
listen_os_signals: true,
|
||||
cmd_tx,
|
||||
@@ -98,6 +114,24 @@ impl ServerBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets MultiPath TCP (MPTCP) preference on bound sockets.
|
||||
///
|
||||
/// Multipath TCP (MPTCP) builds on top of TCP to improve connection redundancy and performance
|
||||
/// by sharing a network data stream across multiple underlying TCP sessions. See [mptcp.dev]
|
||||
/// for more info about MPTCP itself.
|
||||
///
|
||||
/// MPTCP is available on Linux kernel version 5.6 and higher. In addition, you'll also need to
|
||||
/// ensure the kernel option is enabled using `sysctl net.mptcp.enabled=1`.
|
||||
///
|
||||
/// This method will have no effect if called after a `bind()`.
|
||||
///
|
||||
/// [mptcp.dev]: https://www.mptcp.dev
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn mptcp(mut self, mptcp_enabled: MpTcp) -> Self {
|
||||
self.mptcp = mptcp_enabled;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the maximum per-worker number of concurrent connections.
|
||||
///
|
||||
/// All socket listeners will stop accepting connections when this limit is reached for
|
||||
@@ -146,7 +180,7 @@ impl ServerBuilder {
|
||||
U: ToSocketAddrs,
|
||||
N: AsRef<str>,
|
||||
{
|
||||
let sockets = bind_addr(addr, self.backlog)?;
|
||||
let sockets = bind_addr(addr, self.backlog, &self.mptcp)?;
|
||||
|
||||
trace!("binding server to: {:?}", &sockets);
|
||||
|
||||
@@ -246,8 +280,7 @@ impl ServerBuilder {
|
||||
use std::net::{IpAddr, Ipv4Addr};
|
||||
lst.set_nonblocking(true)?;
|
||||
let token = self.next_token();
|
||||
let addr =
|
||||
crate::socket::StdSocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
|
||||
let addr = crate::socket::StdSocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
|
||||
self.factories.push(StreamNewService::create(
|
||||
name.as_ref().to_string(),
|
||||
token,
|
||||
@@ -263,13 +296,14 @@ impl ServerBuilder {
|
||||
pub(super) fn bind_addr<S: ToSocketAddrs>(
|
||||
addr: S,
|
||||
backlog: u32,
|
||||
mptcp: &MpTcp,
|
||||
) -> io::Result<Vec<MioTcpListener>> {
|
||||
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) {
|
||||
match create_mio_tcp_listener(addr, backlog, mptcp) {
|
||||
Ok(lst) => {
|
||||
success = true;
|
||||
sockets.push(lst);
|
||||
|
@@ -18,13 +18,15 @@ mod test_server;
|
||||
mod waker_queue;
|
||||
mod worker;
|
||||
|
||||
pub use self::builder::ServerBuilder;
|
||||
pub use self::handle::ServerHandle;
|
||||
pub use self::server::Server;
|
||||
pub use self::service::ServerServiceFactory;
|
||||
#[doc(hidden)]
|
||||
pub use self::socket::FromStream;
|
||||
pub use self::test_server::TestServer;
|
||||
pub use self::{
|
||||
builder::{MpTcp, ServerBuilder},
|
||||
handle::ServerHandle,
|
||||
server::Server,
|
||||
service::ServerServiceFactory,
|
||||
test_server::TestServer,
|
||||
};
|
||||
|
||||
/// Start server building process
|
||||
#[doc(hidden)]
|
||||
|
@@ -78,7 +78,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
error!("can not convert to an async TCP stream: {}", err);
|
||||
error!("can not convert to an async TCP stream: {err}");
|
||||
Err(())
|
||||
}
|
||||
})
|
||||
|
@@ -8,10 +8,11 @@ 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,
|
||||
mio::net::UnixListener as MioUnixListener, std::os::unix::net::UnixListener as StdUnixListener,
|
||||
};
|
||||
|
||||
use crate::builder::MpTcp;
|
||||
|
||||
pub(crate) enum MioListener {
|
||||
Tcp(MioTcpListener),
|
||||
#[cfg(unix)]
|
||||
@@ -105,7 +106,7 @@ impl fmt::Debug for MioListener {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
MioListener::Tcp(ref lst) => write!(f, "{:?}", lst),
|
||||
#[cfg(all(unix))]
|
||||
#[cfg(unix)]
|
||||
MioListener::Uds(ref lst) => write!(f, "{:?}", lst),
|
||||
}
|
||||
}
|
||||
@@ -224,10 +225,30 @@ mod unix_impl {
|
||||
pub(crate) fn create_mio_tcp_listener(
|
||||
addr: StdSocketAddr,
|
||||
backlog: u32,
|
||||
mptcp: &MpTcp,
|
||||
) -> io::Result<MioTcpListener> {
|
||||
use socket2::{Domain, Protocol, Socket, Type};
|
||||
|
||||
let socket = Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP))?;
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
let protocol = Protocol::TCP;
|
||||
#[cfg(target_os = "linux")]
|
||||
let protocol = if matches!(mptcp, MpTcp::Disabled) {
|
||||
Protocol::TCP
|
||||
} else {
|
||||
Protocol::MPTCP
|
||||
};
|
||||
|
||||
let socket = match Socket::new(Domain::for_address(addr), Type::STREAM, Some(protocol)) {
|
||||
Ok(sock) => sock,
|
||||
|
||||
Err(err) if matches!(mptcp, MpTcp::TcpFallback) => {
|
||||
tracing::warn!("binding socket as MPTCP failed: {err}");
|
||||
tracing::warn!("falling back to TCP");
|
||||
Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP))?
|
||||
}
|
||||
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
|
||||
socket.set_reuse_address(true)?;
|
||||
socket.set_nonblocking(true)?;
|
||||
@@ -248,7 +269,7 @@ mod tests {
|
||||
assert_eq!(format!("{}", addr), "127.0.0.1:8080");
|
||||
|
||||
let addr: StdSocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||
let lst = create_mio_tcp_listener(addr, 128).unwrap();
|
||||
let lst = create_mio_tcp_listener(addr, 128, &MpTcp::Disabled).unwrap();
|
||||
let lst = MioListener::Tcp(lst);
|
||||
assert!(format!("{:?}", lst).contains("TcpListener"));
|
||||
assert!(format!("{}", lst).contains("127.0.0.1"));
|
||||
|
@@ -117,7 +117,7 @@ impl TestServerHandle {
|
||||
|
||||
/// Stop server.
|
||||
fn stop(&mut self) {
|
||||
let _ = self.server_handle.stop(false);
|
||||
drop(self.server_handle.stop(false));
|
||||
self.thread_handle.take().unwrap().join().unwrap().unwrap();
|
||||
}
|
||||
|
||||
|
@@ -625,8 +625,8 @@ impl Future for ServerWorker {
|
||||
let factory_id = restart.factory_id;
|
||||
let token = restart.token;
|
||||
|
||||
let (token_new, service) = ready!(restart.fut.as_mut().poll(cx))
|
||||
.unwrap_or_else(|_| {
|
||||
let (token_new, service) =
|
||||
ready!(restart.fut.as_mut().poll(cx)).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Can not restart {:?} service",
|
||||
this.factories[factory_id].name(token)
|
||||
@@ -697,7 +697,10 @@ impl Future for ServerWorker {
|
||||
match ready!(this.conn_rx.poll_recv(cx)) {
|
||||
Some(msg) => {
|
||||
let guard = this.counter.guard();
|
||||
let _ = this.services[msg.token].service.call((guard, msg.io));
|
||||
let _ = this.services[msg.token]
|
||||
.service
|
||||
.call((guard, msg.io))
|
||||
.into_inner();
|
||||
}
|
||||
None => return Poll::Ready(()),
|
||||
};
|
||||
@@ -706,9 +709,7 @@ impl Future for ServerWorker {
|
||||
}
|
||||
}
|
||||
|
||||
fn wrap_worker_services(
|
||||
services: Vec<(usize, usize, BoxedServerService)>,
|
||||
) -> Vec<WorkerService> {
|
||||
fn wrap_worker_services(services: Vec<(usize, usize, BoxedServerService)>) -> Vec<WorkerService> {
|
||||
services
|
||||
.into_iter()
|
||||
.fold(Vec::new(), |mut services, (idx, token, service)| {
|
||||
|
@@ -1,3 +1,5 @@
|
||||
#![allow(clippy::let_underscore_future)]
|
||||
|
||||
use std::{
|
||||
net,
|
||||
sync::{
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 2.0.2 - 2021-12-18
|
||||
|
||||
|
@@ -10,11 +10,8 @@ keywords = ["network", "framework", "async", "futures", "service"]
|
||||
categories = ["network-programming", "asynchronous", "no-std"]
|
||||
repository = "https://github.com/actix/actix-net"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_service"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
futures-core = { version = "0.3.17", default-features = false }
|
||||
|
@@ -121,12 +121,7 @@ pub struct AndThenServiceFactory<A, B, Req>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
A::Config: Clone,
|
||||
B: ServiceFactory<
|
||||
A::Response,
|
||||
Config = A::Config,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
B: ServiceFactory<A::Response, Config = A::Config, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
inner: Rc<(A, B)>,
|
||||
_phantom: PhantomData<Req>,
|
||||
@@ -136,12 +131,7 @@ impl<A, B, Req> AndThenServiceFactory<A, B, Req>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
A::Config: Clone,
|
||||
B: ServiceFactory<
|
||||
A::Response,
|
||||
Config = A::Config,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
B: ServiceFactory<A::Response, Config = A::Config, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
/// Create new `AndThenFactory` combinator
|
||||
pub(crate) fn new(a: A, b: B) -> Self {
|
||||
@@ -156,12 +146,7 @@ impl<A, B, Req> ServiceFactory<Req> for AndThenServiceFactory<A, B, Req>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
A::Config: Clone,
|
||||
B: ServiceFactory<
|
||||
A::Response,
|
||||
Config = A::Config,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
B: ServiceFactory<A::Response, Config = A::Config, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
type Response = B::Response;
|
||||
type Error = A::Error;
|
||||
@@ -184,12 +169,7 @@ impl<A, B, Req> Clone for AndThenServiceFactory<A, B, Req>
|
||||
where
|
||||
A: ServiceFactory<Req>,
|
||||
A::Config: Clone,
|
||||
B: ServiceFactory<
|
||||
A::Response,
|
||||
Config = A::Config,
|
||||
Error = A::Error,
|
||||
InitError = A::InitError,
|
||||
>,
|
||||
B: ServiceFactory<A::Response, Config = A::Config, Error = A::Error, InitError = A::InitError>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
@@ -334,9 +314,8 @@ mod tests {
|
||||
async fn test_new_service() {
|
||||
let cnt = Rc::new(Cell::new(0));
|
||||
let cnt2 = cnt.clone();
|
||||
let new_srv =
|
||||
pipeline_factory(fn_factory(move || ready(Ok::<_, ()>(Srv1(cnt2.clone())))))
|
||||
.and_then(move || ready(Ok(Srv2(cnt.clone()))));
|
||||
let new_srv = pipeline_factory(fn_factory(move || ready(Ok::<_, ()>(Srv1(cnt2.clone())))))
|
||||
.and_then(move || ready(Ok(Srv2(cnt.clone()))));
|
||||
|
||||
let srv = new_srv.new_service(()).await.unwrap();
|
||||
let res = srv.call("srv1").await;
|
||||
|
@@ -140,8 +140,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<SF, F, Fut, Req, In, Res, Err> ServiceFactory<Req>
|
||||
for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
impl<SF, F, Fut, Req, In, Res, Err> ServiceFactory<Req> for ApplyFactory<SF, F, Req, In, Res, Err>
|
||||
where
|
||||
SF: ServiceFactory<In, Error = Err>,
|
||||
F: Fn(Req, &SF::Service) -> Fut + Clone,
|
||||
|
@@ -198,8 +198,7 @@ pin_project! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<SF, Req, F, Cfg, Fut, S> Future
|
||||
for ApplyConfigServiceFactoryResponse<SF, Req, F, Cfg, Fut, S>
|
||||
impl<SF, Req, F, Cfg, Fut, S> Future for ApplyConfigServiceFactoryResponse<SF, Req, F, Cfg, Fut, S>
|
||||
where
|
||||
SF: ServiceFactory<Req, Config = ()>,
|
||||
SF::InitError: From<SF::Error>,
|
||||
|
@@ -91,8 +91,7 @@ type Inner<C, Req, Res, Err, InitErr> = Box<
|
||||
>,
|
||||
>;
|
||||
|
||||
impl<C, Req, Res, Err, InitErr> ServiceFactory<Req>
|
||||
for BoxServiceFactory<C, Req, Res, Err, InitErr>
|
||||
impl<C, Req, Res, Err, InitErr> ServiceFactory<Req> for BoxServiceFactory<C, Req, Res, Err, InitErr>
|
||||
where
|
||||
Req: 'static,
|
||||
Res: 'static,
|
||||
|
@@ -3,9 +3,7 @@ use core::{future::Future, marker::PhantomData};
|
||||
use crate::{ok, IntoService, IntoServiceFactory, Ready, Service, ServiceFactory};
|
||||
|
||||
/// Create `ServiceFactory` for function that can act as a `Service`
|
||||
pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(
|
||||
f: F,
|
||||
) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
|
||||
pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(f: F) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
|
||||
where
|
||||
F: Fn(Req) -> Fut + Clone,
|
||||
Fut: Future<Output = Result<Res, Err>>,
|
||||
@@ -48,9 +46,7 @@ where
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(
|
||||
f: F,
|
||||
) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||
pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(f: F) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
|
||||
where
|
||||
F: Fn() -> Fut,
|
||||
Fut: Future<Output = Result<Srv, Err>>,
|
||||
@@ -265,8 +261,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, Fut, Cfg, Srv, Req, Err> ServiceFactory<Req>
|
||||
for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||
impl<F, Fut, Cfg, Srv, Req, Err> ServiceFactory<Req> for FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
|
||||
where
|
||||
F: Fn(Cfg) -> Fut,
|
||||
Fut: Future<Output = Result<Srv, Err>>,
|
||||
@@ -404,9 +399,8 @@ mod tests {
|
||||
ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8))))
|
||||
});
|
||||
|
||||
let fac_2 = fn_factory(|| {
|
||||
ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8))))
|
||||
});
|
||||
let fac_2 =
|
||||
fn_factory(|| ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8)))));
|
||||
|
||||
fn is_send<T: Send + Sync + Clone>(_: &T) {}
|
||||
|
||||
|
@@ -33,14 +33,16 @@ mod then;
|
||||
mod transform;
|
||||
mod transform_err;
|
||||
|
||||
pub use self::apply::{apply_fn, apply_fn_factory};
|
||||
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};
|
||||
#[allow(unused_imports)]
|
||||
use self::ready::{err, ok, ready, Ready};
|
||||
pub use self::transform::{apply, ApplyTransform, Transform};
|
||||
pub use self::{
|
||||
apply::{apply_fn, apply_fn_factory},
|
||||
apply_cfg::{apply_cfg, apply_cfg_factory},
|
||||
ext::{ServiceExt, ServiceFactoryExt, TransformExt},
|
||||
fn_service::{fn_factory, fn_factory_with_config, fn_service},
|
||||
map_config::{map_config, unit_config},
|
||||
transform::{apply, ApplyTransform, Transform},
|
||||
};
|
||||
|
||||
/// An asynchronous operation from `Request` to a `Response`.
|
||||
///
|
||||
|
@@ -206,8 +206,7 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
err, ok, IntoServiceFactory, Ready, Service, ServiceExt, ServiceFactory,
|
||||
ServiceFactoryExt,
|
||||
err, ok, IntoServiceFactory, Ready, Service, ServiceExt, ServiceFactory, ServiceFactoryExt,
|
||||
};
|
||||
|
||||
struct Srv;
|
||||
|
@@ -6,12 +6,14 @@ use core::{
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use crate::and_then::{AndThenService, AndThenServiceFactory};
|
||||
use crate::map::{Map, MapServiceFactory};
|
||||
use crate::map_err::{MapErr, MapErrServiceFactory};
|
||||
use crate::map_init_err::MapInitErr;
|
||||
use crate::then::{ThenService, ThenServiceFactory};
|
||||
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||
use crate::{
|
||||
and_then::{AndThenService, AndThenServiceFactory},
|
||||
map::{Map, MapServiceFactory},
|
||||
map_err::{MapErr, MapErrServiceFactory},
|
||||
map_init_err::MapInitErr,
|
||||
then::{ThenService, ThenServiceFactory},
|
||||
IntoService, IntoServiceFactory, Service, ServiceFactory,
|
||||
};
|
||||
|
||||
/// Construct new pipeline with one service in pipeline chain.
|
||||
pub(crate) fn pipeline<I, S, Req>(service: I) -> Pipeline<S, Req>
|
||||
@@ -252,10 +254,7 @@ where
|
||||
}
|
||||
|
||||
/// Map this service's error to a different error, returning a new service.
|
||||
pub fn map_err<F, E>(
|
||||
self,
|
||||
f: F,
|
||||
) -> PipelineFactory<MapErrServiceFactory<SF, Req, F, E>, Req>
|
||||
pub fn map_err<F, E>(self, f: F) -> PipelineFactory<MapErrServiceFactory<SF, Req, F, E>, Req>
|
||||
where
|
||||
Self: Sized,
|
||||
F: Fn(SF::Error) -> E + Clone,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 3.0.4 - 2022-03-15
|
||||
|
||||
|
@@ -10,16 +10,13 @@ keywords = ["network", "tls", "ssl", "async", "transport"]
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
categories = ["network-programming", "asynchronous", "cryptography"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[lib]
|
||||
name = "actix_tls"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[features]
|
||||
default = ["accept", "connect"]
|
||||
|
||||
@@ -42,14 +39,14 @@ native-tls = ["tokio-native-tls"]
|
||||
uri = ["http"]
|
||||
|
||||
[dependencies]
|
||||
actix-rt = { version = "2.2.0", default-features = false }
|
||||
actix-rt = { version = "2.2", default-features = false }
|
||||
actix-service = "2"
|
||||
actix-utils = "3"
|
||||
|
||||
futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] }
|
||||
impl-more = "0.1"
|
||||
pin-project-lite = "0.2.7"
|
||||
tokio = "1.18.4"
|
||||
tokio = "1.23.1"
|
||||
tokio-util = "0.7"
|
||||
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
|
||||
|
||||
@@ -57,7 +54,7 @@ tracing = { version = "0.1.30", default-features = false, features = ["log"] }
|
||||
http = { version = "0.2.3", optional = true }
|
||||
|
||||
# openssl
|
||||
tls-openssl = { package = "openssl", version = "0.10.9", optional = true }
|
||||
tls-openssl = { package = "openssl", version = "0.10.48", optional = true }
|
||||
tokio-openssl = { version = "0.6", optional = true }
|
||||
|
||||
# rustls
|
||||
|
@@ -21,7 +21,6 @@
|
||||
use tokio_rustls::rustls;
|
||||
|
||||
use std::{
|
||||
env,
|
||||
fs::File,
|
||||
io::{self, BufReader},
|
||||
sync::{
|
||||
|
@@ -10,15 +10,12 @@ use std::{
|
||||
use actix_utils::counter::Counter;
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "openssl")))]
|
||||
pub mod openssl;
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
|
||||
pub mod rustls;
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))]
|
||||
pub mod native_tls;
|
||||
|
||||
pub(crate) static MAX_CONN: AtomicUsize = AtomicUsize::new(256);
|
||||
@@ -59,6 +56,25 @@ pub enum TlsError<TlsErr, SvcErr> {
|
||||
Service(SvcErr),
|
||||
}
|
||||
|
||||
impl<TlsErr> TlsError<TlsErr, Infallible> {
|
||||
/// Casts the infallible service error type returned from acceptors into caller's type.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::convert::Infallible;
|
||||
/// # use actix_tls::accept::TlsError;
|
||||
/// let a: TlsError<u32, Infallible> = TlsError::Tls(42);
|
||||
/// let _b: TlsError<u32, u64> = a.into_service_error();
|
||||
/// ```
|
||||
pub fn into_service_error<SvcErr>(self) -> TlsError<TlsErr, SvcErr> {
|
||||
match self {
|
||||
Self::Timeout => TlsError::Timeout,
|
||||
Self::Tls(err) => TlsError::Tls(err),
|
||||
Self::Service(err) => match err {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TlsErr, SvcErr> fmt::Display for TlsError<TlsErr, SvcErr> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
@@ -83,25 +99,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TlsErr> TlsError<TlsErr, Infallible> {
|
||||
/// Casts the infallible service error type returned from acceptors into caller's type.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// # use std::convert::Infallible;
|
||||
/// # use actix_tls::accept::TlsError;
|
||||
/// let a: TlsError<u32, Infallible> = TlsError::Tls(42);
|
||||
/// let _b: TlsError<u32, u64> = a.into_service_error();
|
||||
/// ```
|
||||
pub fn into_service_error<SvcErr>(self) -> TlsError<TlsErr, SvcErr> {
|
||||
match self {
|
||||
Self::Timeout => TlsError::Timeout,
|
||||
Self::Tls(err) => TlsError::Tls(err),
|
||||
Self::Service(err) => match err {},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@@ -73,17 +73,17 @@ impl<IO: ActixStream> AsyncWrite for TlsStream<IO> {
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
(&**self).is_write_vectored()
|
||||
(**self).is_write_vectored()
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: ActixStream> ActixStream for TlsStream<IO> {
|
||||
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_read_ready((&**self).get_ref().get_ref().get_ref(), cx)
|
||||
IO::poll_read_ready((**self).get_ref().get_ref().get_ref(), cx)
|
||||
}
|
||||
|
||||
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_write_ready((&**self).get_ref().get_ref().get_ref(), cx)
|
||||
IO::poll_write_ready((**self).get_ref().get_ref().get_ref(), cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -76,17 +76,17 @@ impl<IO: ActixStream> AsyncWrite for TlsStream<IO> {
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
(&**self).is_write_vectored()
|
||||
(**self).is_write_vectored()
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: ActixStream> ActixStream for TlsStream<IO> {
|
||||
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_read_ready((&**self).get_ref(), cx)
|
||||
IO::poll_read_ready((**self).get_ref(), cx)
|
||||
}
|
||||
|
||||
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_write_ready((&**self).get_ref(), cx)
|
||||
IO::poll_write_ready((**self).get_ref(), cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -23,8 +23,7 @@ use actix_utils::{
|
||||
};
|
||||
use pin_project_lite::pin_project;
|
||||
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||
use tokio_rustls::rustls::ServerConfig;
|
||||
use tokio_rustls::{Accept, TlsAcceptor};
|
||||
use tokio_rustls::{rustls::ServerConfig, Accept, TlsAcceptor};
|
||||
|
||||
use super::{TlsError, DEFAULT_TLS_HANDSHAKE_TIMEOUT, MAX_CONN_COUNTER};
|
||||
|
||||
@@ -76,17 +75,17 @@ impl<IO: ActixStream> AsyncWrite for TlsStream<IO> {
|
||||
}
|
||||
|
||||
fn is_write_vectored(&self) -> bool {
|
||||
(&**self).is_write_vectored()
|
||||
(**self).is_write_vectored()
|
||||
}
|
||||
}
|
||||
|
||||
impl<IO: ActixStream> ActixStream for TlsStream<IO> {
|
||||
fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_read_ready((&**self).get_ref().0, cx)
|
||||
IO::poll_read_ready((**self).get_ref().0, cx)
|
||||
}
|
||||
|
||||
fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
|
||||
IO::poll_write_ready((&**self).get_ref().0, cx)
|
||||
IO::poll_write_ready((**self).get_ref().0, cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,25 +22,23 @@ mod resolver;
|
||||
pub mod tcp;
|
||||
|
||||
#[cfg(feature = "uri")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "uri")))]
|
||||
mod uri;
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "openssl")))]
|
||||
pub mod openssl;
|
||||
|
||||
#[cfg(feature = "rustls")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
|
||||
pub mod rustls;
|
||||
|
||||
#[cfg(feature = "native-tls")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "native-tls")))]
|
||||
pub mod native_tls;
|
||||
|
||||
pub use self::connection::Connection;
|
||||
pub use self::connector::{Connector, ConnectorService};
|
||||
pub use self::error::ConnectError;
|
||||
pub use self::host::Host;
|
||||
pub use self::info::ConnectInfo;
|
||||
pub use self::resolve::Resolve;
|
||||
pub use self::resolver::{Resolver, ResolverService};
|
||||
pub use self::{
|
||||
connection::Connection,
|
||||
connector::{Connector, ConnectorService},
|
||||
error::ConnectError,
|
||||
host::Host,
|
||||
info::ConnectInfo,
|
||||
resolve::Resolve,
|
||||
resolver::{Resolver, ResolverService},
|
||||
};
|
||||
|
@@ -19,8 +19,7 @@ use crate::connect::{Connection, Host};
|
||||
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;
|
||||
pub use tokio_native_tls::{native_tls::TlsConnector, TlsStream as AsyncTlsStream};
|
||||
}
|
||||
|
||||
/// Connector service and factory using `native-tls`.
|
||||
|
@@ -22,9 +22,7 @@ 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, SslConnectorBuilder, SslMethod,
|
||||
};
|
||||
pub use openssl::ssl::{Error, HandshakeError, SslConnector, SslConnectorBuilder, SslMethod};
|
||||
pub use tokio_openssl::SslStream as AsyncSslStream;
|
||||
}
|
||||
|
||||
|
@@ -15,9 +15,11 @@ use actix_rt::net::ActixStream;
|
||||
use actix_service::{Service, ServiceFactory};
|
||||
use actix_utils::future::{ok, Ready};
|
||||
use futures_core::ready;
|
||||
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 tokio_rustls::{
|
||||
client::TlsStream as AsyncTlsStream,
|
||||
rustls::{client::ServerName, ClientConfig, OwnedTrustAnchor, RootCertStore},
|
||||
Connect as RustlsConnect, TlsConnector as RustlsTlsConnector,
|
||||
};
|
||||
use tracing::trace;
|
||||
use webpki_roots::TLS_SERVER_ROOTS;
|
||||
|
||||
@@ -26,8 +28,7 @@ use crate::connect::{Connection, Host};
|
||||
pub mod reexports {
|
||||
//! Re-exports from `rustls` and `webpki_roots` that are useful for connectors.
|
||||
|
||||
pub use tokio_rustls::client::TlsStream as AsyncTlsStream;
|
||||
pub use tokio_rustls::rustls::ClientConfig;
|
||||
pub use tokio_rustls::{client::TlsStream as AsyncTlsStream, rustls::ClientConfig};
|
||||
pub use webpki_roots::TLS_SERVER_ROOTS;
|
||||
}
|
||||
|
||||
|
@@ -4,17 +4,14 @@
|
||||
#![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_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
#[cfg(feature = "openssl")]
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate tls_openssl as openssl;
|
||||
|
||||
#[cfg(feature = "accept")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "accept")))]
|
||||
pub mod accept;
|
||||
|
||||
#[cfg(feature = "connect")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "connect")))]
|
||||
pub mod connect;
|
||||
|
@@ -17,11 +17,9 @@ use actix_utils::future::ok;
|
||||
use tokio_rustls::rustls::{Certificate, ClientConfig, RootCertStore, ServerName};
|
||||
|
||||
fn new_cert_and_key() -> (String, String) {
|
||||
let cert = rcgen::generate_simple_self_signed(vec![
|
||||
"127.0.0.1".to_owned(),
|
||||
"localhost".to_owned(),
|
||||
])
|
||||
.unwrap();
|
||||
let cert =
|
||||
rcgen::generate_simple_self_signed(vec!["127.0.0.1".to_owned(), "localhost".to_owned()])
|
||||
.unwrap();
|
||||
|
||||
let key = cert.serialize_private_key_pem();
|
||||
let cert = cert.serialize_pem().unwrap();
|
||||
|
@@ -14,19 +14,19 @@ use std::io::{BufReader, Write};
|
||||
use actix_rt::net::TcpStream;
|
||||
use actix_server::TestServer;
|
||||
use actix_service::ServiceFactoryExt as _;
|
||||
use actix_tls::accept::rustls::{Acceptor, TlsStream};
|
||||
use actix_tls::connect::openssl::reexports::SslConnector;
|
||||
use actix_tls::{
|
||||
accept::rustls::{Acceptor, TlsStream},
|
||||
connect::openssl::reexports::SslConnector,
|
||||
};
|
||||
use actix_utils::future::ok;
|
||||
use rustls_pemfile::{certs, pkcs8_private_keys};
|
||||
use tls_openssl::ssl::SslVerifyMode;
|
||||
use tokio_rustls::rustls::{self, Certificate, PrivateKey, ServerConfig};
|
||||
|
||||
fn new_cert_and_key() -> (String, String) {
|
||||
let cert = rcgen::generate_simple_self_signed(vec![
|
||||
"127.0.0.1".to_owned(),
|
||||
"localhost".to_owned(),
|
||||
])
|
||||
.unwrap();
|
||||
let cert =
|
||||
rcgen::generate_simple_self_signed(vec!["127.0.0.1".to_owned(), "localhost".to_owned()])
|
||||
.unwrap();
|
||||
|
||||
let key = cert.serialize_private_key_pem();
|
||||
let cert = cert.serialize_pem().unwrap();
|
||||
|
@@ -51,8 +51,7 @@ async fn custom_resolver_connect() {
|
||||
|
||||
use trust_dns_resolver::TokioAsyncResolver;
|
||||
|
||||
let srv =
|
||||
TestServer::start(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
|
||||
let srv = TestServer::start(|| fn_service(|_io: TcpStream| async { Ok::<_, io::Error>(()) }));
|
||||
|
||||
struct MyResolver {
|
||||
trust_dns: TokioAsyncResolver,
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 0.1.0 - 2020-01-15
|
||||
|
||||
|
@@ -9,11 +9,8 @@ repository = "https://github.com/actix/actix-net.git"
|
||||
documentation = "https://docs.rs/actix-tracing"
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_tracing"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
actix-service = "2"
|
||||
|
@@ -118,9 +118,11 @@ where
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use actix_service::{fn_factory, fn_service};
|
||||
use slab::Slab;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 3.0.1 - 2022-10-21
|
||||
|
||||
|
@@ -10,11 +10,8 @@ keywords = ["network", "framework", "async", "futures"]
|
||||
categories = ["network-programming", "asynchronous"]
|
||||
repository = "https://github.com/actix/actix-net"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "actix_utils"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
pin-project-lite = "0.2"
|
||||
|
@@ -4,6 +4,8 @@ mod either;
|
||||
mod poll_fn;
|
||||
mod ready;
|
||||
|
||||
pub use self::either::Either;
|
||||
pub use self::poll_fn::{poll_fn, PollFn};
|
||||
pub use self::ready::{err, ok, ready, Ready};
|
||||
pub use self::{
|
||||
either::Either,
|
||||
poll_fn::{poll_fn, PollFn},
|
||||
ready::{err, ok, ready, Ready},
|
||||
};
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
## 1.3.0 - 2023-03-03
|
||||
|
||||
|
@@ -11,11 +11,8 @@ categories = ["no-std", "web-programming"]
|
||||
homepage = "https://actix.rs"
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "bytestring"
|
||||
path = "src/lib.rs"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bytes = { version = "1.2", default-features = false }
|
||||
|
@@ -11,7 +11,7 @@ use alloc::{
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
};
|
||||
use core::{borrow, convert::TryFrom, fmt, hash, ops, str};
|
||||
use core::{borrow::Borrow, convert::TryFrom, fmt, hash, ops, str};
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
@@ -132,13 +132,12 @@ impl ops::Deref for ByteString {
|
||||
#[inline]
|
||||
fn deref(&self) -> &str {
|
||||
let bytes = self.0.as_ref();
|
||||
// SAFETY:
|
||||
// UTF-8 validity is guaranteed at during construction.
|
||||
// SAFETY: UTF-8 validity is guaranteed during construction.
|
||||
unsafe { str::from_utf8_unchecked(bytes) }
|
||||
}
|
||||
}
|
||||
|
||||
impl borrow::Borrow<str> for ByteString {
|
||||
impl Borrow<str> for ByteString {
|
||||
fn borrow(&self) -> &str {
|
||||
self
|
||||
}
|
||||
@@ -254,8 +253,10 @@ impl fmt::Display for ByteString {
|
||||
mod serde {
|
||||
use alloc::string::String;
|
||||
|
||||
use serde::de::{Deserialize, Deserializer};
|
||||
use serde::ser::{Serialize, Serializer};
|
||||
use serde::{
|
||||
de::{Deserialize, Deserializer},
|
||||
ser::{Serialize, Serializer},
|
||||
};
|
||||
|
||||
use super::ByteString;
|
||||
|
||||
@@ -292,7 +293,7 @@ mod serde {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use alloc::borrow::ToOwned;
|
||||
use alloc::{borrow::ToOwned, format, vec};
|
||||
use core::{
|
||||
hash::{Hash, Hasher},
|
||||
panic::{RefUnwindSafe, UnwindSafe},
|
||||
@@ -309,7 +310,7 @@ mod test {
|
||||
assert_impl_all!(ByteString: UnwindSafe, RefUnwindSafe);
|
||||
|
||||
#[test]
|
||||
fn test_partial_eq() {
|
||||
fn eq() {
|
||||
let s: ByteString = ByteString::from_static("test");
|
||||
assert_eq!(s, "test");
|
||||
assert_eq!(s, *"test");
|
||||
@@ -317,12 +318,45 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
fn new() {
|
||||
let _: ByteString = ByteString::new();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hash() {
|
||||
fn as_bytes() {
|
||||
let buf = ByteString::new();
|
||||
assert!(buf.as_bytes().is_empty());
|
||||
|
||||
let buf = ByteString::from("hello");
|
||||
assert_eq!(buf.as_bytes(), "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_bytes_unchecked() {
|
||||
let buf = unsafe { ByteString::from_bytes_unchecked(Bytes::new()) };
|
||||
assert!(buf.is_empty());
|
||||
|
||||
let buf = unsafe { ByteString::from_bytes_unchecked(Bytes::from("hello")) };
|
||||
assert_eq!(buf, "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn as_ref() {
|
||||
let buf = ByteString::new();
|
||||
|
||||
let _: &ByteString = buf.as_ref();
|
||||
let _: &[u8] = buf.as_ref();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrow() {
|
||||
let buf = ByteString::new();
|
||||
|
||||
let _: &str = buf.borrow();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash() {
|
||||
let mut hasher1 = AHasher::default();
|
||||
"str".hash(&mut hasher1);
|
||||
|
||||
@@ -333,7 +367,7 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_string() {
|
||||
fn from_string() {
|
||||
let s: ByteString = "hello".to_owned().into();
|
||||
assert_eq!(&s, "hello");
|
||||
let t: &str = s.as_ref();
|
||||
@@ -341,23 +375,30 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
fn from_str() {
|
||||
let _: ByteString = "str".into();
|
||||
let _: ByteString = "str".to_owned().into_boxed_str().into();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_static_str() {
|
||||
fn to_string() {
|
||||
let buf = ByteString::from("foo");
|
||||
assert_eq!(String::from(buf), "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_static_str() {
|
||||
static _S: ByteString = ByteString::from_static("hello");
|
||||
let _ = ByteString::from_static("str");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_slice() {
|
||||
fn try_from_slice() {
|
||||
let _ = ByteString::try_from(b"nice bytes").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_array() {
|
||||
fn try_from_array() {
|
||||
assert_eq!(
|
||||
ByteString::try_from([b'h', b'i']).unwrap(),
|
||||
ByteString::from_static("hi")
|
||||
@@ -365,25 +406,43 @@ mod test {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_bytes() {
|
||||
fn try_from_vec() {
|
||||
let _ = ByteString::try_from(vec![b'f', b'o', b'o']).unwrap();
|
||||
ByteString::try_from(vec![0, 159, 146, 150]).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_from_bytes() {
|
||||
let _ = ByteString::try_from(Bytes::from_static(b"nice bytes")).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_from_bytes_mut() {
|
||||
fn try_from_bytes_mut() {
|
||||
let _ = ByteString::try_from(bytes::BytesMut::from(&b"nice bytes"[..])).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display() {
|
||||
let buf = ByteString::from("bar");
|
||||
assert_eq!(format!("{buf}"), "bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn debug() {
|
||||
let buf = ByteString::from("baz");
|
||||
assert_eq!(format!("{buf:?}"), r#""baz""#);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_serialize() {
|
||||
fn serialize() {
|
||||
let s: ByteString = serde_json::from_str(r#""nice bytes""#).unwrap();
|
||||
assert_eq!(s, "nice bytes");
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_deserialize() {
|
||||
fn deserialize() {
|
||||
let s = serde_json::to_string(&ByteString::from_static("nice bytes")).unwrap();
|
||||
assert_eq!(s, r#""nice bytes""#);
|
||||
}
|
||||
@@ -399,7 +458,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_slice_ref_catches_not_a_subset() {
|
||||
fn slice_ref_catches_not_a_subset() {
|
||||
// panics because the given slice is not derived from the original byte string, despite
|
||||
// being a logical subset of the string
|
||||
ByteString::from_static("foo bar").slice_ref("foo");
|
||||
|
@@ -1 +0,0 @@
|
||||
msrv = "1.59"
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 0.1.3 - 2022-05-03
|
||||
|
||||
|
@@ -9,7 +9,8 @@ authors = [
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
keywords = ["channel", "local", "futures"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
futures-core = "0.3.17"
|
||||
@@ -18,4 +19,4 @@ futures-util = { version = "0.3.17", default-features = false }
|
||||
local-waker = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.18.4", features = ["rt", "macros"] }
|
||||
tokio = { version = "1.23.1", features = ["rt", "macros"] }
|
||||
|
@@ -1,8 +1,8 @@
|
||||
# Changes
|
||||
|
||||
## Unreleased - 2022-xx-xx
|
||||
## Unreleased - 2023-xx-xx
|
||||
|
||||
- Minimum supported Rust version (MSRV) is now 1.59.
|
||||
- Minimum supported Rust version (MSRV) is now 1.65.
|
||||
|
||||
## 0.1.3 - 2022-05-03
|
||||
|
||||
|
@@ -10,6 +10,7 @@ repository = "https://github.com/actix/actix-net.git"
|
||||
keywords = ["waker", "local", "futures", "no-std"]
|
||||
categories = ["asynchronous", "no-std"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2018"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
|
@@ -1,2 +0,0 @@
|
||||
max_width = 96
|
||||
group_imports = "StdExternalCrate"
|
Reference in New Issue
Block a user