mirror of
https://github.com/fafhrd91/actix-net
synced 2025-08-16 17:18:59 +02:00
Compare commits
16 Commits
tls-v2.0.0
...
macros-v0.
Author | SHA1 | Date | |
---|---|---|---|
|
ab496a71b5 | ||
|
76d956e25c | ||
|
89e56cf661 | ||
|
8aca8d4d07 | ||
|
e0dd2a3d76 | ||
|
59e976aaca | ||
|
4cc1c87724 | ||
|
ca39917d2c | ||
|
704af672b9 | ||
|
242bef269f | ||
|
6c65e2a79f | ||
|
e5ca271764 | ||
|
98a2197a09 | ||
|
fb0aa02b3c | ||
|
681eeb497d | ||
|
3e04b87311 |
2
.github/workflows/clippy-fmt.yml
vendored
2
.github/workflows/clippy-fmt.yml
vendored
@@ -31,4 +31,4 @@ jobs:
|
|||||||
uses: actions-rs/clippy-check@v1
|
uses: actions-rs/clippy-check@v1
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
args: --all-features --all --tests
|
args: --workspace --tests
|
||||||
|
6
.github/workflows/linux.yml
vendored
6
.github/workflows/linux.yml
vendored
@@ -53,20 +53,20 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests
|
args: --workspace --bins --examples --tests
|
||||||
|
|
||||||
- name: tests
|
- name: tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
timeout-minutes: 40
|
timeout-minutes: 40
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --all --all-features --no-fail-fast -- --nocapture
|
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture
|
||||||
|
|
||||||
- name: Generate coverage file
|
- name: Generate coverage file
|
||||||
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||||
run: |
|
run: |
|
||||||
cargo install cargo-tarpaulin
|
cargo install cargo-tarpaulin
|
||||||
cargo tarpaulin --out Xml --workspace --all-features
|
cargo tarpaulin --out Xml --workspace
|
||||||
|
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||||
|
4
.github/workflows/macos.yml
vendored
4
.github/workflows/macos.yml
vendored
@@ -34,10 +34,10 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests
|
args: --workspace --bins --examples --tests
|
||||||
|
|
||||||
- name: tests
|
- name: tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --all --all-features --no-fail-fast -- --nocapture
|
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture
|
||||||
|
2
.github/workflows/windows-mingw.yml
vendored
2
.github/workflows/windows-mingw.yml
vendored
@@ -42,4 +42,4 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests
|
args: --workspace --bins --examples --tests
|
||||||
|
4
.github/workflows/windows.yml
vendored
4
.github/workflows/windows.yml
vendored
@@ -60,10 +60,10 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests
|
args: --workspace --bins --examples --tests
|
||||||
|
|
||||||
- name: tests
|
- name: tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --all --all-features --no-fail-fast -- --nocapture
|
args: --workspace --exclude=actix-tls --no-fail-fast -- --nocapture
|
||||||
|
@@ -34,10 +34,13 @@ This Code of Conduct applies both within project spaces and in public spaces whe
|
|||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at fafhrd91@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at robjtede@icloud.com ([@robjtede]) or huyuumi@neet.club ([@JohnTitor]). The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
|
|
||||||
|
[@robjtede]: https://github.com/robjtede
|
||||||
|
[@JohnTitor]: https://github.com/JohnTitor
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
* Upgrade `pin-project` to `1.0`.
|
||||||
|
|
||||||
## 0.3.0 - 2020-08-23
|
## 0.3.0 - 2020-08-23
|
||||||
* No changes from beta 2.
|
* No changes from beta 2.
|
||||||
|
@@ -21,6 +21,6 @@ bytes = "0.5.2"
|
|||||||
futures-core = { version = "0.3.4", default-features = false }
|
futures-core = { version = "0.3.4", default-features = false }
|
||||||
futures-sink = { version = "0.3.4", default-features = false }
|
futures-sink = { version = "0.3.4", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pin-project = "0.4.17"
|
pin-project = "1.0.0"
|
||||||
tokio = { version = "0.2.5", default-features = false }
|
tokio = { version = "0.2.5", default-features = false }
|
||||||
tokio-util = { version = "0.3.1", default-features = false, features = ["codec"] }
|
tokio-util = { version = "0.3.1", default-features = false, features = ["codec"] }
|
||||||
|
@@ -1,3 +0,0 @@
|
|||||||
# actix-ioframe
|
|
||||||
|
|
||||||
**This crate has been deprecated and removed.**
|
|
@@ -1,5 +1,9 @@
|
|||||||
# CHANGES
|
# CHANGES
|
||||||
|
|
||||||
|
## 0.1.3 - 2020-12-3
|
||||||
|
|
||||||
|
* Add `actix-reexport` feature
|
||||||
|
|
||||||
## 0.1.2 - 2020-05-18
|
## 0.1.2 - 2020-05-18
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-macros"
|
name = "actix-macros"
|
||||||
version = "0.1.2"
|
version = "0.1.3"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix runtime macros"
|
description = "Actix runtime macros"
|
||||||
repository = "https://github.com/actix/actix-net"
|
repository = "https://github.com/actix/actix-net"
|
||||||
@@ -16,6 +16,9 @@ proc-macro = true
|
|||||||
quote = "1.0.3"
|
quote = "1.0.3"
|
||||||
syn = { version = "^1", features = ["full"] }
|
syn = { version = "^1", features = ["full"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
actix-reexport = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "1.0"
|
actix-rt = "1.0"
|
||||||
|
|
||||||
|
@@ -33,14 +33,25 @@ pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
sig.asyncness = None;
|
sig.asyncness = None;
|
||||||
|
|
||||||
(quote! {
|
if cfg!(feature = "actix-reexport") {
|
||||||
#(#attrs)*
|
(quote! {
|
||||||
#vis #sig {
|
#(#attrs)*
|
||||||
actix_rt::System::new(stringify!(#name))
|
#vis #sig {
|
||||||
.block_on(async move { #body })
|
actix::System::new(stringify!(#name))
|
||||||
}
|
.block_on(async move { #body })
|
||||||
})
|
}
|
||||||
.into()
|
})
|
||||||
|
.into()
|
||||||
|
} else {
|
||||||
|
(quote! {
|
||||||
|
#(#attrs)*
|
||||||
|
#vis #sig {
|
||||||
|
actix_rt::System::new(stringify!(#name))
|
||||||
|
.block_on(async move { #body })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Marks async test function to be executed by actix runtime.
|
/// Marks async test function to be executed by actix runtime.
|
||||||
|
@@ -17,10 +17,9 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-macros = "0.1.0"
|
actix-macros = "0.1.0"
|
||||||
actix-threadpool = "0.3"
|
|
||||||
futures-channel = { version = "0.3.4", default-features = false }
|
|
||||||
futures-util = { version = "0.3.4", default-features = false, features = ["alloc"] }
|
|
||||||
copyless = "0.1.4"
|
copyless = "0.1.4"
|
||||||
|
futures-channel = "0.3.4"
|
||||||
|
futures-util = { version = "0.3.4", default-features = false, features = ["alloc"] }
|
||||||
smallvec = "1"
|
smallvec = "1"
|
||||||
tokio = { version = "0.2.6", default-features = false, features = ["rt-core", "rt-util", "io-driver", "tcp", "uds", "udp", "time", "signal", "stream"] }
|
tokio = { version = "0.2.6", default-features = false, features = ["rt-core", "rt-util", "io-driver", "tcp", "uds", "udp", "time", "signal", "stream"] }
|
||||||
|
|
||||||
|
@@ -134,10 +134,7 @@ impl Arbiter {
|
|||||||
.unbounded_send(SystemCommand::RegisterArbiter(id, arb));
|
.unbounded_send(SystemCommand::RegisterArbiter(id, arb));
|
||||||
|
|
||||||
// run loop
|
// run loop
|
||||||
let _ = match rt.block_on(stop_rx) {
|
let _ = rt.block_on(stop_rx).unwrap_or(1);
|
||||||
Ok(code) => code,
|
|
||||||
Err(_) => 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// unregister arbiter
|
// unregister arbiter
|
||||||
let _ = System::current()
|
let _ = System::current()
|
||||||
|
@@ -15,9 +15,6 @@ pub use self::builder::{Builder, SystemRunner};
|
|||||||
pub use self::runtime::Runtime;
|
pub use self::runtime::Runtime;
|
||||||
pub use self::system::System;
|
pub use self::system::System;
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub use actix_threadpool as blocking;
|
|
||||||
|
|
||||||
/// Spawns a future on the current arbiter.
|
/// Spawns a future on the current arbiter.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
@@ -1,216 +1,129 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased - 2020-xx-xx
|
||||||
|
* Added explicit info log message on accept queue pause. [#215]
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* workers must be greater than 0
|
## 1.0.4 - 2020-09-12
|
||||||
|
* Update actix-codec to 0.3.0.
|
||||||
|
* Workers must be greater than 0. [#167]
|
||||||
|
|
||||||
## [1.0.3] - 2020-05-19
|
[#167]: https://github.com/actix/actix-net/pull/167
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
|
## 1.0.3 - 2020-05-19
|
||||||
* Replace deprecated `net2` crate with `socket2` [#140]
|
* Replace deprecated `net2` crate with `socket2` [#140]
|
||||||
|
|
||||||
[#140]: https://github.com/actix/actix-net/pull/140
|
[#140]: https://github.com/actix/actix-net/pull/140
|
||||||
|
|
||||||
## [1.0.2] - 2020-02-26
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
|
## 1.0.2 - 2020-02-26
|
||||||
* Avoid error by calling `reregister()` on Windows [#103]
|
* Avoid error by calling `reregister()` on Windows [#103]
|
||||||
|
|
||||||
[#103]: https://github.com/actix/actix-net/pull/103
|
[#103]: https://github.com/actix/actix-net/pull/103
|
||||||
|
|
||||||
## [1.0.1] - 2019-12-29
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
|
## 1.0.1 - 2019-12-29
|
||||||
* Rename `.start()` method to `.run()`
|
* Rename `.start()` method to `.run()`
|
||||||
|
|
||||||
## [1.0.0] - 2019-12-11
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
|
## 1.0.0 - 2019-12-11
|
||||||
* Use actix-net releases
|
* Use actix-net releases
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.4] - 2019-12-08
|
## 1.0.0-alpha.4 - 2019-12-08
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Use actix-service 1.0.0-alpha.4
|
* Use actix-service 1.0.0-alpha.4
|
||||||
|
|
||||||
## [1.0.0-alpha.3] - 2019-12-07
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
|
## 1.0.0-alpha.3 - 2019-12-07
|
||||||
* Migrate to tokio 0.2
|
* Migrate to tokio 0.2
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fix compilation on non-unix platforms
|
* Fix compilation on non-unix platforms
|
||||||
|
|
||||||
* Better handling server configuration
|
* Better handling server configuration
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0-alpha.2] - 2019-12-02
|
## 1.0.0-alpha.2 - 2019-12-02
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Simplify server service (remove actix-server-config)
|
* Simplify server service (remove actix-server-config)
|
||||||
|
|
||||||
* Allow to wait on `Server` until server stops
|
* Allow to wait on `Server` until server stops
|
||||||
|
|
||||||
|
|
||||||
## [0.8.0-alpha.1] - 2019-11-22
|
## 0.8.0-alpha.1 - 2019-11-22
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Migrate to `std::future`
|
* Migrate to `std::future`
|
||||||
|
|
||||||
|
|
||||||
## [0.7.0] - 2019-10-04
|
## 0.7.0 - 2019-10-04
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Update `rustls` to 0.16
|
* Update `rustls` to 0.16
|
||||||
* Minimum required Rust version upped to 1.37.0
|
* Minimum required Rust version upped to 1.37.0
|
||||||
|
|
||||||
|
|
||||||
## [0.6.1] - 2019-09-25
|
## 0.6.1 - 2019-09-25
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Add UDS listening support to `ServerBuilder`
|
* Add UDS listening support to `ServerBuilder`
|
||||||
|
|
||||||
|
|
||||||
## [0.6.0] - 2019-07-18
|
## 0.6.0 - 2019-07-18
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Support Unix domain sockets #3
|
* Support Unix domain sockets #3
|
||||||
|
|
||||||
|
|
||||||
## [0.5.1] - 2019-05-18
|
## 0.5.1 - 2019-05-18
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* ServerBuilder::shutdown_timeout() accepts u64
|
* ServerBuilder::shutdown_timeout() accepts u64
|
||||||
|
|
||||||
|
|
||||||
## [0.5.0] - 2019-05-12
|
## 0.5.0 - 2019-05-12
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Add `Debug` impl for `SslError`
|
* Add `Debug` impl for `SslError`
|
||||||
|
|
||||||
* Derive debug for `Server` and `ServerCommand`
|
* Derive debug for `Server` and `ServerCommand`
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Upgrade to actix-service 0.4
|
* Upgrade to actix-service 0.4
|
||||||
|
|
||||||
|
|
||||||
## [0.4.3] - 2019-04-16
|
## 0.4.3 - 2019-04-16
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Re-export `IoStream` trait
|
* Re-export `IoStream` trait
|
||||||
|
* Depend on `ssl` and `rust-tls` features from actix-server-config
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Deppend on `ssl` and `rust-tls` features from actix-server-config
|
|
||||||
|
|
||||||
|
|
||||||
## [0.4.2] - 2019-03-30
|
## 0.4.2 - 2019-03-30
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fix SIGINT force shutdown
|
* Fix SIGINT force shutdown
|
||||||
|
|
||||||
|
|
||||||
## [0.4.1] - 2019-03-14
|
## 0.4.1 - 2019-03-14
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* `SystemRuntime::on_start()` - allow to run future before server service initialization
|
* `SystemRuntime::on_start()` - allow to run future before server service initialization
|
||||||
|
|
||||||
|
|
||||||
## [0.4.0] - 2019-03-12
|
## 0.4.0 - 2019-03-12
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Use `ServerConfig` for service factory
|
* Use `ServerConfig` for service factory
|
||||||
|
|
||||||
* Wrap tcp socket to `Io` type
|
* Wrap tcp socket to `Io` type
|
||||||
|
|
||||||
* Upgrade actix-service
|
* Upgrade actix-service
|
||||||
|
|
||||||
|
|
||||||
## [0.3.1] - 2019-03-04
|
## 0.3.1 - 2019-03-04
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Add `ServerBuilder::maxconnrate` sets the maximum per-worker number of concurrent connections
|
* Add `ServerBuilder::maxconnrate` sets the maximum per-worker number of concurrent connections
|
||||||
|
|
||||||
* Add helper ssl error `SslError`
|
* Add helper ssl error `SslError`
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Rename `StreamServiceFactory` to `ServiceFactory`
|
* Rename `StreamServiceFactory` to `ServiceFactory`
|
||||||
|
|
||||||
* Deprecate `StreamServiceFactory`
|
* Deprecate `StreamServiceFactory`
|
||||||
|
|
||||||
|
|
||||||
## [0.3.0] - 2019-03-02
|
## 0.3.0 - 2019-03-02
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Use new `NewService` trait
|
* Use new `NewService` trait
|
||||||
|
|
||||||
|
|
||||||
## [0.2.1] - 2019-02-09
|
## 0.2.1 - 2019-02-09
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Drop service response
|
* Drop service response
|
||||||
|
|
||||||
|
|
||||||
## [0.2.0] - 2019-02-01
|
## 0.2.0 - 2019-02-01
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Migrate to actix-service 0.2
|
* Migrate to actix-service 0.2
|
||||||
|
|
||||||
* Updated rustls dependency
|
* Updated rustls dependency
|
||||||
|
|
||||||
|
|
||||||
## [0.1.3] - 2018-12-21
|
## 0.1.3 - 2018-12-21
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fix max concurrent connections handling
|
* Fix max concurrent connections handling
|
||||||
|
|
||||||
|
|
||||||
## [0.1.2] - 2018-12-12
|
## 0.1.2 - 2018-12-12
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* rename ServiceConfig::rt() to ServiceConfig::apply()
|
* rename ServiceConfig::rt() to ServiceConfig::apply()
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fix back-pressure for concurrent ssl handshakes
|
* Fix back-pressure for concurrent ssl handshakes
|
||||||
|
|
||||||
|
|
||||||
## [0.1.1] - 2018-12-11
|
## 0.1.1 - 2018-12-11
|
||||||
|
|
||||||
* Fix signal handling on windows
|
* Fix signal handling on windows
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0] - 2018-12-09
|
## 0.1.0 - 2018-12-09
|
||||||
|
|
||||||
* Move server to separate crate
|
* Move server to separate crate
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-server"
|
name = "actix-server"
|
||||||
version = "1.0.3"
|
version = "1.0.4"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Actix server - General purpose tcp server"
|
description = "General purpose TCP server built for the Actix ecosystem"
|
||||||
keywords = ["network", "framework", "async", "futures"]
|
keywords = ["network", "framework", "async", "futures"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
repository = "https://github.com/actix/actix-net.git"
|
repository = "https://github.com/actix/actix-net.git"
|
||||||
@@ -11,7 +11,6 @@ categories = ["network-programming", "asynchronous"]
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
exclude = [".gitignore", ".cargo/config"]
|
exclude = [".gitignore", ".cargo/config"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
workspace = ".."
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "actix_server"
|
name = "actix_server"
|
||||||
@@ -21,13 +20,13 @@ path = "src/lib.rs"
|
|||||||
default = []
|
default = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "1.0.1"
|
actix-service = "1.0.6"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.1.1"
|
||||||
actix-codec = "0.3.0"
|
actix-codec = "0.3.0"
|
||||||
actix-utils = "2.0.0"
|
actix-utils = "2.0.0"
|
||||||
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
num_cpus = "1.11"
|
num_cpus = "1.13"
|
||||||
mio = "0.6.19"
|
mio = "0.6.19"
|
||||||
socket2 = "0.3"
|
socket2 = "0.3"
|
||||||
futures-channel = { version = "0.3.4", default-features = false }
|
futures-channel = { version = "0.3.4", default-features = false }
|
||||||
@@ -42,3 +41,4 @@ mio-uds = { version = "0.6.7" }
|
|||||||
bytes = "0.5"
|
bytes = "0.5"
|
||||||
env_logger = "0.7"
|
env_logger = "0.7"
|
||||||
actix-testing = "1.0.0"
|
actix-testing = "1.0.0"
|
||||||
|
tokio = { version = "0.2", features = ["io-util"] }
|
||||||
|
88
actix-server/examples/basic.rs
Normal file
88
actix-server/examples/basic.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
//! Simple composite-service TCP echo server.
|
||||||
|
//!
|
||||||
|
//! Using the following command:
|
||||||
|
//!
|
||||||
|
//! ```sh
|
||||||
|
//! nc 127.0.0.1 8080
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Start typing. When you press enter the typed line will be echoed back. The server will log
|
||||||
|
//! the length of each line it echos and the total size of data sent when the connection is closed.
|
||||||
|
|
||||||
|
use std::sync::{
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
Arc,
|
||||||
|
};
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
|
use actix_rt::net::TcpStream;
|
||||||
|
use actix_server::Server;
|
||||||
|
use actix_service::pipeline_factory;
|
||||||
|
use bytes::BytesMut;
|
||||||
|
use futures_util::future::ok;
|
||||||
|
use log::{error, info};
|
||||||
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
|
#[actix_rt::main]
|
||||||
|
async fn main() -> io::Result<()> {
|
||||||
|
env::set_var("RUST_LOG", "actix=trace,basic=trace");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let count = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
|
let addr = ("127.0.0.1", 8080);
|
||||||
|
info!("starting server on port: {}", &addr.0);
|
||||||
|
|
||||||
|
// Bind socket address and start worker(s). By default, the server uses the number of available
|
||||||
|
// logical CPU cores as the worker count. For this reason, the closure passed to bind needs
|
||||||
|
// to return a service *factory*; so it can be created once per worker.
|
||||||
|
Server::build()
|
||||||
|
.bind("echo", addr, move || {
|
||||||
|
let count = Arc::clone(&count);
|
||||||
|
let num2 = Arc::clone(&count);
|
||||||
|
|
||||||
|
pipeline_factory(move |mut stream: TcpStream| {
|
||||||
|
let count = Arc::clone(&count);
|
||||||
|
|
||||||
|
async move {
|
||||||
|
let num = count.fetch_add(1, Ordering::SeqCst);
|
||||||
|
let num = num + 1;
|
||||||
|
|
||||||
|
let mut size = 0;
|
||||||
|
let mut buf = BytesMut::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match stream.read_buf(&mut buf).await {
|
||||||
|
// end of stream; bail from loop
|
||||||
|
Ok(0) => break,
|
||||||
|
|
||||||
|
// more bytes to process
|
||||||
|
Ok(bytes_read) => {
|
||||||
|
info!("[{}] read {} bytes", num, bytes_read);
|
||||||
|
stream.write_all(&buf[size..]).await.unwrap();
|
||||||
|
size += bytes_read;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stream error; bail from loop with error
|
||||||
|
Err(err) => {
|
||||||
|
error!("Stream Error: {:?}", err);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// send data down service pipeline
|
||||||
|
Ok((buf.freeze(), size))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map_err(|err| error!("Service Error: {:?}", err))
|
||||||
|
.and_then(move |(_, size)| {
|
||||||
|
let num = num2.load(Ordering::SeqCst);
|
||||||
|
info!("[{}] total bytes read: {}", num, size);
|
||||||
|
ok(size)
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.workers(1)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
@@ -381,6 +381,7 @@ impl Accept {
|
|||||||
self.backpressure = true;
|
self.backpressure = true;
|
||||||
for (_, info) in self.sockets.iter() {
|
for (_, info) in self.sockets.iter() {
|
||||||
let _ = self.poll.deregister(&info.sock);
|
let _ = self.poll.deregister(&info.sock);
|
||||||
|
info!("Accepting connections on {} has been paused", info.addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
//! General purpose tcp server
|
//! General purpose TCP server.
|
||||||
#![deny(rust_2018_idioms, warnings)]
|
|
||||||
#![allow(clippy::type_complexity)]
|
#![deny(rust_2018_idioms)]
|
||||||
|
|
||||||
mod accept;
|
mod accept;
|
||||||
mod builder;
|
mod builder;
|
||||||
@@ -19,7 +19,7 @@ pub use self::service::ServiceFactory;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use self::socket::FromStream;
|
pub use self::socket::FromStream;
|
||||||
|
|
||||||
/// Socket id token
|
/// Socket ID token
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub(crate) struct Token(usize);
|
pub(crate) struct Token(usize);
|
||||||
|
|
||||||
|
@@ -17,8 +17,10 @@ use crate::socket::{FromStream, StdStream};
|
|||||||
pub(crate) enum ServerMessage {
|
pub(crate) enum ServerMessage {
|
||||||
/// New stream
|
/// New stream
|
||||||
Connect(StdStream),
|
Connect(StdStream),
|
||||||
/// Gracefull shutdown
|
|
||||||
|
/// Gracefully shutdown
|
||||||
Shutdown(Duration),
|
Shutdown(Duration),
|
||||||
|
|
||||||
/// Force shutdown
|
/// Force shutdown
|
||||||
ForceShutdown,
|
ForceShutdown,
|
||||||
}
|
}
|
||||||
|
@@ -303,6 +303,7 @@ enum WorkerState {
|
|||||||
Restarting(
|
Restarting(
|
||||||
usize,
|
usize,
|
||||||
Token,
|
Token,
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
Pin<Box<dyn Future<Output = Result<Vec<(Token, BoxedServerService)>, ()>>>>,
|
Pin<Box<dyn Future<Output = Result<Vec<(Token, BoxedServerService)>, ()>>>>,
|
||||||
),
|
),
|
||||||
Shutdown(
|
Shutdown(
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
* Upgrade `pin-project` to `1.0`.
|
||||||
|
|
||||||
## 1.0.6 - 2020-08-09
|
## 1.0.6 - 2020-08-09
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures-util = "0.3.1"
|
futures-util = "0.3.1"
|
||||||
pin-project = "0.4.17"
|
pin-project = "1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.0.0"
|
||||||
|
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
> Service trait and combinators for representing asynchronous request/response operations.
|
> Service trait and combinators for representing asynchronous request/response operations.
|
||||||
|
|
||||||
See documentation for detailed explanations these components: [https://docs.rs/actix-service](docs).
|
See documentation for detailed explanations these components: [https://docs.rs/actix-service][docs].
|
||||||
|
|
||||||
[docs]: https://docs.rs/actix-service
|
[docs]: https://docs.rs/actix-service
|
||||||
|
@@ -9,7 +9,7 @@ use super::{Service, ServiceFactory};
|
|||||||
/// Service for the `and_then` combinator, chaining a computation onto the end
|
/// Service for the `and_then` combinator, chaining a computation onto the end
|
||||||
/// of another service which completes successfully.
|
/// of another service which completes successfully.
|
||||||
///
|
///
|
||||||
/// This is created by the `ServiceExt::and_then` method.
|
/// This is created by the `Pipeline::and_then` method.
|
||||||
pub(crate) struct AndThenService<A, B>(Rc<RefCell<(A, B)>>);
|
pub(crate) struct AndThenService<A, B>(Rc<RefCell<(A, B)>>);
|
||||||
|
|
||||||
impl<A, B> AndThenService<A, B> {
|
impl<A, B> AndThenService<A, B> {
|
||||||
|
@@ -5,7 +5,7 @@ use std::task::{Context, Poll};
|
|||||||
|
|
||||||
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use super::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
/// Apply tranform function to a service.
|
/// Apply transform function to a service.
|
||||||
pub fn apply_fn<T, F, R, In, Out, Err, U>(service: U, f: F) -> Apply<T, F, R, In, Out, Err>
|
pub fn apply_fn<T, F, R, In, Out, Err, U>(service: U, f: F) -> Apply<T, F, R, In, Out, Err>
|
||||||
where
|
where
|
||||||
T: Service<Error = Err>,
|
T: Service<Error = Err>,
|
||||||
@@ -16,7 +16,7 @@ where
|
|||||||
Apply::new(service.into_service(), f)
|
Apply::new(service.into_service(), f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Service factory that prodices `apply_fn` service.
|
/// Service factory that produces `apply_fn` service.
|
||||||
pub fn apply_fn_factory<T, F, R, In, Out, Err, U>(
|
pub fn apply_fn_factory<T, F, R, In, Out, Err, U>(
|
||||||
service: U,
|
service: U,
|
||||||
f: F,
|
f: F,
|
||||||
|
@@ -9,7 +9,7 @@ use crate::map_init_err::MapInitErr;
|
|||||||
use crate::then::{ThenService, ThenServiceFactory};
|
use crate::then::{ThenService, ThenServiceFactory};
|
||||||
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
|
||||||
|
|
||||||
/// Contruct new pipeline with one service in pipeline chain.
|
/// Construct new pipeline with one service in pipeline chain.
|
||||||
pub fn pipeline<F, T>(service: F) -> Pipeline<T>
|
pub fn pipeline<F, T>(service: F) -> Pipeline<T>
|
||||||
where
|
where
|
||||||
F: IntoService<T>,
|
F: IntoService<T>,
|
||||||
@@ -20,7 +20,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contruct new pipeline factory with one service factory.
|
/// Construct new pipeline factory with one service factory.
|
||||||
pub fn pipeline_factory<T, F>(factory: F) -> PipelineFactory<T>
|
pub fn pipeline_factory<T, F>(factory: F) -> PipelineFactory<T>
|
||||||
where
|
where
|
||||||
T: ServiceFactory,
|
T: ServiceFactory,
|
||||||
|
@@ -70,7 +70,7 @@ where
|
|||||||
/// timeout: Duration,
|
/// timeout: Duration,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// impl<S> Transform<S> for TimeoutTransform<E>
|
/// impl<S> Transform<S> for TimeoutTransform
|
||||||
/// where
|
/// where
|
||||||
/// S: Service,
|
/// S: Service,
|
||||||
/// {
|
/// {
|
||||||
@@ -115,7 +115,7 @@ pub trait Transform<S> {
|
|||||||
/// Creates and returns a new Transform component, asynchronously
|
/// Creates and returns a new Transform component, asynchronously
|
||||||
fn new_transform(&self, service: S) -> Self::Future;
|
fn new_transform(&self, service: S) -> Self::Future;
|
||||||
|
|
||||||
/// Map this transforms's factory error to a different error,
|
/// Map this transform's factory error to a different error,
|
||||||
/// returning a new transform service factory.
|
/// returning a new transform service factory.
|
||||||
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
|
fn map_init_err<F, E>(self, f: F) -> TransformMapInitErr<Self, S, F, E>
|
||||||
where
|
where
|
||||||
|
@@ -37,7 +37,7 @@ pub use actix_macros::test;
|
|||||||
/// ```
|
/// ```
|
||||||
pub struct TestServer;
|
pub struct TestServer;
|
||||||
|
|
||||||
/// Test server runstime
|
/// Test server runtime
|
||||||
pub struct TestServerRuntime {
|
pub struct TestServerRuntime {
|
||||||
addr: net::SocketAddr,
|
addr: net::SocketAddr,
|
||||||
host: String,
|
host: String,
|
||||||
@@ -107,7 +107,7 @@ impl TestServer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get firat available unused local address
|
/// Get first available unused local address
|
||||||
pub fn unused_addr() -> net::SocketAddr {
|
pub fn unused_addr() -> net::SocketAddr {
|
||||||
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
|
||||||
let socket =
|
let socket =
|
||||||
|
@@ -3,7 +3,7 @@ name = "actix-tls"
|
|||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "TLS acceptor services for Actix ecosystem."
|
description = "TLS acceptor services for Actix ecosystem."
|
||||||
keywords = ["network", "framework", "async", "futures", "tls", "ssl"]
|
keywords = ["network", "framework", "async", "tls", "ssl"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
repository = "https://github.com/actix/actix-net.git"
|
repository = "https://github.com/actix/actix-net.git"
|
||||||
documentation = "https://docs.rs/actix-tls/"
|
documentation = "https://docs.rs/actix-tls/"
|
||||||
@@ -18,6 +18,10 @@ features = ["openssl", "rustls", "nativetls"]
|
|||||||
name = "actix_tls"
|
name = "actix_tls"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "basic"
|
||||||
|
required-features = ["rustls"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
@@ -53,4 +57,8 @@ tokio-tls = { version = "0.3", optional = true }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
bytes = "0.5"
|
bytes = "0.5"
|
||||||
actix-testing = { version = "1.0.0" }
|
log = "0.4"
|
||||||
|
env_logger = "0.7"
|
||||||
|
actix-testing = "1.0.0"
|
||||||
|
actix-server = "1"
|
||||||
|
actix-rt = "1"
|
||||||
|
82
actix-tls/examples/basic.rs
Normal file
82
actix-tls/examples/basic.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
//! TLS Acceptor Server
|
||||||
|
//!
|
||||||
|
//! Using either HTTPie (`http`) or cURL:
|
||||||
|
//!
|
||||||
|
//! This commands will produce errors in the server log:
|
||||||
|
//! ```sh
|
||||||
|
//! curl 127.0.0.1:8443
|
||||||
|
//! http 127.0.0.1:8443
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! These commands will show "empty reply" on the client but will debug print the TLS stream info
|
||||||
|
//! in the server log, indicating a successful TLS handshake:
|
||||||
|
//! ```sh
|
||||||
|
//! curl -k https://127.0.0.1:8443
|
||||||
|
//! http --verify=false https://127.0.0.1:8443
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
fs::File,
|
||||||
|
io::{self, BufReader},
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
Arc,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
use actix_server::Server;
|
||||||
|
use actix_service::pipeline_factory;
|
||||||
|
use actix_tls::rustls::Acceptor as RustlsAcceptor;
|
||||||
|
use futures_util::future::ok;
|
||||||
|
use log::info;
|
||||||
|
use rust_tls::{
|
||||||
|
internal::pemfile::certs, internal::pemfile::rsa_private_keys, NoClientAuth, ServerConfig,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct ServiceState {
|
||||||
|
num: Arc<AtomicUsize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_rt::main]
|
||||||
|
async fn main() -> io::Result<()> {
|
||||||
|
env::set_var("RUST_LOG", "actix=trace,basic=trace");
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let mut tls_config = ServerConfig::new(NoClientAuth::new());
|
||||||
|
|
||||||
|
// Load TLS key and cert files
|
||||||
|
let cert_file = &mut BufReader::new(File::open("./examples/cert.pem").unwrap());
|
||||||
|
let key_file = &mut BufReader::new(File::open("./examples/key.pem").unwrap());
|
||||||
|
|
||||||
|
let cert_chain = certs(cert_file).unwrap();
|
||||||
|
let mut keys = rsa_private_keys(key_file).unwrap();
|
||||||
|
tls_config
|
||||||
|
.set_single_cert(cert_chain, keys.remove(0))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let tls_acceptor = RustlsAcceptor::new(tls_config);
|
||||||
|
|
||||||
|
let count = Arc::new(AtomicUsize::new(0));
|
||||||
|
|
||||||
|
let addr = ("127.0.0.1", 8443);
|
||||||
|
info!("starting server on port: {}", &addr.0);
|
||||||
|
|
||||||
|
Server::build()
|
||||||
|
.bind("tls-example", addr, move || {
|
||||||
|
let count = Arc::clone(&count);
|
||||||
|
|
||||||
|
// Set up TLS service factory
|
||||||
|
pipeline_factory(tls_acceptor.clone())
|
||||||
|
.map_err(|err| println!("Rustls error: {:?}", err))
|
||||||
|
.and_then(move |stream| {
|
||||||
|
let num = count.fetch_add(1, Ordering::Relaxed);
|
||||||
|
info!("[{}] Got TLS connection: {:?}", num, stream);
|
||||||
|
ok(())
|
||||||
|
})
|
||||||
|
})?
|
||||||
|
.workers(1)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
25
actix-tls/examples/cert.pem
Normal file
25
actix-tls/examples/cert.pem
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIENjCCAp6gAwIBAgIRANp+D9pBErdacw6KjrwJ+4swDQYJKoZIhvcNAQELBQAw
|
||||||
|
bTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSEwHwYDVQQLDBhyb2JA
|
||||||
|
c29tYnJhLng1Mi5kZXYgKFJvYikxKDAmBgNVBAMMH21rY2VydCByb2JAc29tYnJh
|
||||||
|
Lng1Mi5kZXYgKFJvYikwHhcNMTkwNjAxMDAwMDAwWhcNMzAwOTEzMDIzNDI0WjBM
|
||||||
|
MScwJQYDVQQKEx5ta2NlcnQgZGV2ZWxvcG1lbnQgY2VydGlmaWNhdGUxITAfBgNV
|
||||||
|
BAsMGHJvYkBzb21icmEueDUyLmRldiAoUm9iKTCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||||
|
ggEPADCCAQoCggEBALYAn8dsQUDTp8SptAtkiAySvQYLpAOct3/OjBn+dSYfbQcp
|
||||||
|
Ph9w/Zo83Msl7Fb1DBvADHFtyBpESATZ2chS5fwCAwUFTlKrzMk3qauEoJ3cCQa8
|
||||||
|
ccqhTMLeT38jRlhXrMHWBfz0ipqy+yTLWeM32LX8s0jPbbsZ3gVJ/Ls4qm0CTaqb
|
||||||
|
zRdcQ7GTVKYet5DR7ZvwvAaLtWk/iiHKwnOveuF27HNlxj0Rwd/lhJ/t9x8xJwyR
|
||||||
|
MTdm852KQadI8xOSbWNK4j9419yzKjUEMKgn78wT/7DQfeKKCAreHa4MaEw4+koD
|
||||||
|
2Bqb+V4fI6T84VvXkNG3CjSpmIiYGlIE1LVgBL8CAwEAAaNyMHAwDgYDVR0PAQH/
|
||||||
|
BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHwYDVR0j
|
||||||
|
BBgwFoAUto/ox0MqZShmQpViV/gjfJKrMDkwGgYDVR0RBBMwEYIJbG9jYWxob3N0
|
||||||
|
hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBgQBUCMzqTY0sg+61gh8gKS5TCL6qs0R1
|
||||||
|
xys/EFFaD5JYUsfM/HyhHd0jq+x5Pd3mB2Jvhoq9xhjMwP11H8Uw5lLBHA8USdF9
|
||||||
|
EiLW1GvT3/gLfMqb0lPk0RMRBeX8c0QbDtqdiUCE7S6zJbZ5gjFeRuFNjdcGA1Ss
|
||||||
|
8CPPts2mns5cwah6H7T/BFzj5aR9Qe14vo1Rpr5gD5CpHvk1t16q7YsczQfVMvt3
|
||||||
|
Ydk6p0rwA8Z5okQK7y3qKPZI+//ygWL6ZBjVjl1/Al8vybG2UYjYgfMBwaVvMiDJ
|
||||||
|
j/vCdVmlvGb+MZlZID/p2veaNeEKgi1A1EOj3sNuQYXXFfSD9mdamX7JIfGi/U7v
|
||||||
|
ivvUjJUbzGrUngldt5iCKqcCQum7nlzu9sT1Tm2t/n4tz/btrI+Wimg8riSzM+Nk
|
||||||
|
dfuvv4NbWe6Th5460HH8mMvfPZSB8dCoxwm98tuqcMXLkR1RJX5Z8LYAaPTsUs/h
|
||||||
|
HxQCY4EaY7feZ/qFal9FGwvpzVr3/XjgSCU=
|
||||||
|
-----END CERTIFICATE-----
|
27
actix-tls/examples/key.pem
Normal file
27
actix-tls/examples/key.pem
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEAtgCfx2xBQNOnxKm0C2SIDJK9BgukA5y3f86MGf51Jh9tByk+
|
||||||
|
H3D9mjzcyyXsVvUMG8AMcW3IGkRIBNnZyFLl/AIDBQVOUqvMyTepq4SgndwJBrxx
|
||||||
|
yqFMwt5PfyNGWFeswdYF/PSKmrL7JMtZ4zfYtfyzSM9tuxneBUn8uziqbQJNqpvN
|
||||||
|
F1xDsZNUph63kNHtm/C8Bou1aT+KIcrCc6964Xbsc2XGPRHB3+WEn+33HzEnDJEx
|
||||||
|
N2bznYpBp0jzE5JtY0riP3jX3LMqNQQwqCfvzBP/sNB94ooICt4drgxoTDj6SgPY
|
||||||
|
Gpv5Xh8jpPzhW9eQ0bcKNKmYiJgaUgTUtWAEvwIDAQABAoIBADC0Zg21+Jhii6jj
|
||||||
|
SR0rYAUNV6xAfTnCPJDlMzTZlXwIOOMLtGYxlIwr8WIj2eVDWmQqtqm8GSp+T0+N
|
||||||
|
BOzI0mboGurDCryw4PKQBMWzjk/wTDITR9hT5fjYCSoaxH5rp/2PSrbwsg7ICtFD
|
||||||
|
4eAeV84Lu+amK9VADNwZepqXhXP6EDOY5yovkwzOQNDM/qVzHSe9EoFP74M/oWnY
|
||||||
|
ohIuWdZzwAZuTA5SUjPygiVzs/vhsrSE9crMIzr5VgKBi+C+ALkrL7Lc4GlRPI4r
|
||||||
|
6VsbIxZHa7who+FhjZ0cVfdXHH47QDdf10X5bEXsaFBvGGCLtkQ3XEpov6GOlaH+
|
||||||
|
aY7fzPECgYEA4LGloaMC9J27uyPxHkQwEehexmJdIu0vNUefv5yiO9PbvrjvYnh7
|
||||||
|
JxRVgv1fy2bRMOvg19TujCYRZdkrLDqSDsfFfEiThvlFBRZfKKIHmWdyfvIe9Jp9
|
||||||
|
rqdxhWAco7FoM+W6c8c4iR4xs8/GA60CVcAiTLqgPWWzn12fesiULi0CgYEAz1xD
|
||||||
|
OulJyfpHVGQ6ZM1wR0SZ9H9GS3BenpL2ue5uBfe3hM+JIAAM61Y48wJuCWT5EvfL
|
||||||
|
FgnH3oCo7SYGcgGkERS8H7k67DJCLlqDo/3FC7lX/irz+ya/FoZmKBagvjEUWhpe
|
||||||
|
Bb2dRIbqsG0lsCzU9MVrgtvodD0MBTyt0RM5fhsCgYEAhgYQiLhGBAituLN4mBgO
|
||||||
|
IDBdj7GOYk3dkcc2J0HTlyIIeduvlinNM4Myel6NrDKY5rhbtgGhhGEUkY6W7NvG
|
||||||
|
0SAh0L8tmB3JKH6upfr3023b4pKjGj2oZ+wij27DxnQEdqg5reOP+mHTPbDaKMki
|
||||||
|
kml3TBMpj1XBbXaXsNJBaMUCgYEAnnNzEC4563QrU2pvUJ3HgT4Dotgqv/Sy6NuG
|
||||||
|
W1e9jSPYgU0RDHndZWtygwdFTDpzNbJR5po8t2J7MxQOcsmcNE0y387sHpbdCYyy
|
||||||
|
8Po2uxm7CoaJ/02BUVYL8/Aujob0dVGWrS5SYY3zAjO1S+VGKXA+EjW2cDRB3jKa
|
||||||
|
45ucICcCgYBdMxB5Oj6GpdewWWaBss9dwHtDaD4oVGYIBbIc2qdyCYixWdW9NccV
|
||||||
|
fRJs0ulGrpg9OtyWbwZASu2jz55+s3hi4rnrcaXKiIh9Rs25v1irF6Dmduvo7CaN
|
||||||
|
Mf7zBg7LUttmqN6D3npIAxmBULl8KRfjnt6U2tJolF5X0qQ1uqnnTA==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@@ -1,6 +1,7 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## Unreleased - 2020-xx-xx
|
## Unreleased - 2020-xx-xx
|
||||||
|
* Upgrade `pin-project` to `1.0`.
|
||||||
|
|
||||||
## 2.0.0 - 2020-08-23
|
## 2.0.0 - 2020-08-23
|
||||||
* No changes from beta 1.
|
* No changes from beta 1.
|
||||||
|
@@ -26,5 +26,5 @@ futures-channel = { version = "0.3.4", default-features = false }
|
|||||||
futures-sink = { version = "0.3.4", default-features = false }
|
futures-sink = { version = "0.3.4", default-features = false }
|
||||||
futures-util = { version = "0.3.4", default-features = false }
|
futures-util = { version = "0.3.4", default-features = false }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
pin-project = "0.4.17"
|
pin-project = "1.0.0"
|
||||||
slab = "0.4"
|
slab = "0.4"
|
||||||
|
@@ -1,77 +0,0 @@
|
|||||||
//! simple composite service
|
|
||||||
//! build: cargo run --example basic --features "ssl"
|
|
||||||
//! to test: curl https://127.0.0.1:8443/ -k
|
|
||||||
use std::sync::{
|
|
||||||
atomic::{AtomicUsize, Ordering},
|
|
||||||
Arc,
|
|
||||||
};
|
|
||||||
use std::{env, fmt, io};
|
|
||||||
|
|
||||||
use actix_codec::{AsyncRead, AsyncWrite};
|
|
||||||
use actix_rt::System;
|
|
||||||
use actix_server::{Io, Server};
|
|
||||||
use actix_service::{service_fn, NewService};
|
|
||||||
use futures_util::{future, Future};
|
|
||||||
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
|
||||||
use tokio_openssl::SslAcceptorExt;
|
|
||||||
|
|
||||||
/// Simple logger service, it just prints fact of the new connections
|
|
||||||
fn logger<T: AsyncRead + AsyncWrite + fmt::Debug>(
|
|
||||||
stream: T,
|
|
||||||
) -> impl Future<Item = T, Error = ()> {
|
|
||||||
println!("New connection: {:?}", stream);
|
|
||||||
future::ok(stream)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
|
||||||
env::set_var("RUST_LOG", "actix_net=trace");
|
|
||||||
env_logger::init();
|
|
||||||
|
|
||||||
let sys = System::new("test");
|
|
||||||
|
|
||||||
// load ssl keys
|
|
||||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
|
||||||
builder
|
|
||||||
.set_private_key_file("./examples/key.pem", SslFiletype::PEM)
|
|
||||||
.unwrap();
|
|
||||||
builder
|
|
||||||
.set_certificate_chain_file("./examples/cert.pem")
|
|
||||||
.unwrap();
|
|
||||||
let acceptor = builder.build();
|
|
||||||
|
|
||||||
let num = Arc::new(AtomicUsize::new(0));
|
|
||||||
|
|
||||||
// bind socket address and start workers. By default server uses number of
|
|
||||||
// available logical cpu as threads count. actix net start separate
|
|
||||||
// instances of service pipeline in each worker.
|
|
||||||
Server::build()
|
|
||||||
.bind(
|
|
||||||
// configure service pipeline
|
|
||||||
"basic",
|
|
||||||
"0.0.0.0:8443",
|
|
||||||
move || {
|
|
||||||
let num = num.clone();
|
|
||||||
let acceptor = acceptor.clone();
|
|
||||||
|
|
||||||
// service for converting incoming TcpStream to a SslStream<TcpStream>
|
|
||||||
service_fn(move |stream: Io<tokio_tcp::TcpStream>| {
|
|
||||||
SslAcceptorExt::accept_async(&acceptor, stream.into_parts().0)
|
|
||||||
.map_err(|e| println!("Openssl error: {}", e))
|
|
||||||
})
|
|
||||||
// .and_then() combinator uses other service to convert incoming `Request` to a
|
|
||||||
// `Response` and then uses that response as an input for next
|
|
||||||
// service. in this case, on success we use `logger` service
|
|
||||||
.and_then(logger)
|
|
||||||
// Next service counts number of connections
|
|
||||||
.and_then(move |_| {
|
|
||||||
let num = num.fetch_add(1, Ordering::Relaxed);
|
|
||||||
println!("got ssl connection {:?}", num);
|
|
||||||
future::ok(())
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.start();
|
|
||||||
|
|
||||||
sys.run()
|
|
||||||
}
|
|
@@ -1,31 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
1QU=
|
|
||||||
-----END CERTIFICATE-----
|
|
@@ -1,51 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
@@ -1,51 +0,0 @@
|
|||||||
use std::io;
|
|
||||||
use std::sync::{
|
|
||||||
atomic::{AtomicUsize, Ordering},
|
|
||||||
Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use actix_rt::System;
|
|
||||||
use actix_server::{ssl, Server};
|
|
||||||
use actix_service::NewService;
|
|
||||||
use futures_util::future;
|
|
||||||
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct ServiceState {
|
|
||||||
num: Arc<AtomicUsize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
|
||||||
let sys = System::new("test");
|
|
||||||
|
|
||||||
// load ssl keys
|
|
||||||
let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
|
|
||||||
builder
|
|
||||||
.set_private_key_file("./examples/key.pem", SslFiletype::PEM)
|
|
||||||
.unwrap();
|
|
||||||
builder
|
|
||||||
.set_certificate_chain_file("./examples/cert.pem")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let num = Arc::new(AtomicUsize::new(0));
|
|
||||||
let openssl = ssl::OpensslAcceptor::new(builder.build());
|
|
||||||
|
|
||||||
// server start mutiple workers, it runs supplied `Fn` in each worker.
|
|
||||||
Server::build()
|
|
||||||
.bind("test-ssl", "0.0.0.0:8443", move || {
|
|
||||||
let num = num.clone();
|
|
||||||
|
|
||||||
// configure service
|
|
||||||
openssl
|
|
||||||
.clone()
|
|
||||||
.map_err(|e| println!("Openssl error: {}", e))
|
|
||||||
.and_then(move |_| {
|
|
||||||
let num = num.fetch_add(1, Ordering::Relaxed);
|
|
||||||
println!("got ssl connection {:?}", num);
|
|
||||||
future::ok(())
|
|
||||||
})
|
|
||||||
})?
|
|
||||||
.start();
|
|
||||||
|
|
||||||
sys.run()
|
|
||||||
}
|
|
@@ -1,53 +1,55 @@
|
|||||||
# Changes
|
# Changes
|
||||||
|
|
||||||
## [0.2.4] - 2019-12-31
|
## Unreleased - 2020-xx-xx
|
||||||
|
|
||||||
|
|
||||||
|
## 0.2.5 - 2020-09-20
|
||||||
|
* Fix `from_hex()` method
|
||||||
|
|
||||||
|
|
||||||
|
## 0.2.4 - 2019-12-31
|
||||||
* Add `ResourceDef::resource_path_named()` path generation method
|
* Add `ResourceDef::resource_path_named()` path generation method
|
||||||
|
|
||||||
## [0.2.3] - 2019-12-25
|
|
||||||
|
|
||||||
|
## 0.2.3 - 2019-12-25
|
||||||
* Add impl `IntoPattern` for `&String`
|
* Add impl `IntoPattern` for `&String`
|
||||||
|
|
||||||
## [0.2.2] - 2019-12-25
|
|
||||||
|
|
||||||
|
## 0.2.2 - 2019-12-25
|
||||||
* Use `IntoPattern` for `RouterBuilder::path()`
|
* Use `IntoPattern` for `RouterBuilder::path()`
|
||||||
|
|
||||||
## [0.2.1] - 2019-12-25
|
|
||||||
|
|
||||||
|
## 0.2.1 - 2019-12-25
|
||||||
* Add `IntoPattern` trait
|
* Add `IntoPattern` trait
|
||||||
|
|
||||||
* Add multi-pattern resources
|
* Add multi-pattern resources
|
||||||
|
|
||||||
## [0.2.0] - 2019-12-07
|
|
||||||
|
|
||||||
|
## 0.2.0 - 2019-12-07
|
||||||
* Update http to 0.2
|
* Update http to 0.2
|
||||||
|
|
||||||
* Update regex to 1.3
|
* Update regex to 1.3
|
||||||
|
|
||||||
* Use bytestring instead of string
|
* Use bytestring instead of string
|
||||||
|
|
||||||
## [0.1.5] - 2019-05-15
|
|
||||||
|
|
||||||
|
## 0.1.5 - 2019-05-15
|
||||||
* Remove debug prints
|
* Remove debug prints
|
||||||
|
|
||||||
## [0.1.4] - 2019-05-15
|
|
||||||
|
|
||||||
|
## 0.1.4 - 2019-05-15
|
||||||
* Fix checked resource match
|
* Fix checked resource match
|
||||||
|
|
||||||
## [0.1.3] - 2019-04-22
|
|
||||||
|
|
||||||
|
## 0.1.3 - 2019-04-22
|
||||||
* Added support for `remainder match` (i.e "/path/{tail}*")
|
* Added support for `remainder match` (i.e "/path/{tail}*")
|
||||||
|
|
||||||
## [0.1.2] - 2019-04-07
|
|
||||||
|
|
||||||
|
## 0.1.2 - 2019-04-07
|
||||||
* Export `Quoter` type
|
* Export `Quoter` type
|
||||||
|
|
||||||
* Allow to reset `Path` instance
|
* Allow to reset `Path` instance
|
||||||
|
|
||||||
## [0.1.1] - 2019-04-03
|
|
||||||
|
|
||||||
|
## 0.1.1 - 2019-04-03
|
||||||
* Get dynamic segment by name instead of iterator.
|
* Get dynamic segment by name instead of iterator.
|
||||||
|
|
||||||
## [0.1.0] - 2019-03-09
|
|
||||||
|
|
||||||
|
## 0.1.0 - 2019-03-09
|
||||||
* Initial release
|
* Initial release
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.2.4"
|
version = "0.2.5"
|
||||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||||
description = "Path router"
|
description = "Resource path matching library"
|
||||||
keywords = ["actix"]
|
keywords = ["actix"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
repository = "https://github.com/actix/actix-net.git"
|
repository = "https://github.com/actix/actix-net.git"
|
||||||
@@ -22,7 +22,7 @@ regex = "1.3.1"
|
|||||||
serde = "1.0.104"
|
serde = "1.0.104"
|
||||||
bytestring = "0.1.2"
|
bytestring = "0.1.2"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
http = { version="0.2.0", optional=true }
|
http = { version = "0.2.0", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
http = "0.2.0"
|
http = "0.2.0"
|
||||||
|
@@ -161,9 +161,7 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
|
|||||||
V: Visitor<'de>,
|
V: Visitor<'de>,
|
||||||
{
|
{
|
||||||
if self.path.is_empty() {
|
if self.path.is_empty() {
|
||||||
Err(de::value::Error::custom(
|
Err(de::value::Error::custom("expected at least one parameters"))
|
||||||
"expeceted at least one parameters",
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
visitor.visit_enum(ValueEnum {
|
visitor.visit_enum(ValueEnum {
|
||||||
value: &self.path[0],
|
value: &self.path[0],
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
//! Resource path matching library.
|
//! Resource path matching library.
|
||||||
|
|
||||||
mod de;
|
mod de;
|
||||||
mod path;
|
mod path;
|
||||||
mod resource;
|
mod resource;
|
||||||
|
@@ -155,7 +155,7 @@ impl ResourceDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Check if path matchs this pattern?
|
/// Check if path matches this pattern.
|
||||||
pub fn is_match(&self, path: &str) -> bool {
|
pub fn is_match(&self, path: &str) -> bool {
|
||||||
match self.tp {
|
match self.tp {
|
||||||
PatternType::Static(ref s) => s == path,
|
PatternType::Static(ref s) => s == path,
|
||||||
@@ -165,15 +165,15 @@ impl ResourceDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is prefix path a match against this resource?
|
/// Is prefix path a match against this resource.
|
||||||
pub fn is_prefix_match(&self, path: &str) -> Option<usize> {
|
pub fn is_prefix_match(&self, path: &str) -> Option<usize> {
|
||||||
let plen = path.len();
|
let p_len = path.len();
|
||||||
let path = if path.is_empty() { "/" } else { path };
|
let path = if path.is_empty() { "/" } else { path };
|
||||||
|
|
||||||
match self.tp {
|
match self.tp {
|
||||||
PatternType::Static(ref s) => {
|
PatternType::Static(ref s) => {
|
||||||
if s == path {
|
if s == path {
|
||||||
Some(plen)
|
Some(p_len)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ impl ResourceDef {
|
|||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(min(plen, len))
|
Some(min(p_len, len))
|
||||||
}
|
}
|
||||||
PatternType::DynamicSet(ref re, ref params) => {
|
PatternType::DynamicSet(ref re, ref params) => {
|
||||||
if let Some(idx) = re.matches(path).into_iter().next() {
|
if let Some(idx) = re.matches(path).into_iter().next() {
|
||||||
@@ -240,7 +240,7 @@ impl ResourceDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is the given path and parameters a match against this pattern?
|
/// Is the given path and parameters a match against this pattern.
|
||||||
pub fn match_path<T: ResourcePath>(&self, path: &mut Path<T>) -> bool {
|
pub fn match_path<T: ResourcePath>(&self, path: &mut Path<T>) -> bool {
|
||||||
match self.tp {
|
match self.tp {
|
||||||
PatternType::Static(ref s) => {
|
PatternType::Static(ref s) => {
|
||||||
@@ -252,11 +252,11 @@ impl ResourceDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatternType::Prefix(ref s) => {
|
PatternType::Prefix(ref s) => {
|
||||||
let rpath = path.path();
|
let r_path = path.path();
|
||||||
let len = if s == rpath {
|
let len = if s == r_path {
|
||||||
s.len()
|
s.len()
|
||||||
} else if rpath.starts_with(s)
|
} else if r_path.starts_with(s)
|
||||||
&& (s.ends_with('/') || rpath.split_at(s.len()).1.starts_with('/'))
|
&& (s.ends_with('/') || r_path.split_at(s.len()).1.starts_with('/'))
|
||||||
{
|
{
|
||||||
if s.ends_with('/') {
|
if s.ends_with('/') {
|
||||||
s.len() - 1
|
s.len() - 1
|
||||||
@@ -266,8 +266,8 @@ impl ResourceDef {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let rpath_len = rpath.len();
|
let r_path_len = r_path.len();
|
||||||
path.skip(min(rpath_len, len) as u16);
|
path.skip(min(r_path_len, len) as u16);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
PatternType::Dynamic(ref re, ref names, len) => {
|
PatternType::Dynamic(ref re, ref names, len) => {
|
||||||
@@ -361,11 +361,11 @@ impl ResourceDef {
|
|||||||
}
|
}
|
||||||
PatternType::Prefix(ref s) => {
|
PatternType::Prefix(ref s) => {
|
||||||
let len = {
|
let len = {
|
||||||
let rpath = res.resource_path().path();
|
let r_path = res.resource_path().path();
|
||||||
if s == rpath {
|
if s == r_path {
|
||||||
s.len()
|
s.len()
|
||||||
} else if rpath.starts_with(s)
|
} else if r_path.starts_with(s)
|
||||||
&& (s.ends_with('/') || rpath.split_at(s.len()).1.starts_with('/'))
|
&& (s.ends_with('/') || r_path.split_at(s.len()).1.starts_with('/'))
|
||||||
{
|
{
|
||||||
if s.ends_with('/') {
|
if s.ends_with('/') {
|
||||||
s.len() - 1
|
s.len() - 1
|
||||||
@@ -580,6 +580,8 @@ impl ResourceDef {
|
|||||||
mut for_prefix: bool,
|
mut for_prefix: bool,
|
||||||
) -> (String, Vec<PatternElement>, bool, usize) {
|
) -> (String, Vec<PatternElement>, bool, usize) {
|
||||||
if pattern.find('{').is_none() {
|
if pattern.find('{').is_none() {
|
||||||
|
// TODO: MSRV: 1.45
|
||||||
|
#[allow(clippy::manual_strip)]
|
||||||
return if pattern.ends_with('*') {
|
return if pattern.ends_with('*') {
|
||||||
let path = &pattern[..pattern.len() - 1];
|
let path = &pattern[..pattern.len() - 1];
|
||||||
let re = String::from("^") + path + "(.*)";
|
let re = String::from("^") + path + "(.*)";
|
||||||
@@ -594,39 +596,39 @@ impl ResourceDef {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut elems = Vec::new();
|
let mut elements = Vec::new();
|
||||||
let mut re = String::from("^");
|
let mut re = String::from("^");
|
||||||
let mut dyn_elems = 0;
|
let mut dyn_elements = 0;
|
||||||
|
|
||||||
while let Some(idx) = pattern.find('{') {
|
while let Some(idx) = pattern.find('{') {
|
||||||
let (prefix, rem) = pattern.split_at(idx);
|
let (prefix, rem) = pattern.split_at(idx);
|
||||||
elems.push(PatternElement::Str(String::from(prefix)));
|
elements.push(PatternElement::Str(String::from(prefix)));
|
||||||
re.push_str(&escape(prefix));
|
re.push_str(&escape(prefix));
|
||||||
let (param_pattern, re_part, rem, tail) = Self::parse_param(rem);
|
let (param_pattern, re_part, rem, tail) = Self::parse_param(rem);
|
||||||
if tail {
|
if tail {
|
||||||
for_prefix = true;
|
for_prefix = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
elems.push(param_pattern);
|
elements.push(param_pattern);
|
||||||
re.push_str(&re_part);
|
re.push_str(&re_part);
|
||||||
pattern = rem;
|
pattern = rem;
|
||||||
dyn_elems += 1;
|
dyn_elements += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
elems.push(PatternElement::Str(String::from(pattern)));
|
elements.push(PatternElement::Str(String::from(pattern)));
|
||||||
re.push_str(&escape(pattern));
|
re.push_str(&escape(pattern));
|
||||||
|
|
||||||
if dyn_elems > MAX_DYNAMIC_SEGMENTS {
|
if dyn_elements > MAX_DYNAMIC_SEGMENTS {
|
||||||
panic!(
|
panic!(
|
||||||
"Only {} dynanic segments are allowed, provided: {}",
|
"Only {} dynamic segments are allowed, provided: {}",
|
||||||
MAX_DYNAMIC_SEGMENTS, dyn_elems
|
MAX_DYNAMIC_SEGMENTS, dyn_elements
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !for_prefix {
|
if !for_prefix {
|
||||||
re.push('$');
|
re.push('$');
|
||||||
}
|
}
|
||||||
(re, elems, true, pattern.chars().count())
|
(re, elements, true, pattern.chars().count())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,10 +720,10 @@ mod tests {
|
|||||||
assert!(!re.is_match("/v/resource/1"));
|
assert!(!re.is_match("/v/resource/1"));
|
||||||
assert!(!re.is_match("/resource"));
|
assert!(!re.is_match("/resource"));
|
||||||
|
|
||||||
let mut path = Path::new("/v151/resource/adahg32");
|
let mut path = Path::new("/v151/resource/adage32");
|
||||||
assert!(re.match_path(&mut path));
|
assert!(re.match_path(&mut path));
|
||||||
assert_eq!(path.get("version").unwrap(), "151");
|
assert_eq!(path.get("version").unwrap(), "151");
|
||||||
assert_eq!(path.get("id").unwrap(), "adahg32");
|
assert_eq!(path.get("id").unwrap(), "adage32");
|
||||||
|
|
||||||
let re = ResourceDef::new("/{id:[[:digit:]]{6}}");
|
let re = ResourceDef::new("/{id:[[:digit:]]{6}}");
|
||||||
assert!(re.is_match("/012345"));
|
assert!(re.is_match("/012345"));
|
||||||
@@ -759,10 +761,10 @@ mod tests {
|
|||||||
assert!(!re.is_match("/v/resource/1"));
|
assert!(!re.is_match("/v/resource/1"));
|
||||||
assert!(!re.is_match("/resource"));
|
assert!(!re.is_match("/resource"));
|
||||||
|
|
||||||
let mut path = Path::new("/v151/resource/adahg32");
|
let mut path = Path::new("/v151/resource/adage32");
|
||||||
assert!(re.match_path(&mut path));
|
assert!(re.match_path(&mut path));
|
||||||
assert_eq!(path.get("version").unwrap(), "151");
|
assert_eq!(path.get("version").unwrap(), "151");
|
||||||
assert_eq!(path.get("id").unwrap(), "adahg32");
|
assert_eq!(path.get("id").unwrap(), "adage32");
|
||||||
|
|
||||||
assert!(re.is_match("/012345"));
|
assert!(re.is_match("/012345"));
|
||||||
assert!(!re.is_match("/012"));
|
assert!(!re.is_match("/012"));
|
||||||
@@ -875,7 +877,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reousrce_prefix_dynamic() {
|
fn test_resource_prefix_dynamic() {
|
||||||
let re = ResourceDef::prefix("/{name}/");
|
let re = ResourceDef::prefix("/{name}/");
|
||||||
assert!(re.is_match("/name/"));
|
assert!(re.is_match("/name/"));
|
||||||
assert!(re.is_match("/name/gs"));
|
assert!(re.is_match("/name/gs"));
|
||||||
|
@@ -182,11 +182,11 @@ impl Quoter {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_hex(v: u8) -> Option<u8> {
|
fn from_hex(v: u8) -> Option<u8> {
|
||||||
if v >= b'0' && v <= b'9' {
|
if (b'0'..=b'9').contains(&v) {
|
||||||
Some(v - 0x30) // ord('0') == 0x30
|
Some(v - 0x30) // ord('0') == 0x30
|
||||||
} else if v >= b'A' && v <= b'F' {
|
} else if (b'A'..=b'F').contains(&v) {
|
||||||
Some(v - 0x41 + 10) // ord('A') == 0x41
|
Some(v - 0x41 + 10) // ord('A') == 0x41
|
||||||
} else if v > b'a' && v <= b'f' {
|
} else if (b'a'..=b'f').contains(&v) {
|
||||||
Some(v - 0x61 + 10) // ord('a') == 0x61
|
Some(v - 0x61 + 10) // ord('a') == 0x61
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -225,4 +225,25 @@ mod tests {
|
|||||||
assert!(re.match_path(&mut path));
|
assert!(re.match_path(&mut path));
|
||||||
assert_eq!(path.get("id").unwrap(), "qwe%rty");
|
assert_eq!(path.get("id").unwrap(), "qwe%rty");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_hex() {
|
||||||
|
let hex = b"0123456789abcdefABCDEF";
|
||||||
|
|
||||||
|
for i in 0..256 {
|
||||||
|
let c = i as u8;
|
||||||
|
if hex.contains(&c) {
|
||||||
|
assert!(from_hex(c).is_some())
|
||||||
|
} else {
|
||||||
|
assert!(from_hex(c).is_none())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 10, 11, 12, 13, 14, 15,
|
||||||
|
];
|
||||||
|
for i in 0..hex.len() {
|
||||||
|
assert_eq!(from_hex(hex[i]).unwrap(), expected[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user