mirror of
https://github.com/fafhrd91/actix-net
synced 2025-08-16 21:49:00 +02:00
Compare commits
5 Commits
test-serve
...
router-v0.
Author | SHA1 | Date | |
---|---|---|---|
|
76c317e0b2 | ||
|
3b314e4c8c | ||
|
ae27b87641 | ||
|
fc2dcadc7a | ||
|
54f62b5035 |
@@ -1,5 +1,16 @@
|
||||
# Changes
|
||||
|
||||
## [0.1.5] - 2019-04-19
|
||||
|
||||
### Added
|
||||
|
||||
* `Connect::set_addr()`
|
||||
|
||||
### Changed
|
||||
|
||||
* Use trust-dns-resolver 0.11.0
|
||||
|
||||
|
||||
## [0.1.4] - 2019-04-12
|
||||
|
||||
### Changed
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-connect"
|
||||
version = "0.1.4"
|
||||
version = "0.1.5"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix Connector - tcp connector service"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@@ -34,13 +34,13 @@ actix-service = "0.3.6"
|
||||
actix-codec = "0.1.2"
|
||||
actix-utils = "0.3.5"
|
||||
derive_more = "0.14.0"
|
||||
either = "1.5.1"
|
||||
either = "1.5.2"
|
||||
futures = "0.1.25"
|
||||
http = { version = "0.1.16", optional = true }
|
||||
http = { version = "0.1.17", optional = true }
|
||||
log = "0.4"
|
||||
tokio-tcp = "0.1.3"
|
||||
tokio-current-thread = "0.1.5"
|
||||
trust-dns-resolver = { version="0.11.0-alpha.3", default-features = false }
|
||||
trust-dns-resolver = { version="0.11.0", default-features = false }
|
||||
|
||||
# openssl
|
||||
openssl = { version="0.10", optional = true }
|
||||
@@ -48,8 +48,7 @@ tokio-openssl = { version="0.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bytes = "0.4"
|
||||
#actix-test-server = { version="0.2.0", features=["ssl"] }
|
||||
actix-test-server = { path="../actix-test-server", features=["ssl"] }
|
||||
actix-test-server = { version="0.2.1", features=["ssl"] }
|
||||
actix-server-config = "0.1.0"
|
||||
actix-utils = "0.3.4"
|
||||
tokio-tcp = "0.1"
|
@@ -69,6 +69,14 @@ impl<T: Address> Connect<T> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Use address.
|
||||
pub fn set_addr(mut self, addr: Option<SocketAddr>) -> Self {
|
||||
if let Some(addr) = addr {
|
||||
self.addr = Some(Either::Left(addr));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Host name
|
||||
pub fn host(&self) -> &str {
|
||||
self.req.host()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-server-config"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix server config utils"
|
||||
homepage = "https://actix.rs"
|
||||
@@ -13,5 +13,22 @@ workspace = ".."
|
||||
name = "actix_server_config"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["ssl", "rust-tls"]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
# openssl
|
||||
ssl = ["tokio-openssl"]
|
||||
|
||||
# rustls
|
||||
rust-tls = ["rustls", "tokio-rustls"]
|
||||
|
||||
[dependencies]
|
||||
futures = "0.1.25"
|
||||
tokio-io = "0.1.12"
|
||||
tokio-tcp = "0.1"
|
||||
tokio-openssl = { version="0.3.0", optional = true }
|
||||
rustls = { version = "0.15.2", optional = true }
|
||||
tokio-rustls = { version = "0.9.1", optional = true }
|
||||
|
7
actix-server-config/changes.md
Normal file
7
actix-server-config/changes.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Changes
|
||||
|
||||
## [0.1.1] - 2019-04-16
|
||||
|
||||
### Added
|
||||
|
||||
* `IoStream` trait and impls for TcpStream, SslStream and TlsStream
|
@@ -1,7 +1,10 @@
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::net::SocketAddr;
|
||||
use std::rc::Rc;
|
||||
use std::{fmt, io, net, time};
|
||||
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use tokio_tcp::TcpStream;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServerConfig {
|
||||
@@ -130,3 +133,86 @@ impl<T: fmt::Debug, P> fmt::Debug for Io<T, P> {
|
||||
write!(f, "Io {{{:?}}}", self.io)
|
||||
}
|
||||
}
|
||||
|
||||
/// Low-level io stream operations
|
||||
pub trait IoStream: AsyncRead + AsyncWrite {
|
||||
/// Returns the socket address of the remote peer of this TCP connection.
|
||||
fn peer_addr(&self) -> Option<SocketAddr> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Sets the value of the TCP_NODELAY option on this socket.
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()>;
|
||||
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()>;
|
||||
|
||||
fn set_keepalive(&mut self, dur: Option<time::Duration>) -> io::Result<()>;
|
||||
}
|
||||
|
||||
impl IoStream for TcpStream {
|
||||
#[inline]
|
||||
fn peer_addr(&self) -> Option<net::SocketAddr> {
|
||||
TcpStream::peer_addr(self).ok()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
TcpStream::set_nodelay(self, nodelay)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
TcpStream::set_linger(self, dur)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_keepalive(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
TcpStream::set_keepalive(self, dur)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "ssl"))]
|
||||
impl<T: IoStream> IoStream for tokio_openssl::SslStream<T> {
|
||||
#[inline]
|
||||
fn peer_addr(&self) -> Option<net::SocketAddr> {
|
||||
self.get_ref().get_ref().peer_addr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
self.get_mut().get_mut().set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().get_mut().set_linger(dur)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_keepalive(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().get_mut().set_keepalive(dur)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "rust-tls"))]
|
||||
impl<T: IoStream> IoStream for tokio_rustls::TlsStream<T, rustls::ServerSession> {
|
||||
#[inline]
|
||||
fn peer_addr(&self) -> Option<net::SocketAddr> {
|
||||
self.get_ref().0.peer_addr()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
self.get_mut().0.set_nodelay(nodelay)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().0.set_linger(dur)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_keepalive(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
self.get_mut().0.set_keepalive(dur)
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,16 @@
|
||||
# Changes
|
||||
|
||||
## [0.4.3] - 2019-04-16
|
||||
|
||||
### Added
|
||||
|
||||
* Re-export `IoStream` trait
|
||||
|
||||
### Changed
|
||||
|
||||
* Deppend on `ssl` and `rust-tls` features from actix-server-config
|
||||
|
||||
|
||||
## [0.4.2] - 2019-03-30
|
||||
|
||||
### Fixed
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "actix-server"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Actix server - General purpose tcp server"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
@@ -27,20 +27,20 @@ default = []
|
||||
tls = ["native-tls"]
|
||||
|
||||
# openssl
|
||||
ssl = ["openssl", "tokio-openssl"]
|
||||
ssl = ["openssl", "tokio-openssl", "actix-server-config/ssl"]
|
||||
|
||||
# rustls
|
||||
rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots"]
|
||||
rust-tls = ["rustls", "tokio-rustls", "webpki", "webpki-roots", "actix-server-config/rust-tls"]
|
||||
|
||||
[dependencies]
|
||||
actix-rt = "0.2.1"
|
||||
actix-service = "0.3.4"
|
||||
actix-server-config = "0.1.0"
|
||||
actix-server-config = "0.1.1"
|
||||
|
||||
log = "0.4"
|
||||
num_cpus = "1.0"
|
||||
|
||||
mio = "^0.6.13"
|
||||
mio = "0.6.13"
|
||||
net2 = "0.2"
|
||||
futures = "0.1"
|
||||
slab = "0.4"
|
||||
@@ -58,12 +58,12 @@ openssl = { version="0.10", optional = true }
|
||||
tokio-openssl = { version="0.3", optional = true }
|
||||
|
||||
#rustls
|
||||
rustls = { version = "^0.15", optional = true }
|
||||
tokio-rustls = { version = "^0.9", optional = true }
|
||||
rustls = { version = "0.15.2", optional = true }
|
||||
tokio-rustls = { version = "0.9.1", optional = true }
|
||||
webpki = { version = "0.19", optional = true }
|
||||
webpki-roots = { version = "0.16", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bytes = "0.4"
|
||||
actix-codec = "0.1.0"
|
||||
actix-codec = "0.1.2"
|
||||
env_logger = "0.6"
|
||||
|
@@ -10,7 +10,7 @@ mod signals;
|
||||
pub mod ssl;
|
||||
mod worker;
|
||||
|
||||
pub use actix_server_config::{Io, Protocol, ServerConfig};
|
||||
pub use actix_server_config::{Io, IoStream, Protocol, ServerConfig};
|
||||
|
||||
pub use self::builder::ServerBuilder;
|
||||
pub use self::config::{ServiceConfig, ServiceRuntime};
|
||||
|
@@ -8,10 +8,13 @@ pub type BoxedService<Req, Res, Err> = Box<
|
||||
Request = Req,
|
||||
Response = Res,
|
||||
Error = Err,
|
||||
Future = Either<FutureResult<Res, Err>, Box<Future<Item = Res, Error = Err>>>,
|
||||
Future = BoxedServiceResponse<Res, Err>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub type BoxedServiceResponse<Res, Err> =
|
||||
Either<FutureResult<Res, Err>, Box<Future<Item = Res, Error = Err>>>;
|
||||
|
||||
/// Create boxed new service
|
||||
pub fn new_service<T, C>(
|
||||
service: T,
|
||||
|
@@ -1,5 +1,9 @@
|
||||
# Changes
|
||||
|
||||
## [0.1.3] - 2019-04-22
|
||||
|
||||
* Added support for `remainder match` (i.e "/path/{tail}*")
|
||||
|
||||
## [0.1.2] - 2019-04-07
|
||||
|
||||
* Export `Quoter` type
|
||||
|
@@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "actix-router"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
|
||||
description = "Path router"
|
||||
description = "Path table router"
|
||||
keywords = ["actix"]
|
||||
homepage = "https://actix.rs"
|
||||
repository = "https://github.com/actix/actix-net.git"
|
||||
|
@@ -267,8 +267,9 @@ impl ResourceDef {
|
||||
true
|
||||
}
|
||||
|
||||
fn parse_param(pattern: &str) -> (PatternElement, String, &str) {
|
||||
fn parse_param(pattern: &str) -> (PatternElement, String, &str, bool) {
|
||||
const DEFAULT_PATTERN: &str = "[^/]+";
|
||||
const DEFAULT_PATTERN_TAIL: &str = ".*";
|
||||
let mut params_nesting = 0usize;
|
||||
let close_idx = pattern
|
||||
.find(|c| match c {
|
||||
@@ -283,34 +284,54 @@ impl ResourceDef {
|
||||
_ => false,
|
||||
})
|
||||
.expect("malformed dynamic segment");
|
||||
let (mut param, rem) = pattern.split_at(close_idx + 1);
|
||||
let (mut param, mut rem) = pattern.split_at(close_idx + 1);
|
||||
param = ¶m[1..param.len() - 1]; // Remove outer brackets
|
||||
let tail = rem == "*";
|
||||
|
||||
let (name, pattern) = match param.find(':') {
|
||||
Some(idx) => {
|
||||
if tail {
|
||||
panic!("Custom regex is not supported for remainder match");
|
||||
}
|
||||
let (name, pattern) = param.split_at(idx);
|
||||
(name, &pattern[1..])
|
||||
}
|
||||
None => (param, DEFAULT_PATTERN),
|
||||
None => (
|
||||
param,
|
||||
if tail {
|
||||
rem = &rem[1..];
|
||||
DEFAULT_PATTERN_TAIL
|
||||
} else {
|
||||
DEFAULT_PATTERN
|
||||
},
|
||||
),
|
||||
};
|
||||
(
|
||||
PatternElement::Var(name.to_string()),
|
||||
format!(r"(?P<{}>{})", &name, &pattern),
|
||||
rem,
|
||||
tail,
|
||||
)
|
||||
}
|
||||
|
||||
fn parse(
|
||||
mut pattern: &str,
|
||||
for_prefix: bool,
|
||||
mut for_prefix: bool,
|
||||
) -> (String, Vec<PatternElement>, bool, usize) {
|
||||
if pattern.find('{').is_none() {
|
||||
return (
|
||||
return if pattern.ends_with('*') {
|
||||
let path = &pattern[..pattern.len() - 1];
|
||||
let re = String::from("^") + path + "(.*)";
|
||||
(re, vec![PatternElement::Str(String::from(path))], true, 0)
|
||||
} else {
|
||||
(
|
||||
String::from(pattern),
|
||||
vec![PatternElement::Str(String::from(pattern))],
|
||||
false,
|
||||
pattern.chars().count(),
|
||||
);
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
let mut elems = Vec::new();
|
||||
let mut re = String::from("^");
|
||||
@@ -320,7 +341,11 @@ impl ResourceDef {
|
||||
let (prefix, rem) = pattern.split_at(idx);
|
||||
elems.push(PatternElement::Str(String::from(prefix)));
|
||||
re.push_str(&escape(prefix));
|
||||
let (param_pattern, re_part, rem) = Self::parse_param(rem);
|
||||
let (param_pattern, re_part, rem, tail) = Self::parse_param(rem);
|
||||
if tail {
|
||||
for_prefix = true;
|
||||
}
|
||||
|
||||
elems.push(param_pattern);
|
||||
re.push_str(&re_part);
|
||||
pattern = rem;
|
||||
@@ -340,7 +365,6 @@ impl ResourceDef {
|
||||
if !for_prefix {
|
||||
re.push_str("$");
|
||||
}
|
||||
|
||||
(re, elems, true, pattern.chars().count())
|
||||
}
|
||||
}
|
||||
@@ -448,6 +472,42 @@ mod tests {
|
||||
assert_eq!(path.get("id").unwrap(), "012345");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_tail() {
|
||||
let re = ResourceDef::new("/user/-{id}*");
|
||||
|
||||
let mut path = Path::new("/user/-profile");
|
||||
assert!(re.match_path(&mut path));
|
||||
assert_eq!(path.get("id").unwrap(), "profile");
|
||||
|
||||
let mut path = Path::new("/user/-2345");
|
||||
assert!(re.match_path(&mut path));
|
||||
assert_eq!(path.get("id").unwrap(), "2345");
|
||||
|
||||
let mut path = Path::new("/user/-2345/");
|
||||
assert!(re.match_path(&mut path));
|
||||
assert_eq!(path.get("id").unwrap(), "2345/");
|
||||
|
||||
let mut path = Path::new("/user/-2345/sdg");
|
||||
assert!(re.match_path(&mut path));
|
||||
assert_eq!(path.get("id").unwrap(), "2345/sdg");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_static_tail() {
|
||||
let re = ResourceDef::new("/user*");
|
||||
assert!(re.is_match("/user/profile"));
|
||||
assert!(re.is_match("/user/2345"));
|
||||
assert!(re.is_match("/user/2345/"));
|
||||
assert!(re.is_match("/user/2345/sdg"));
|
||||
|
||||
let re = ResourceDef::new("/user/*");
|
||||
assert!(re.is_match("/user/profile"));
|
||||
assert!(re.is_match("/user/2345"));
|
||||
assert!(re.is_match("/user/2345/"));
|
||||
assert!(re.is_match("/user/2345/sdg"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_urlencoded_param() {
|
||||
let re = ResourceDef::new("/user/{id}/test");
|
||||
|
Reference in New Issue
Block a user