1
0
mirror of https://github.com/fafhrd91/actix-net synced 2025-09-03 00:46:38 +02:00

Compare commits

..

50 Commits

Author SHA1 Message Date
Rob Ede
e67d4521e5 parse v1 header from tcpstream 2025-08-29 04:32:49 +01:00
Rob Ede
567e9ad2ca add no-op SSL TLV 2025-08-29 01:03:02 +01:00
Rob Ede
d78e238415 add alpn and authority TLVs 2025-08-29 01:03:02 +01:00
Rob Ede
26a28606d3 add some typed TLVs 2025-08-29 01:03:02 +01:00
Rob Ede
2daf68dc49 add Tlv trait 2025-08-29 01:03:02 +01:00
Rob Ede
4d4367f5f2 PoC proxy protocol stream wrapper 2025-08-29 01:03:02 +01:00
Rob Ede
b8ff2a47a6 refactor: inline format args 2025-08-29 00:57:13 +01:00
dependabot[bot]
160fdc5efc build(deps): bump codecov/codecov-action from 5.4.3 to 5.5.0 (#721)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rob Ede <robjtede@icloud.com>
2025-08-26 16:39:21 +01:00
dependabot[bot]
c856fcdcd5 build(deps): bump actions-rust-lang/setup-rust-toolchain (#720)
Bumps [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) from 1.13.0 to 1.14.0.
- [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases)
- [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1.13.0...v1.14.0)

---
updated-dependencies:
- dependency-name: actions-rust-lang/setup-rust-toolchain
  dependency-version: 1.14.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 10:24:07 +00:00
dependabot[bot]
4ee45b24b5 build(deps): bump taiki-e/install-action from 2.58.17 to 2.58.21 (#719)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.58.17 to 2.58.21.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.58.17...v2.58.21)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.58.21
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 10:24:05 +00:00
dependabot[bot]
43f9da3c4e build(deps): bump bitflags from 2.9.2 to 2.9.3 (#718)
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.2 to 2.9.3.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.2...2.9.3)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 10:24:02 +00:00
dependabot[bot]
d24e5b4e95 build(deps): bump serde_json from 1.0.142 to 1.0.143 (#717)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.142 to 1.0.143.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.142...v1.0.143)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.143
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 10:24:01 +00:00
Rob Ede
0d45bf9b43 chore: revert msrv bump 2025-08-26 08:25:35 +01:00
dependabot[bot]
e85ae87b98 build(deps): bump bitflags from 2.9.1 to 2.9.2 (#712)
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.1 to 2.9.2.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.1...2.9.2)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 07:33:13 +00:00
dependabot[bot]
dc19b196da build(deps): bump proc-macro2 from 1.0.95 to 1.0.101 (#713)
Bumps [proc-macro2](https://github.com/dtolnay/proc-macro2) from 1.0.95 to 1.0.101.
- [Release notes](https://github.com/dtolnay/proc-macro2/releases)
- [Commits](https://github.com/dtolnay/proc-macro2/compare/1.0.95...1.0.101)

---
updated-dependencies:
- dependency-name: proc-macro2
  dependency-version: 1.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 07:16:22 +00:00
dependabot[bot]
e22bca03d5 build(deps): bump syn from 2.0.104 to 2.0.106 (#714)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.104 to 2.0.106.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.104...2.0.106)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.106
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 06:11:14 +00:00
dependabot[bot]
19ab9cc97a build(deps): bump taiki-e/install-action from 2.58.9 to 2.58.17 (#715)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.58.9 to 2.58.17.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.58.9...v2.58.17)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.58.17
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-22 06:00:47 +00:00
Yuki Okushi
1ea0f773b6 chore: Bump up MSRV to 1.80 (#716) 2025-08-22 11:53:32 +09:00
dependabot[bot]
ee3d54f574 build(deps): bump tokio-util from 0.7.15 to 0.7.16 (#704)
Bumps [tokio-util](https://github.com/tokio-rs/tokio) from 0.7.15 to 0.7.16.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-util-0.7.15...tokio-util-0.7.16)

---
updated-dependencies:
- dependency-name: tokio-util
  dependency-version: 0.7.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:29:11 +00:00
dependabot[bot]
75e56d56d8 build(deps): bump tokio from 1.46.1 to 1.47.1 (#706)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.46.1 to 1.47.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.46.1...tokio-1.47.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.47.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:29:00 +00:00
dependabot[bot]
222527a407 build(deps): bump actions/checkout from 4 to 5 (#707)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:58 +00:00
dependabot[bot]
cfddd3ea2e build(deps): bump serde_json from 1.0.141 to 1.0.142 (#708)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.141 to 1.0.142.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.141...v1.0.142)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.142
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:56 +00:00
dependabot[bot]
d869455251 build(deps): bump trybuild from 1.0.106 to 1.0.110 (#709)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.106 to 1.0.110.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.106...1.0.110)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-version: 1.0.110
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:54 +00:00
dependabot[bot]
3e925d8f80 build(deps): bump slab from 0.4.10 to 0.4.11 (#710)
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.10 to 0.4.11.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.10...v0.4.11)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:52 +00:00
dependabot[bot]
0c8337f1c9 build(deps): bump taiki-e/install-action from 2.56.19 to 2.58.9 (#711)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.56.19 to 2.58.9.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.56.19...v2.58.9)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.58.9
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:51 +00:00
dependabot[bot]
20ae763da8 build(deps): bump taiki-e/cache-cargo-install-action from 2.2.0 to 2.3.0 (#705)
Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 2.2.0 to 2.3.0.
- [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases)
- [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v2.2.0...v2.3.0)

---
updated-dependencies:
- dependency-name: taiki-e/cache-cargo-install-action
  dependency-version: 2.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 05:28:45 +00:00
dependabot[bot]
6c6f7f19f5 build(deps): bump taiki-e/install-action from 2.56.13 to 2.56.19 (#701)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.56.13 to 2.56.19.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.56.13...v2.56.19)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.56.19
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-10 05:39:25 +00:00
dependabot[bot]
95d569d8d7 build(deps): bump serde_json from 1.0.140 to 1.0.141 (#702)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.140 to 1.0.141.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.140...v1.0.141)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.141
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-10 05:39:12 +00:00
dependabot[bot]
347fc17035 build(deps): bump trybuild from 1.0.105 to 1.0.106 (#700)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.105 to 1.0.106.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.105...1.0.106)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-version: 1.0.106
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-15 03:39:14 +00:00
dependabot[bot]
4cb04042f5 build(deps): bump taiki-e/install-action from 2.56.7 to 2.56.13 (#699)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.56.7 to 2.56.13.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.56.7...v2.56.13)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.56.13
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-15 03:39:11 +00:00
Thomas de Zeeuw
e6ddf0ccff Update to socket2 v0.6 (#696) 2025-07-14 01:13:23 +00:00
dependabot[bot]
21de88385e build(deps): bump taiki-e/install-action from 2.55.1 to 2.56.7 (#697)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.55.1 to 2.56.7.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.55.1...v2.56.7)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.56.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 08:09:41 +00:00
dependabot[bot]
a91bdcb80c build(deps): bump tokio from 1.45.1 to 1.46.1 (#698)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.1 to 1.46.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.1...tokio-1.46.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.46.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-10 08:09:32 +00:00
dependabot[bot]
64a2d1c1eb build(deps): bump syn from 2.0.103 to 2.0.104 (#692)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.103 to 2.0.104.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.103...2.0.104)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.104
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 23:09:03 +00:00
dependabot[bot]
637bd709ae build(deps): bump taiki-e/install-action from 2.54.0 to 2.55.1 (#695)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.54.0 to 2.55.1.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.54.0...v2.55.1)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.55.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 21:51:44 +00:00
dependabot[bot]
bbac996677 build(deps): bump taiki-e/cache-cargo-install-action from 2.1.2 to 2.2.0 (#694)
Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 2.1.2 to 2.2.0.
- [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases)
- [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v2.1.2...v2.2.0)

---
updated-dependencies:
- dependency-name: taiki-e/cache-cargo-install-action
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-30 21:44:21 +00:00
dependabot[bot]
c9cea86445 build(deps): bump actions-rust-lang/setup-rust-toolchain (#691)
Bumps [actions-rust-lang/setup-rust-toolchain](https://github.com/actions-rust-lang/setup-rust-toolchain) from 1.12.0 to 1.13.0.
- [Release notes](https://github.com/actions-rust-lang/setup-rust-toolchain/releases)
- [Changelog](https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions-rust-lang/setup-rust-toolchain/compare/v1.12.0...v1.13.0)

---
updated-dependencies:
- dependency-name: actions-rust-lang/setup-rust-toolchain
  dependency-version: 1.13.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-28 13:57:32 +00:00
dependabot[bot]
05065186ff build(deps): bump taiki-e/cache-cargo-install-action from 2.1.1 to 2.1.2 (#693)
Bumps [taiki-e/cache-cargo-install-action](https://github.com/taiki-e/cache-cargo-install-action) from 2.1.1 to 2.1.2.
- [Release notes](https://github.com/taiki-e/cache-cargo-install-action/releases)
- [Changelog](https://github.com/taiki-e/cache-cargo-install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/cache-cargo-install-action/compare/v2.1.1...v2.1.2)

---
updated-dependencies:
- dependency-name: taiki-e/cache-cargo-install-action
  dependency-version: 2.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-28 13:57:10 +00:00
dependabot[bot]
3d54a00d5b build(deps): bump memchr from 2.7.4 to 2.7.5 (#690)
Bumps [memchr](https://github.com/BurntSushi/memchr) from 2.7.4 to 2.7.5.
- [Commits](https://github.com/BurntSushi/memchr/compare/2.7.4...2.7.5)

---
updated-dependencies:
- dependency-name: memchr
  dependency-version: 2.7.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 10:26:10 +00:00
dependabot[bot]
120e0206eb build(deps): bump syn from 2.0.101 to 2.0.103 (#689)
Bumps [syn](https://github.com/dtolnay/syn) from 2.0.101 to 2.0.103.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.101...2.0.103)

---
updated-dependencies:
- dependency-name: syn
  dependency-version: 2.0.103
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 10:26:06 +00:00
dependabot[bot]
1ad8a98f1b build(deps): bump slab from 0.4.9 to 0.4.10 (#688)
Bumps [slab](https://github.com/tokio-rs/slab) from 0.4.9 to 0.4.10.
- [Release notes](https://github.com/tokio-rs/slab/releases)
- [Changelog](https://github.com/tokio-rs/slab/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/slab/compare/v0.4.9...v0.4.10)

---
updated-dependencies:
- dependency-name: slab
  dependency-version: 0.4.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-23 10:25:58 +00:00
dependabot[bot]
da1c0024f0 build(deps): bump taiki-e/install-action from 2.52.7 to 2.54.0 (#687)
* build(deps): bump taiki-e/install-action from 2.52.7 to 2.53.0

Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.52.7 to 2.53.0.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.52.7...v2.53.0)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.53.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Apply suggestions from code review

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Yuki Okushi <jtitor@2k36.org>
2025-06-23 09:58:14 +00:00
dependabot[bot]
0be1dd8156 build(deps): bump mio from 1.0.3 to 1.0.4 (#682)
Bumps [mio](https://github.com/tokio-rs/mio) from 1.0.3 to 1.0.4.
- [Release notes](https://github.com/tokio-rs/mio/releases)
- [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/mio/commits)

---
updated-dependencies:
- dependency-name: mio
  dependency-version: 1.0.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 02:51:56 +00:00
dependabot[bot]
9c646e4998 build(deps): bump tokio from 1.45.0 to 1.45.1 (#681)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.45.0 to 1.45.1.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.45.0...tokio-1.45.1)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.45.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 02:51:52 +00:00
dependabot[bot]
758c37b80c build(deps): bump taiki-e/install-action from 2.51.2 to 2.52.7 (#686)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.51.2 to 2.52.7.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.51.2...v2.52.7)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.52.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-12 02:38:15 +00:00
dependabot[bot]
1a1af68bf0 build(deps): bump socket2 from 0.5.9 to 0.5.10 (#683)
Bumps [socket2](https://github.com/rust-lang/socket2) from 0.5.9 to 0.5.10.
- [Release notes](https://github.com/rust-lang/socket2/releases)
- [Changelog](https://github.com/rust-lang/socket2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/socket2/commits)

---
updated-dependencies:
- dependency-name: socket2
  dependency-version: 0.5.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-02 09:38:20 +00:00
dependabot[bot]
3ebed4701d build(deps): bump codecov/codecov-action from 5.4.2 to 5.4.3 (#678)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5.4.2 to 5.4.3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v5.4.2...v5.4.3)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: 5.4.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 07:19:37 +00:00
dependabot[bot]
15c13c3e32 build(deps): bump taiki-e/install-action from 2.50.10 to 2.51.2 (#679)
Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.50.10 to 2.51.2.
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/taiki-e/install-action/compare/v2.50.10...v2.51.2)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.51.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 07:19:30 +00:00
dependabot[bot]
3356038c80 build(deps): bump bitflags from 2.9.0 to 2.9.1 (#680)
Bumps [bitflags](https://github.com/bitflags/bitflags) from 2.9.0 to 2.9.1.
- [Release notes](https://github.com/bitflags/bitflags/releases)
- [Changelog](https://github.com/bitflags/bitflags/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bitflags/bitflags/compare/2.9.0...2.9.1)

---
updated-dependencies:
- dependency-name: bitflags
  dependency-version: 2.9.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-24 07:19:22 +00:00
dependabot[bot]
7834d76d4f build(deps): bump trybuild from 1.0.104 to 1.0.105 (#677)
Bumps [trybuild](https://github.com/dtolnay/trybuild) from 1.0.104 to 1.0.105.
- [Release notes](https://github.com/dtolnay/trybuild/releases)
- [Commits](https://github.com/dtolnay/trybuild/compare/1.0.104...1.0.105)

---
updated-dependencies:
- dependency-name: trybuild
  dependency-version: 1.0.105
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-16 07:16:02 +00:00
48 changed files with 1670 additions and 297 deletions

4
.clippy.toml Normal file
View File

@@ -0,0 +1,4 @@
disallowed-names = [
"..", # defaults
"e", # prefer `err`
]

View File

@@ -2,7 +2,22 @@ version: "0.2"
words:
- actix
- addrs
- ALPN
- arrayvec
- bitflags
- clippy
- deque
- itertools
- itoa
- mptcp
- MSRV
- nonblocking
- oneshot
- pemfile
- rcgen
- Rustls
- rustup
- smallvec
- spki
- uring
- webpki

View File

@@ -35,7 +35,7 @@ jobs:
if: matrix.target.os == 'macos-latest'
run: sudo ifconfig lo0 alias 127.0.0.3
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Free Disk Space
if: matrix.target.os == 'ubuntu-latest'
@@ -59,12 +59,12 @@ jobs:
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
- name: Install Rust (${{ matrix.version }})
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: ${{ matrix.version }}
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
@@ -113,15 +113,15 @@ jobs:
name: minimal versions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Install Rust (nightly)
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: nightly
- name: Install cargo-hack & cargo-minimal-versions
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: cargo-hack,cargo-minimal-versions

View File

@@ -44,7 +44,7 @@ jobs:
if: matrix.target.os == 'macos-latest'
run: sudo ifconfig lo0 alias 127.0.0.3
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Free Disk Space
if: matrix.target.os == 'ubuntu-latest'
@@ -68,12 +68,12 @@ jobs:
echo "RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
- name: Install Rust (${{ matrix.version.name }})
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: ${{ matrix.version.version }}
- name: Install just, cargo-hack, cargo-nextest, cargo-ci-cache-clean
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: just,cargo-hack,cargo-nextest,cargo-ci-cache-clean
@@ -117,15 +117,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Install Rust (nightly)
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: nightly
- name: Install just
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: just

View File

@@ -15,15 +15,15 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Install Rust
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
components: llvm-tools-preview
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: cargo-llvm-cov
@@ -31,7 +31,7 @@ jobs:
run: cargo llvm-cov --workspace --all-features --codecov --output-path codecov.json
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5.4.2
uses: codecov/codecov-action@v5.5.0
with:
files: codecov.json
fail_ci_if_error: true

View File

@@ -16,9 +16,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
- uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: nightly
components: rustfmt
@@ -33,9 +33,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
- uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with: { components: clippy }
- uses: giraffate/clippy-action@v1.0.1
@@ -48,20 +48,20 @@ jobs:
if: false # rustdoc mismatch currently
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Install Rust (${{ vars.RUST_VERSION_EXTERNAL_TYPES }})
uses: actions-rust-lang/setup-rust-toolchain@v1.12.0
uses: actions-rust-lang/setup-rust-toolchain@v1.14.0
with:
toolchain: ${{ vars.RUST_VERSION_EXTERNAL_TYPES }}
- name: Install just
uses: taiki-e/install-action@v2.50.10
uses: taiki-e/install-action@v2.58.21
with:
tool: just
- name: Install cargo-check-external-types
uses: taiki-e/cache-cargo-install-action@v2.1.1
uses: taiki-e/cache-cargo-install-action@v2.3.0
with:
tool: cargo-check-external-types

32
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"rust-analyzer.cargo.features": [
"accept",
"actix-macros",
"connect",
"default",
"macros",
"native-tls",
"openssl",
"rustls",
"rustls-021",
"rustls-0_20",
"rustls-0_20-native-roots",
"rustls-0_20-webpki-roots",
"rustls-0_21",
"rustls-0_21-native-roots",
"rustls-0_21-webpki-roots",
"rustls-0_22",
"rustls-0_22-native-roots",
"rustls-0_22-webpki-roots",
"rustls-0_23",
"rustls-0_23-native-roots",
"rustls-0_23-webpki-roots",
"rustls-webpki-0101",
"serde",
"tokio-rustls-023",
"tokio-rustls-024",
"uri",
"webpki-roots-022",
"webpki-roots-025",
]
}

604
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@ resolver = "2"
members = [
"actix-codec",
"actix-macros",
"actix-proxy-protocol",
"actix-rt",
"actix-server",
"actix-service",
@@ -17,11 +18,12 @@ members = [
[workspace.package]
license = "MIT OR Apache-2.0"
edition = "2021"
rust-version = "1.74"
rust-version = "1.75"
[patch.crates-io]
actix-codec = { path = "actix-codec" }
actix-macros = { path = "actix-macros" }
actix-proxy-protocol = { path = "actix-proxy-protocol" }
actix-rt = { path = "actix-rt" }
actix-server = { path = "actix-server" }
actix-service = { path = "actix-service" }
@@ -38,7 +40,11 @@ opt-level = 3
codegen-units = 1
[workspace.lints.rust]
rust_2018_idioms = "deny"
rust-2018-idioms = "deny"
nonstandard-style = "deny"
future_incompatible = "deny"
missing_docs = { level = "warn", priority = -1 }
future-incompatible = "deny"
missing-docs = { level = "warn", priority = -1 }
[workspace.lints.clippy]
uninlined-format-args = "warn"
disallowed-names = "warn"

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.5.2

View File

@@ -57,7 +57,7 @@ impl Write for Bilateral {
Ok(data.len())
}
Some(Err(err)) => Err(err),
None => panic!("unexpected write; {:?}", src),
None => panic!("unexpected write; {src:?}"),
}
}

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.2.4

View File

@@ -1,3 +1,5 @@
#![allow(unused_imports)]
mod system {
pub use actix_rt::System as MySystem;
}

View File

@@ -0,0 +1,7 @@
# Changes
## Unreleased - 2022-xx-xx
## 0.0.1 - 2022-xx-xx
- delete me

40
actix-proxy-protocol/Cargo.toml Executable file
View File

@@ -0,0 +1,40 @@
[package]
name = "actix-proxy-protocol"
version = "0.0.1"
authors = ["Rob Ede <robjtede@icloud.com>"]
description = "PROXY protocol utilities"
keywords = ["proxy", "protocol", "network", "haproxy", "tcp"]
categories = ["network-programming", "asynchronous"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-net"
license.workspace = true
edition.workspace = true
rust-version.workspace = true
[dependencies]
actix-service = "2"
actix-utils = "3"
arrayvec = "0.7"
bitflags = "2"
crc32fast = "1"
futures-core = { version = "0.3.17", default-features = false, features = ["std"] }
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
itoa = "1"
nom = "8"
smallvec = "1"
tokio = { version = "1.13.1", features = ["sync", "io-util"] }
tracing = { version = "0.1.30", default-features = false, features = ["log"] }
[dev-dependencies]
actix-codec = "0.5"
actix-rt = "2.6"
actix-server = "2"
bytes = "1"
const-str = "0.5"
futures-util = { version = "0.3.7", default-features = false, features = ["sink", "async-await-macro"] }
hex = "0.4"
once_cell = "1"
pretty_assertions = "1"
tokio = { version = "1.13.1", features = ["io-util", "rt-multi-thread", "macros", "fs"] }
tracing-subscriber = "0.3"

View File

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

View File

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

View File

@@ -0,0 +1,17 @@
# actix-proxy-protocol
> Implementation of the [PROXY protocol].
[![crates.io](https://img.shields.io/crates/v/actix-proxy-protocol?label=latest)](https://crates.io/crates/actix-proxy-protocol)
[![Documentation](https://docs.rs/actix-proxy-protocol/badge.svg?version=0.1.0)](https://docs.rs/actix-proxy-protocol/0.1.0)
[![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-proxy-protocol.svg)
[![Dependency Status](https://deps.rs/crate/actix-proxy-protocol/0.1.0/status.svg)](https://deps.rs/crate/actix-proxy-protocol/0.1.0)
![Downloads](https://img.shields.io/crates/d/actix-proxy-protocol.svg)
[![Chat on Discord](https://img.shields.io/discord/771444961383153695?label=chat&logo=discord)](https://discord.gg/NWpN5mmg3x)
## Resources
- [Examples](./examples)
[proxy protocol]: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

View File

@@ -0,0 +1,173 @@
//! Adds PROXY protocol v1 prelude to connections.
#![allow(unused)]
use std::{
io, mem,
net::{IpAddr, Ipv4Addr, SocketAddr},
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
};
use actix_proxy_protocol::{tlv, v1, v2, AddressFamily, Command, TransportProtocol};
use actix_rt::net::TcpStream;
use actix_server::Server;
use actix_service::{fn_service, ServiceFactoryExt as _};
use arrayvec::ArrayVec;
use bytes::BytesMut;
use const_str::concat_bytes;
use once_cell::sync::Lazy;
use tokio::io::{
copy_bidirectional, AsyncBufReadExt as _, AsyncReadExt as _, AsyncWriteExt as _, BufReader,
};
static UPSTREAM: Lazy<SocketAddr> = Lazy::new(|| SocketAddr::from(([127, 0, 0, 1], 8080)));
/*
NOTES:
108 byte buffer on receiver side is enough for any PROXY header
after PROXY, receive until CRLF, *then* decode parts
TLV = type-length-value
TO DO:
handle UNKNOWN transport
v2 UNSPEC mode
AF_UNIX socket
*/
fn extend_with_ip_bytes(buf: &mut Vec<u8>, ip: IpAddr) {
match ip {
IpAddr::V4(ip) => buf.extend_from_slice(&ip.octets()),
IpAddr::V6(ip) => buf.extend_from_slice(&ip.octets()),
}
}
async fn wrap_with_proxy_protocol_v1(mut stream: TcpStream) -> io::Result<()> {
let mut upstream = TcpStream::connect(("127.0.0.1", 8080)).await?;
tracing::info!(
"PROXYv1 {} -> {}",
stream.peer_addr().unwrap(),
UPSTREAM.to_string(),
);
let proxy_header = v1::Header::new(
AddressFamily::Inet,
SocketAddr::from(([127, 0, 0, 1], 8081)),
*UPSTREAM,
);
proxy_header.write_to_tokio(&mut upstream).await?;
let (_bytes_read, _bytes_written) = copy_bidirectional(&mut stream, &mut upstream).await?;
Ok(())
}
async fn wrap_with_proxy_protocol_v2(mut stream: TcpStream) -> io::Result<()> {
let mut upstream = TcpStream::connect(("127.0.0.1", 8080)).await?;
tracing::info!(
"PROXYv2 {} -> {}",
stream.peer_addr().unwrap(),
UPSTREAM.to_string(),
);
let mut proxy_header = v2::Header::new_tcp_ipv4_proxy(([127, 0, 0, 1], 8082), *UPSTREAM);
proxy_header.add_typed_tlv(tlv::UniqueId::new("4269")); // UNIQUE_ID
proxy_header.add_typed_tlv(tlv::Noop::new("NOOP m8")); // NOOP
proxy_header.add_typed_tlv(tlv::Authority::new("localhost")); // NOOP
proxy_header.add_typed_tlv(tlv::Alpn::new("http/1.1")); // NOOP
proxy_header.add_crc23c_checksum();
proxy_header.write_to_tokio(&mut upstream).await?;
let (_bytes_read, _bytes_written) = copy_bidirectional(&mut stream, &mut upstream).await?;
Ok(())
}
async fn unwrap_proxy_protocol(mut stream: TcpStream) -> io::Result<()> {
let mut upstream = TcpStream::connect(("127.0.0.1", 8080)).await?;
tracing::info!(
"PROXY unwrap {} -> {}",
stream.peer_addr().unwrap(),
UPSTREAM.to_string(),
);
let mut header = [0; 12];
stream.peek(&mut header).await?;
eprintln!("header: {}", String::from_utf8_lossy(&header));
if &header[..v1::SIGNATURE.len()] == v1::SIGNATURE.as_bytes() {
tracing::info!("v1");
let mut stream = BufReader::new(stream);
let mut buf = Vec::with_capacity(v1::MAX_HEADER_SIZE);
let _len = stream.read_until(b'\n', &mut buf).await?;
eprintln!("{}", String::from_utf8_lossy(&buf));
let (rest, header) = match v1::Header::try_from_bytes(&buf) {
Ok((rest, header)) => (rest, header),
Err(err) => {
match err {
nom::Err::Incomplete(needed) => todo!(),
nom::Err::Error(err) => {
eprintln!(
"err {:?}, input: {}",
err.code,
String::from_utf8_lossy(err.input)
)
}
nom::Err::Failure(_) => todo!(),
}
return Ok(());
}
};
eprintln!("{:02X?} - {:?}", rest, header);
let (_bytes_read, _bytes_written) = copy_bidirectional(&mut stream, &mut upstream).await?;
} else if header == v2::SIGNATURE {
tracing::info!("v2");
let (_bytes_read, _bytes_written) = copy_bidirectional(&mut stream, &mut upstream).await?;
} else {
tracing::warn!("No proxy header; closing");
}
Ok(())
}
fn start_server() -> io::Result<Server> {
tracing::info!("proxying to 127.0.0.1:8080");
Ok(Server::build()
.bind("proxy-protocol-v1", ("127.0.0.1", 8081), move || {
fn_service(wrap_with_proxy_protocol_v1)
.map_err(|err| tracing::error!("service error: {err:?}"))
})?
.bind("proxy-protocol-v2", ("127.0.0.1", 8082), move || {
fn_service(wrap_with_proxy_protocol_v2)
.map_err(|err| tracing::error!("service error: {err:?}"))
})?
.bind("proxy-protocol-unwrap", ("127.0.0.1", 8083), move || {
fn_service(unwrap_proxy_protocol)
.map_err(|err| tracing::error!("service error: {err:?}"))
})?
.workers(2)
.run())
}
#[tokio::main]
async fn main() -> io::Result<()> {
tracing_subscriber::fmt::fmt().without_time().init();
start_server()?.await?;
Ok(())
}

View File

@@ -0,0 +1,156 @@
//! PROXY protocol.
#![expect(dead_code)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
pub mod tlv;
pub mod v1;
pub mod v2;
/// PROXY Protocol Version.
#[derive(Debug, Clone, Copy)]
enum Version {
/// Human-readable header format (Version 1)
V1,
/// Binary header format (Version 2)
V2,
}
impl Version {
const fn signature(&self) -> &'static [u8] {
match self {
Version::V1 => v1::SIGNATURE.as_bytes(),
Version::V2 => v2::SIGNATURE.as_slice(),
}
}
const fn v2_hi(&self) -> u8 {
(match self {
Version::V1 => panic!("v1 not supported in PROXY v2"),
Version::V2 => 0x2,
}) << 4
}
}
/// Command
///
/// other values are unassigned and must not be emitted by senders. Receivers
/// must drop connections presenting unexpected values here.
#[derive(Debug, Clone, Copy)]
pub enum Command {
/// \x0 : LOCAL : the connection was established on purpose by the proxy
/// without being relayed. The connection endpoints are the sender and the
/// receiver. Such connections exist when the proxy sends health-checks to the
/// server. The receiver must accept this connection as valid and must use the
/// real connection endpoints and discard the protocol block including the
/// family which is ignored.
Local,
/// \x1 : PROXY : the connection was established on behalf of another node,
/// and reflects the original connection endpoints. The receiver must then use
/// the information provided in the protocol block to get original the address.
Proxy,
}
impl Command {
const fn v2_lo(&self) -> u8 {
match self {
Command::Local => 0x0,
Command::Proxy => 0x1,
}
}
}
/// Address Family.
///
/// maps to the original socket family without necessarily
/// matching the values internally used by the system.
///
/// other values are unspecified and must not be emitted in version 2 of this
/// protocol and must be rejected as invalid by receivers.
#[derive(Debug, Clone, Copy)]
pub enum AddressFamily {
/// 0x0 : AF_UNSPEC : the connection is forwarded for an unknown, unspecified
/// or unsupported protocol. The sender should use this family when sending
/// LOCAL commands or when dealing with unsupported protocol families. The
/// receiver is free to accept the connection anyway and use the real endpoint
/// addresses or to reject it. The receiver should ignore address information.
Unspecified,
/// 0x1 : AF_INET : the forwarded connection uses the AF_INET address family
/// (IPv4). The addresses are exactly 4 bytes each in network byte order,
/// followed by transport protocol information (typically ports).
Inet,
/// 0x2 : AF_INET6 : the forwarded connection uses the AF_INET6 address family
/// (IPv6). The addresses are exactly 16 bytes each in network byte order,
/// followed by transport protocol information (typically ports).
Inet6,
/// 0x3 : AF_UNIX : the forwarded connection uses the AF_UNIX address family
/// (UNIX). The addresses are exactly 108 bytes each.
Unix,
}
impl AddressFamily {
pub(crate) fn v1_str(&self) -> &'static str {
match self {
AddressFamily::Inet => "TCP4",
AddressFamily::Inet6 => "TCP6",
af => panic!("{:?} is not supported in PROXY v1", af),
}
}
const fn v2_hi(&self) -> u8 {
(match self {
AddressFamily::Unspecified => 0x0,
AddressFamily::Inet => 0x1,
AddressFamily::Inet6 => 0x2,
AddressFamily::Unix => 0x3,
}) << 4
}
}
/// Transport Protocol.
///
/// other values are unspecified and must not be emitted in version 2 of this
/// protocol and must be rejected as invalid by receivers.
#[derive(Debug, Clone, Copy)]
pub enum TransportProtocol {
/// 0x0 : UNSPEC : the connection is forwarded for an unknown, unspecified
/// or unsupported protocol. The sender should use this family when sending
/// LOCAL commands or when dealing with unsupported protocol families. The
/// receiver is free to accept the connection anyway and use the real endpoint
/// addresses or to reject it. The receiver should ignore address information.
Unspecified,
/// 0x1 : STREAM : the forwarded connection uses a SOCK_STREAM protocol (eg:
/// TCP or UNIX_STREAM). When used with AF_INET/AF_INET6 (TCP), the addresses
/// are followed by the source and destination ports represented on 2 bytes
/// each in network byte order.
Stream,
/// 0x2 : DGRAM : the forwarded connection uses a SOCK_DGRAM protocol (eg:
/// UDP or UNIX_DGRAM). When used with AF_INET/AF_INET6 (UDP), the addresses
/// are followed by the source and destination ports represented on 2 bytes
/// each in network byte order.
Datagram,
}
impl TransportProtocol {
const fn v2_lo(&self) -> u8 {
match self {
TransportProtocol::Unspecified => 0x0,
TransportProtocol::Stream => 0x1,
TransportProtocol::Datagram => 0x2,
}
}
}
#[derive(Debug)]
enum ProxyProtocolHeader {
V1(v1::Header),
V2(v2::Header),
}

View File

@@ -0,0 +1,292 @@
use std::{borrow::Cow, convert::TryFrom, str};
const PP2_TYPE_ALPN: u8 = 0x01; // done
const PP2_TYPE_AUTHORITY: u8 = 0x02; // done
const PP2_TYPE_CRC32C: u8 = 0x03; // done
const PP2_TYPE_NOOP: u8 = 0x04; // done
const PP2_TYPE_UNIQUE_ID: u8 = 0x05; // done
const PP2_TYPE_SSL: u8 = 0x20;
const PP2_SUBTYPE_SSL_VERSION: u8 = 0x21;
const PP2_SUBTYPE_SSL_CN: u8 = 0x22;
const PP2_SUBTYPE_SSL_CIPHER: u8 = 0x23;
const PP2_SUBTYPE_SSL_SIG_ALG: u8 = 0x24;
const PP2_SUBTYPE_SSL_KEY_ALG: u8 = 0x25;
const PP2_TYPE_NETNS: u8 = 0x30;
pub trait Tlv: Sized {
const TYPE: u8;
fn try_from_value(value: &[u8]) -> Option<Self>;
fn value_bytes(&self) -> Cow<'_, [u8]>;
fn try_from_parts(typ: u8, value: &[u8]) -> Option<Self> {
if typ != Self::TYPE {
return None;
}
Self::try_from_value(value)
}
}
/// Application-Layer Protocol Negotiation (ALPN). It is a byte sequence defining
/// the upper layer protocol in use over the connection. The most common use case
/// will be to pass the exact copy of the ALPN extension of the Transport Layer
/// Security (TLS) protocol as defined by RFC7301 [9].
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Alpn {
alpn: Vec<u8>,
}
impl Alpn {
///
///
/// # Panics
/// Panics if `alpn` is empty (i.e., has length of 0).
pub fn new(alpn: impl Into<Vec<u8>>) -> Self {
let alpn = alpn.into();
assert!(!alpn.is_empty(), "ALPN TLV value cannot be empty");
Self { alpn }
}
}
impl Tlv for Alpn {
const TYPE: u8 = PP2_TYPE_ALPN;
fn try_from_value(value: &[u8]) -> Option<Self> {
Some(Self {
alpn: value.to_owned(),
})
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Borrowed(&self.alpn)
}
}
/// Contains the host name value passed by the client, as an UTF8-encoded string.
/// In case of TLS being used on the client connection, this is the exact copy of
/// the "server_name" extension as defined by RFC3546 [10], section 3.1, often
/// referred to as "SNI". There are probably other situations where an authority
/// can be mentioned on a connection without TLS being involved at all.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Authority {
authority: String,
}
impl Authority {
/// A UTF-8
///
/// # Panics
/// Panics if `authority` is an empty string.
pub fn new(authority: impl Into<String>) -> Self {
let authority = authority.into();
assert!(!authority.is_empty(), "Authority TLV value cannot be empty");
Self { authority }
}
}
impl Tlv for Authority {
const TYPE: u8 = PP2_TYPE_AUTHORITY;
fn try_from_value(value: &[u8]) -> Option<Self> {
Some(Self {
authority: str::from_utf8(value).ok()?.to_owned(),
})
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Borrowed(self.authority.as_bytes())
}
}
/// The value of the type PP2_TYPE_CRC32C is a 32-bit number storing the CRC32c
/// checksum of the PROXY protocol header.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Crc32c {
pub(crate) checksum: u32,
}
impl Tlv for Crc32c {
const TYPE: u8 = PP2_TYPE_CRC32C;
fn try_from_value(value: &[u8]) -> Option<Self> {
let checksum_bytes = <[u8; 4]>::try_from(value).ok()?;
Some(Self {
checksum: u32::from_be_bytes(checksum_bytes),
})
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Owned(self.checksum.to_be_bytes().to_vec())
}
}
/// The TLV of this type should be ignored when parsed. The value is zero or more
/// bytes. Can be used for data padding or alignment. Note that it can be used
/// to align only by 3 or more bytes because a TLV can not be smaller than that.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Noop {
value: Vec<u8>,
}
impl Noop {
///
///
/// # Panics
/// Panics if `value` is empty (i.e., has length of 0).
pub fn new(value: impl Into<Vec<u8>>) -> Self {
let value = value.into();
assert!(!value.is_empty(), "Noop TLV `value` cannot be empty");
Self { value }
}
}
impl Tlv for Noop {
const TYPE: u8 = PP2_TYPE_NOOP;
fn try_from_value(value: &[u8]) -> Option<Self> {
Some(Self {
value: value.to_owned(),
})
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Borrowed(&self.value)
}
}
/// The value of the type PP2_TYPE_UNIQUE_ID is an opaque byte sequence of up to
/// 128 bytes generated by the upstream proxy that uniquely identifies the
/// connection.
///
/// The unique ID can be used to easily correlate connections across multiple
/// layers of proxies, without needing to look up IP addresses and port numbers.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UniqueId {
value: Vec<u8>,
}
impl UniqueId {
///
///
/// # Panics
/// Panics if `value` is 0 bytes or larger than 128 bytes.
pub fn new(id: impl Into<Vec<u8>>) -> Self {
let value = id.into();
assert!(!value.is_empty(), "UniqueId TLV `value` cannot be empty");
assert!(
value.len() < 128,
"UniqueId TLV `value` cannot be larger than 128 bytes"
);
Self { value }
}
}
impl Tlv for UniqueId {
const TYPE: u8 = PP2_TYPE_UNIQUE_ID;
fn try_from_value(value: &[u8]) -> Option<Self> {
Some(Self {
value: value.to_owned(),
})
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Borrowed(&self.value)
}
}
bitflags::bitflags! {
#[derive(Debug, Clone, PartialEq, Eq)]
struct SslClientFlags: u8 {
const PP2_CLIENT_SSL = 0x01;
const PP2_CLIENT_CERT_CONN = 0x02;
const PP2_CLIENT_CERT_SESS = 0x04;
}
}
/// TLS (SSL).
///
/// Very broken atm.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ssl {
/// The <client> field is made of a bit field indicating which element is present.
///
/// Note, that each of these elements may lead to extra data being appended to
/// this TLV using a second level of TLV encapsulation. It is thus possible to
/// find multiple TLV values after this field. The total length of the pp2_tlv_ssl
/// TLV will reflect this.
client: SslClientFlags,
/// The <verify> field will be zero if the client presented a certificate
/// and it was successfully verified, and non-zero otherwise.
verify: bool,
/// Sub-TLVs.
tlvs: Vec<SslTlv>,
}
impl Tlv for Ssl {
const TYPE: u8 = PP2_TYPE_SSL;
fn try_from_value(_value: &[u8]) -> Option<Self> {
/// The PP2_CLIENT_SSL flag indicates that the client connected over SSL/TLS. When
/// this field is present, the US-ASCII string representation of the TLS version is
/// appended at the end of the field in the TLV format using the type
/// PP2_SUBTYPE_SSL_VERSION.
const PP2_CLIENT_SSL: u8 = 0x01;
/// PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
/// current connection.
const PP2_CLIENT_CERT_CONN: u8 = 0x02;
/// PP2_CLIENT_CERT_SESS indicates that the client provided a
/// certificate at least once over the TLS session this connection belongs to.
const PP2_CLIENT_CERT_SESS: u8 = 0x04;
// TODO: finish parsing
None
}
fn value_bytes(&self) -> Cow<'_, [u8]> {
Cow::Borrowed(&[])
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct SslTlv {}
#[cfg(test)]
mod tests {
use super::*;
// #[test]
// #[should_panic]
// fn tlv_zero_len() {
// Tlv::new(0x00, vec![]);
// }
#[test]
fn tlv_as_crc32c() {
// noop
assert_eq!(Crc32c::try_from_parts(0x04, &[0x00]), None);
assert_eq!(
Crc32c::try_from_parts(0x03, &[0x08, 0x70, 0x17, 0x7b]),
Some(Crc32c {
checksum: 141563771
})
);
}
}

View File

@@ -0,0 +1,148 @@
use std::{fmt, io, net::SocketAddr};
use arrayvec::ArrayVec;
use nom::{IResult, Parser as _};
use tokio::io::{AsyncWrite, AsyncWriteExt as _};
use crate::AddressFamily;
pub const SIGNATURE: &str = "PROXY";
pub const MAX_HEADER_SIZE: usize = 107;
#[derive(Debug, Clone)]
pub struct Header {
/// Address family.
af: AddressFamily,
/// Source address.
src: SocketAddr,
/// Destination address.
dst: SocketAddr,
}
impl Header {
pub const fn new(af: AddressFamily, src: SocketAddr, dst: SocketAddr) -> Self {
Self { af, src, dst }
}
pub const fn new_inet(src: SocketAddr, dst: SocketAddr) -> Self {
Self::new(AddressFamily::Inet, src, dst)
}
pub const fn new_inet6(src: SocketAddr, dst: SocketAddr) -> Self {
Self::new(AddressFamily::Inet6, src, dst)
}
pub fn write_to(&self, wrt: &mut impl io::Write) -> io::Result<()> {
write!(wrt, "{self}")
}
pub async fn write_to_tokio(&self, wrt: &mut (impl AsyncWrite + Unpin)) -> io::Result<()> {
// max length of a V1 header is 107 bytes
let mut buf = ArrayVec::<_, MAX_HEADER_SIZE>::new();
self.write_to(&mut buf)?;
wrt.write_all(&buf).await
}
pub fn try_from_bytes(slice: &[u8]) -> IResult<&[u8], Self> {
parsing::parse(slice)
}
}
impl fmt::Display for Header {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{proto_sig} {af} {src_ip} {dst_ip} {src_port} {dst_port}\r\n",
proto_sig = SIGNATURE,
af = self.af.v1_str(),
src_ip = self.src.ip(),
dst_ip = self.dst.ip(),
src_port = itoa::Buffer::new().format(self.src.port()),
dst_port = itoa::Buffer::new().format(self.dst.port()),
)
}
}
mod parsing {
use std::{
net::{Ipv4Addr, SocketAddrV4},
str::{self, FromStr},
};
use nom::{
branch::alt,
bytes::complete::{tag, take_while},
character::complete::char,
combinator::{map, map_res},
IResult,
};
use super::*;
/// Parses a number from serialized representation (as bytes).
fn parse_number<T: FromStr>(input: &[u8]) -> IResult<&[u8], T> {
map_res(take_while(|c: u8| c.is_ascii_digit()), |s: &[u8]| {
let s = str::from_utf8(s).map_err(|_| "utf8 error")?;
let val = s.parse::<T>().map_err(|_| "u8 parse error")?;
Ok::<_, Box<dyn std::error::Error>>(val)
})
.parse(input)
}
/// Parses an address family.
fn parse_address_family(input: &[u8]) -> IResult<&[u8], AddressFamily> {
map_res(alt((tag("TCP4"), tag("TCP6"))), |af: &[u8]| match af {
b"TCP4" => Ok(AddressFamily::Inet),
b"TCP6" => Ok(AddressFamily::Inet6),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid address family",
)),
})
.parse(input)
}
/// Parses an IPv4 address from serialized representation (as bytes).
fn parse_ipv4(input: &[u8]) -> IResult<&[u8], Ipv4Addr> {
map(
(
parse_number::<u8>,
char('.'),
parse_number::<u8>,
char('.'),
parse_number::<u8>,
char('.'),
parse_number::<u8>,
),
|(a, _, b, _, c, _, d)| Ipv4Addr::new(a, b, c, d),
)
.parse(input)
}
/// Parses an IPv4 address from ASCII bytes.
pub(super) fn parse(input: &[u8]) -> IResult<&[u8], Header> {
map(
(
tag(SIGNATURE),
char(' '),
parse_address_family,
char(' '),
parse_ipv4,
char(' '),
parse_ipv4,
char(' '),
parse_number::<u16>,
char(' '),
parse_number::<u16>,
),
|(_, _, af, _, src_ip, _, dst_ip, _, src_port, _, dst_port)| Header {
af,
src: SocketAddr::V4(SocketAddrV4::new(src_ip, src_port)),
dst: SocketAddr::V4(SocketAddrV4::new(dst_ip, dst_port)),
},
)
.parse(input)
}
}

View File

@@ -0,0 +1,304 @@
use std::{
io,
net::{IpAddr, SocketAddr},
};
use smallvec::{SmallVec, ToSmallVec as _};
use tokio::io::{AsyncWrite, AsyncWriteExt as _};
use crate::{
tlv::{Crc32c, Tlv},
AddressFamily, Command, TransportProtocol, Version,
};
pub const SIGNATURE: [u8; 12] = [
0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A,
];
#[derive(Debug, Clone)]
pub struct Header {
command: Command,
transport_protocol: TransportProtocol,
address_family: AddressFamily,
src: SocketAddr,
dst: SocketAddr,
tlvs: SmallVec<[(u8, SmallVec<[u8; 16]>); 4]>,
}
impl Header {
pub fn new(
command: Command,
transport_protocol: TransportProtocol,
address_family: AddressFamily,
src: impl Into<SocketAddr>,
dst: impl Into<SocketAddr>,
) -> Self {
Self {
command,
transport_protocol,
address_family,
src: src.into(),
dst: dst.into(),
tlvs: SmallVec::new(),
}
}
pub fn new_tcp_ipv4_proxy(src: impl Into<SocketAddr>, dst: impl Into<SocketAddr>) -> Self {
Self::new(
Command::Proxy,
TransportProtocol::Stream,
AddressFamily::Inet,
src,
dst,
)
}
pub fn add_tlv(&mut self, typ: u8, value: impl AsRef<[u8]>) {
self.tlvs.push((typ, SmallVec::from_slice(value.as_ref())));
}
pub fn add_typed_tlv<T: Tlv>(&mut self, tlv: T) {
self.add_tlv(T::TYPE, tlv.value_bytes());
}
fn v2_len(&self) -> u16 {
let addr_len = if self.src.is_ipv4() {
4 + 2 // 4b IPv4 + 2b port number
} else {
16 + 2 // 16b IPv6 + 2b port number
};
(addr_len * 2)
+ self
.tlvs
.iter()
.map(|(_, value)| 1 + 2 + value.len() as u16)
.sum::<u16>()
}
pub fn write_to(&self, wrt: &mut impl io::Write) -> io::Result<()> {
// PROXY v2 signature
wrt.write_all(&SIGNATURE)?;
// version | command
wrt.write_all(&[Version::V2.v2_hi() | self.command.v2_lo()])?;
// address family | transport protocol
wrt.write_all(&[self.address_family.v2_hi() | self.transport_protocol.v2_lo()])?;
// rest-of-header length
wrt.write_all(&self.v2_len().to_be_bytes())?;
tracing::debug!("proxy rest-of-header len: {}", self.v2_len());
fn write_ip_bytes_to(wrt: &mut impl io::Write, ip: IpAddr) -> io::Result<()> {
match ip {
IpAddr::V4(ip) => wrt.write_all(&ip.octets()),
IpAddr::V6(ip) => wrt.write_all(&ip.octets()),
}
}
// L3 (IP) address
write_ip_bytes_to(wrt, self.src.ip())?;
write_ip_bytes_to(wrt, self.dst.ip())?;
// L4 ports
wrt.write_all(&self.src.port().to_be_bytes())?;
wrt.write_all(&self.dst.port().to_be_bytes())?;
// TLVs
for (typ, value) in &self.tlvs {
wrt.write_all(&[*typ])?;
wrt.write_all(&(value.len() as u16).to_be_bytes())?;
wrt.write_all(value)?;
}
Ok(())
}
pub async fn write_to_tokio(&self, wrt: &mut (impl AsyncWrite + Unpin)) -> io::Result<()> {
let buf = self.to_vec();
wrt.write_all(&buf).await
}
fn to_vec(&self) -> Vec<u8> {
// TODO: figure out cap
let mut buf = Vec::with_capacity(64);
self.write_to(&mut buf).unwrap();
buf
}
pub fn has_tlv<T: Tlv>(&self) -> bool {
self.tlvs.iter().any(|&(typ, _)| typ == T::TYPE)
}
/// Calculates and adds a crc32c TLV to the PROXY header.
///
/// Uses method defined in spec.
///
/// If this is not called last thing it will be wrong.
pub fn add_crc23c_checksum(&mut self) {
// don't add a checksum if it is already set
if self.has_tlv::<Crc32c>() {
return;
}
// When the checksum is supported by the sender after constructing the header
// the sender MUST:
// - initialize the checksum field to '0's.
// - calculate the CRC32c checksum of the PROXY header as described in RFC4960,
// Appendix B [8].
// - put the resultant value into the checksum field, and leave the rest of
// the bits unchanged.
// add zeroed checksum field to TLVs
self.add_typed_tlv(Crc32c::default());
// write PROXY header to buffer
let mut buf = Vec::new();
self.write_to(&mut buf).unwrap();
// calculate CRC on buffer and update CRC TLV
let crc_calc = crc32fast::hash(&buf);
self.tlvs.last_mut().unwrap().1 = crc_calc.to_be_bytes().to_smallvec();
tracing::debug!("checksum is {}", crc_calc);
}
pub fn validate_crc32c_tlv(&self) -> Option<bool> {
// extract crc32c TLV or exit early if none is present
let crc_sent = self
.tlvs
.iter()
.filter_map(|(typ, value)| Crc32c::try_from_parts(*typ, value))
.next()?;
// If the checksum is provided as part of the PROXY header and the checksum
// functionality is supported by the receiver, the receiver MUST:
// - store the received CRC32c checksum value aside.
// - replace the 32 bits of the checksum field in the received PROXY header with
// all '0's and calculate a CRC32c checksum value of the whole PROXY header.
// - verify that the calculated CRC32c checksum is the same as the received
// CRC32c checksum. If it is not, the receiver MUST treat the TCP connection
// providing the header as invalid.
// The default procedure for handling an invalid TCP connection is to abort it.
let mut this = self.clone();
for (typ, value) in this.tlvs.iter_mut() {
if Crc32c::try_from_parts(*typ, value).is_some() {
value.fill(0);
}
}
let mut buf = Vec::new();
this.write_to(&mut buf).unwrap();
let crc_calc = crc32fast::hash(&buf);
Some(crc_sent.checksum == crc_calc)
}
}
#[cfg(test)]
mod tests {
use std::net::Ipv6Addr;
use const_str::hex;
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn write_v2_no_tlvs() {
let mut exp = Vec::new();
exp.extend_from_slice(&SIGNATURE); // 0-11
exp.extend_from_slice(&[0x21, 0x11]); // 12-13
exp.extend_from_slice(&[0x00, 0x0C]); // 14-15
exp.extend_from_slice(&[127, 0, 0, 1, 127, 0, 0, 2]); // 16-23
exp.extend_from_slice(&[0x04, 0xd2, 0x00, 80]); // 24-27
let header = Header::new(
Command::Proxy,
TransportProtocol::Stream,
AddressFamily::Inet,
SocketAddr::from(([127, 0, 0, 1], 1234)),
SocketAddr::from(([127, 0, 0, 2], 80)),
);
assert_eq!(header.v2_len(), 12);
assert_eq!(header.to_vec(), exp);
}
#[test]
fn write_v2_ipv6_tlv_noop() {
let mut exp = Vec::new();
exp.extend_from_slice(&SIGNATURE); // 0-11
exp.extend_from_slice(&[0x20, 0x11]); // 12-13
exp.extend_from_slice(&[0x00, 0x28]); // 14-15
exp.extend_from_slice(&hex!("00000000000000000000000000000001")); // 16-31
exp.extend_from_slice(&hex!("000102030405060708090A0B0C0D0E0F")); // 32-45
exp.extend_from_slice(&[0x00, 80, 0xff, 0xff]); // 45-49
exp.extend_from_slice(&[0x04, 0x00, 0x01, 0x00]); // 50-53 NOOP TLV
let mut header = Header::new(
Command::Local,
TransportProtocol::Stream,
AddressFamily::Inet,
SocketAddr::from((Ipv6Addr::LOCALHOST, 80)),
SocketAddr::from((
Ipv6Addr::from([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
65535,
)),
);
header.add_tlv(0x04, [0]);
assert_eq!(header.v2_len(), 36 + 4);
assert_eq!(header.to_vec(), exp);
}
#[test]
fn write_v2_tlv_c2c() {
let mut exp = Vec::new();
exp.extend_from_slice(&SIGNATURE); // 0-11
exp.extend_from_slice(&[0x21, 0x11]); // 12-13
exp.extend_from_slice(&[0x00, 0x13]); // 14-15
exp.extend_from_slice(&[127, 0, 0, 1, 127, 0, 0, 1]); // 16-23
exp.extend_from_slice(&[0x00, 80, 0x00, 80]); // 24-27
exp.extend_from_slice(&[0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00]); // 28-35 TLV crc32c
assert_eq!(
crc32fast::hash(&exp),
// correct checksum calculated manually
u32::from_be_bytes([0x08, 0x70, 0x17, 0x7b]),
);
// re-assign actual checksum to last 4 bytes of expected byte array
exp[31..35].copy_from_slice(&[0x08, 0x70, 0x17, 0x7b]);
let mut header = Header::new(
Command::Proxy,
TransportProtocol::Stream,
AddressFamily::Inet,
SocketAddr::from(([127, 0, 0, 1], 80)),
SocketAddr::from(([127, 0, 0, 1], 80)),
);
assert!(
header.validate_crc32c_tlv().is_none(),
"header doesn't have CRC TLV added yet"
);
// add crc32c TLV to header
header.add_crc23c_checksum();
assert_eq!(header.v2_len(), 12 + 7);
assert_eq!(header.to_vec(), exp);
// struct can self-validate checksum
assert_eq!(header.validate_crc32c_tlv().unwrap(), true);
// mangle crc32c TLV and assert that validate now fails
*header.tlvs.last_mut().unwrap().1.last_mut().unwrap() = 0x00;
assert_eq!(header.validate_crc32c_tlv().unwrap(), false);
}
}

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 2.10.0

View File

@@ -115,7 +115,7 @@ impl Arbiter {
let system_id = sys.id();
let arb_id = COUNT.fetch_add(1, Ordering::Relaxed);
let name = format!("actix-rt|system:{}|arbiter:{}", system_id, arb_id);
let name = format!("actix-rt|system:{system_id}|arbiter:{arb_id}");
let (tx, rx) = mpsc::unbounded_channel();
let (ready_tx, ready_rx) = std::sync::mpsc::channel::<()>();

View File

@@ -187,7 +187,7 @@ impl SystemRunner {
match exit_code {
0 => Ok(()),
nonzero => Err(io::Error::other(format!("Non-zero exit code: {}", nonzero))),
nonzero => Err(io::Error::other(format!("Non-zero exit code: {nonzero}"))),
}
}

View File

@@ -5,7 +5,7 @@
## 2.6.0
- Add `ServerBuilder::shutdown_signal()` method.
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 2.5.1

View File

@@ -29,7 +29,7 @@ actix-utils = "3"
futures-core = { version = "0.3.17", default-features = false, features = ["alloc"] }
futures-util = { version = "0.3.17", default-features = false, features = ["alloc"] }
mio = { version = "1", features = ["os-poll", "net"] }
socket2 = "0.5"
socket2 = "0.6"
tokio = { version = "1.44.2", features = ["sync"] }
tracing = { version = "0.1.30", default-features = false, features = ["log"] }

View File

@@ -130,7 +130,7 @@ impl Accept {
if let Err(err) = self.poll.poll(&mut events, self.timeout) {
match err.kind() {
io::ErrorKind::Interrupted => {}
_ => panic!("Poll error: {}", err),
_ => panic!("Poll error: {err}"),
}
}
@@ -165,7 +165,6 @@ impl Accept {
// 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 notified it became available.
Some(WakerInterest::WorkerAvailable(idx)) => {
@@ -455,8 +454,8 @@ impl Accept {
/// All other errors will incur a timeout before next `accept()` call is attempted. The timeout is
/// useful to handle resource exhaustion errors like `ENFILE` and `EMFILE`. Otherwise, it could
/// enter into a temporary spin loop.
fn connection_error(e: &io::Error) -> bool {
e.kind() == io::ErrorKind::ConnectionRefused
|| e.kind() == io::ErrorKind::ConnectionAborted
|| e.kind() == io::ErrorKind::ConnectionReset
fn connection_error(err: &io::Error) -> bool {
err.kind() == io::ErrorKind::ConnectionRefused
|| err.kind() == io::ErrorKind::ConnectionAborted
|| err.kind() == io::ErrorKind::ConnectionReset
}

View File

@@ -92,11 +92,9 @@ impl OsSignals {
.filter_map(|(kind, sig)| {
unix::signal(*kind)
.map(|tokio_sig| (*sig, tokio_sig))
.map_err(|e| {
.map_err(|err| {
tracing::error!(
"can not initialize stream handler for {:?} err: {}",
sig,
e
"can not initialize stream handler for {sig:?} err: {err}",
)
})
.ok()

View File

@@ -105,9 +105,9 @@ impl From<StdUnixListener> for MioListener {
impl fmt::Debug for MioListener {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
MioListener::Tcp(ref lst) => write!(f, "{:?}", lst),
MioListener::Tcp(ref lst) => write!(f, "{lst:?}"),
#[cfg(unix)]
MioListener::Uds(ref lst) => write!(f, "{:?}", lst),
MioListener::Uds(ref lst) => write!(f, "{lst:?}"),
}
}
}
@@ -115,9 +115,9 @@ impl fmt::Debug for MioListener {
impl fmt::Display for MioListener {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
MioListener::Tcp(ref lst) => write!(f, "{:?}", lst),
MioListener::Tcp(ref lst) => write!(f, "{lst:?}"),
#[cfg(unix)]
MioListener::Uds(ref lst) => write!(f, "{:?}", lst),
MioListener::Uds(ref lst) => write!(f, "{lst:?}"),
}
}
}
@@ -133,9 +133,9 @@ impl fmt::Display for SocketAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::Unknown => write!(f, "Unknown SocketAddr"),
Self::Tcp(ref addr) => write!(f, "{}", addr),
Self::Tcp(ref addr) => write!(f, "{addr}"),
#[cfg(unix)]
Self::Uds(ref addr) => write!(f, "{:?}", addr),
Self::Uds(ref addr) => write!(f, "{addr:?}"),
}
}
}
@@ -144,9 +144,9 @@ impl fmt::Debug for SocketAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::Unknown => write!(f, "Unknown SocketAddr"),
Self::Tcp(ref addr) => write!(f, "{:?}", addr),
Self::Tcp(ref addr) => write!(f, "{addr:?}"),
#[cfg(unix)]
Self::Uds(ref addr) => write!(f, "{:?}", addr),
Self::Uds(ref addr) => write!(f, "{addr:?}"),
}
}
}
@@ -266,14 +266,14 @@ mod tests {
#[test]
fn socket_addr() {
let addr = SocketAddr::Tcp("127.0.0.1:8080".parse().unwrap());
assert!(format!("{:?}", addr).contains("127.0.0.1:8080"));
assert_eq!(format!("{}", addr), "127.0.0.1:8080");
assert!(format!("{addr:?}").contains("127.0.0.1:8080"));
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, &MpTcp::Disabled).unwrap();
let lst = MioListener::Tcp(lst);
assert!(format!("{:?}", lst).contains("TcpListener"));
assert!(format!("{}", lst).contains("127.0.0.1"));
assert!(format!("{lst:?}").contains("TcpListener"));
assert!(format!("{lst}").contains("127.0.0.1"));
}
#[test]
@@ -283,12 +283,12 @@ mod tests {
if let Ok(socket) = MioUnixListener::bind("/tmp/sock.xxxxx") {
let addr = socket.local_addr().expect("Couldn't get local address");
let a = SocketAddr::Uds(addr);
assert!(format!("{:?}", a).contains("/tmp/sock.xxxxx"));
assert!(format!("{}", a).contains("/tmp/sock.xxxxx"));
assert!(format!("{a:?}").contains("/tmp/sock.xxxxx"));
assert!(format!("{a}").contains("/tmp/sock.xxxxx"));
let lst = MioListener::Uds(socket);
assert!(format!("{:?}", lst).contains("/tmp/sock.xxxxx"));
assert!(format!("{}", lst).contains("/tmp/sock.xxxxx"));
assert!(format!("{lst:?}").contains("/tmp/sock.xxxxx"));
assert!(format!("{lst}").contains("/tmp/sock.xxxxx"));
}
}
}

View File

@@ -52,7 +52,7 @@ impl WakerQueue {
waker
.wake()
.unwrap_or_else(|e| panic!("can not wake up Accept Poll: {}", e));
.unwrap_or_else(|err| panic!("can not wake up Accept Poll: {err}"));
}
/// Get a MutexGuard of the waker queue.
@@ -62,7 +62,7 @@ impl WakerQueue {
/// Reset the waker queue so it does not grow infinitely.
pub(crate) fn reset(queue: &mut VecDeque<WakerInterest>) {
std::mem::swap(&mut VecDeque::<WakerInterest>::with_capacity(16), queue);
*queue = VecDeque::<WakerInterest>::with_capacity(16);
}
}

View File

@@ -325,7 +325,7 @@ impl ServerWorker {
// no actix system
(None, Some(rt_handle)) => {
std::thread::Builder::new()
.name(format!("actix-server worker {}", idx))
.name(format!("actix-server worker {idx}"))
.spawn(move || {
let (worker_stopped_tx, worker_stopped_rx) = oneshot::channel();

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 2.0.3

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 3.4.0

View File

@@ -80,7 +80,7 @@ async fn main() -> io::Result<()> {
// Set up TLS service factory
tls_acceptor
.clone()
.map_err(|err| println!("Rustls error: {:?}", err))
.map_err(|err| println!("Rustls error: {err:?}"))
.and_then(move |stream: TlsStream<TcpStream>| {
let num = count.fetch_add(1, Ordering::Relaxed);
info!("[{}] Got TLS connection: {:?}", num, &*stream);

View File

@@ -81,9 +81,9 @@ where
trace!("TLS handshake success: {:?}", stream.hostname());
stream.replace_io(res).1
})
.map_err(|e| {
trace!("TLS handshake error: {:?}", e);
io::Error::new(io::ErrorKind::Other, format!("{}", e))
.map_err(|err| {
trace!("TLS handshake error: {err:?}");
io::Error::other(format!("{err}"))
})
})
}

View File

@@ -141,10 +141,7 @@ where
}
Err(err) => {
trace!("TLS handshake error: {:?}", err);
Poll::Ready(Err(io::Error::new(
io::ErrorKind::Other,
format!("{}", err),
)))
Poll::Ready(Err(io::Error::other(format!("{err}"))))
}
}
}

View File

@@ -159,8 +159,7 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.get_mut() {
Self::InvalidDns => Poll::Ready(Err(io::Error::new(
io::ErrorKind::Other,
Self::InvalidDns => Poll::Ready(Err(io::Error::other(
"Rustls v0.20 can only handle hostname-based connections. Enable the `rustls-0_21` \
feature and use the Rustls v0.21 utilities to gain this feature.",
))),

View File

@@ -126,7 +126,7 @@ async fn accepts_connections() {
let tls_acceptor = Acceptor::new(openssl_acceptor);
tls_acceptor
.map_err(|err| println!("OpenSSL error: {:?}", err))
.map_err(|err| println!("OpenSSL error: {err:?}"))
.and_then(move |_stream: TlsStream<TcpStream>| ok(()))
}
});

View File

@@ -87,7 +87,7 @@ async fn accepts_connections() {
let tls_acceptor = Acceptor::new(rustls_server_config(cert.clone(), key.clone()));
tls_acceptor
.map_err(|err| println!("Rustls error: {:?}", err))
.map_err(|err| println!("Rustls error: {err:?}"))
.and_then(move |_stream: TlsStream<TcpStream>| ok(()))
}
});

View File

@@ -26,7 +26,7 @@ async fn custom_resolver() {
port: u16,
) -> LocalBoxFuture<'a, Result<Vec<SocketAddr>, Box<dyn std::error::Error>>> {
Box::pin(async move {
let local = format!("127.0.0.1:{}", port).parse().unwrap();
let local = format!("127.0.0.1:{port}").parse().unwrap();
Ok(vec![local])
})
}

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.1.0

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 3.0.1

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 1.4.0

View File

@@ -23,6 +23,8 @@ fmt:
# Downgrade dependencies necessary to run MSRV checks/tests.
[private]
downgrade-for-msrv:
cargo {{ toolchain }} update -p=rayon --precise=1.10.0 # next ver: 1.80.0
cargo {{ toolchain }} update -p=rayon-core --precise=1.12.1 # next ver: 1.80.0
cargo {{ toolchain }} update -p=native-tls --precise=0.2.13 # next ver: 1.80.0
cargo {{ toolchain }} update -p=idna_adapter --precise=1.2.0 # next ver: 1.82.0
cargo {{ toolchain }} update -p=litemap --precise=0.7.4 # next ver: 1.81.0

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.1.5

View File

@@ -2,7 +2,7 @@
## Unreleased
- Minimum supported Rust version (MSRV) is now 1.74.
- Minimum supported Rust version (MSRV) is now 1.75.
## 0.1.4