itsi-scheduler 0.1.5 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of itsi-scheduler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +7 -0
- data/Cargo.lock +90 -22
- data/README.md +5 -0
- data/_index.md +7 -0
- data/ext/itsi_error/Cargo.toml +1 -0
- data/ext/itsi_error/src/lib.rs +106 -7
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
- data/ext/itsi_error/target/debug/build/rb-sys-49f554618693db24/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-1mmt5sux7jb0i/s-h510z7m8v9-0bxu7yd.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-2vn3jey74oiw0/s-h5113n0e7e-1v5qzs6.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510ykifhe-0tbnep2.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510yyocpj-0tz7ug7.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510z0xc8g-14ol18k.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3g5qf4y7d54uj/s-h5113n0e7d-1trk8on.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3lpfftm45d3e2/s-h510z7m8r3-1pxp20o.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510ykifek-1uxasnk.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510yyocki-11u37qm.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510z0xc93-0pmy0zm.lock +0 -0
- data/ext/itsi_rb_helpers/Cargo.toml +1 -0
- data/ext/itsi_rb_helpers/src/heap_value.rs +18 -0
- data/ext/itsi_rb_helpers/src/lib.rs +59 -9
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
- data/ext/itsi_rb_helpers/target/debug/build/rb-sys-eb9ed4ff3a60f995/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-040pxg6yhb3g3/s-h5113n7a1b-03bwlt4.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h51113xnh3-1eik1ip.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h5111704jj-0g4rj8x.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-1q2d3drtxrzs5/s-h5113n79yl-0bxcqc5.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h51113xoox-10de2hp.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h5111704w7-0vdq7gq.lock +0 -0
- data/ext/itsi_scheduler/src/itsi_scheduler.rs +1 -1
- data/ext/itsi_server/Cargo.lock +2956 -0
- data/ext/itsi_server/Cargo.toml +72 -28
- data/ext/itsi_server/src/default_responses/mod.rs +11 -0
- data/ext/itsi_server/src/env.rs +43 -0
- data/ext/itsi_server/src/lib.rs +113 -75
- data/ext/itsi_server/src/prelude.rs +2 -0
- data/ext/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
- data/ext/itsi_server/src/{body_proxy/itsi_body_proxy.rs → ruby_types/itsi_body_proxy/mod.rs} +29 -8
- data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +344 -0
- data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +264 -0
- data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +345 -0
- data/ext/itsi_server/src/{response/itsi_response.rs → ruby_types/itsi_http_response.rs} +84 -40
- data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
- data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +375 -0
- data/ext/itsi_server/src/ruby_types/itsi_server.rs +83 -0
- data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
- data/ext/itsi_server/src/server/{bind.rs → binds/bind.rs} +56 -24
- data/ext/itsi_server/src/server/{listener.rs → binds/listener.rs} +218 -113
- data/ext/itsi_server/src/server/binds/mod.rs +4 -0
- data/ext/itsi_server/src/server/{tls → binds/tls}/locked_dir_cache.rs +55 -17
- data/ext/itsi_server/src/server/{tls.rs → binds/tls.rs} +109 -28
- data/ext/itsi_server/src/server/byte_frame.rs +32 -0
- data/ext/itsi_server/src/server/http_message_types.rs +97 -0
- data/ext/itsi_server/src/server/io_stream.rs +2 -1
- data/ext/itsi_server/src/server/lifecycle_event.rs +3 -0
- data/ext/itsi_server/src/server/middleware_stack/middleware.rs +165 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +56 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +87 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +86 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +285 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +142 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +289 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +292 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +55 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +190 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +157 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +195 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +201 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +87 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +414 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +131 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +44 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +36 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +126 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +180 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +55 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +163 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
- data/ext/itsi_server/src/server/middleware_stack/mod.rs +347 -0
- data/ext/itsi_server/src/server/mod.rs +6 -5
- data/ext/itsi_server/src/server/process_worker.rs +65 -14
- data/ext/itsi_server/src/server/request_job.rs +11 -0
- data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +137 -49
- data/ext/itsi_server/src/server/serve_strategy/mod.rs +9 -6
- data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +338 -164
- data/ext/itsi_server/src/server/signal.rs +32 -26
- data/ext/itsi_server/src/server/size_limited_incoming.rs +101 -0
- data/ext/itsi_server/src/server/thread_worker.rs +214 -107
- data/ext/itsi_server/src/services/cache_store.rs +74 -0
- data/ext/itsi_server/src/services/itsi_http_service.rs +239 -0
- data/ext/itsi_server/src/services/mime_types.rs +1416 -0
- data/ext/itsi_server/src/services/mod.rs +6 -0
- data/ext/itsi_server/src/services/password_hasher.rs +83 -0
- data/ext/itsi_server/src/services/rate_limiter.rs +569 -0
- data/ext/itsi_server/src/services/static_file_server.rs +1324 -0
- data/ext/itsi_tracing/Cargo.toml +1 -0
- data/ext/itsi_tracing/src/lib.rs +312 -34
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
- data/lib/itsi/scheduler/version.rb +1 -1
- data/lib/itsi/scheduler.rb +2 -2
- metadata +93 -21
- data/ext/itsi_error/src/from.rs +0 -71
- data/ext/itsi_server/extconf.rb +0 -6
- data/ext/itsi_server/src/body_proxy/mod.rs +0 -2
- data/ext/itsi_server/src/request/itsi_request.rs +0 -277
- data/ext/itsi_server/src/request/mod.rs +0 -1
- data/ext/itsi_server/src/response/mod.rs +0 -1
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -13
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -5
- data/ext/itsi_server/src/server/itsi_server.rs +0 -244
- /data/ext/itsi_server/src/server/{bind_protocol.rs → binds/bind_protocol.rs} +0 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
use magnus::{value::Lazy, Module, RClass, RModule};
|
2
|
+
|
3
|
+
pub mod itsi_body_proxy;
|
4
|
+
pub mod itsi_grpc_call;
|
5
|
+
pub mod itsi_grpc_response_stream;
|
6
|
+
pub mod itsi_http_request;
|
7
|
+
pub mod itsi_http_response;
|
8
|
+
pub mod itsi_server;
|
9
|
+
|
10
|
+
pub static ITSI_MODULE: Lazy<RModule> = Lazy::new(|ruby| ruby.define_module("Itsi").unwrap());
|
11
|
+
pub static ITSI_SERVER: Lazy<RClass> = Lazy::new(|ruby| {
|
12
|
+
ruby.get_inner(&ITSI_MODULE)
|
13
|
+
.define_class("Server", ruby.class_object())
|
14
|
+
.unwrap()
|
15
|
+
});
|
16
|
+
|
17
|
+
pub static ITSI_SERVER_CONFIG: Lazy<RModule> =
|
18
|
+
Lazy::new(|ruby| ruby.get_inner(&ITSI_SERVER).const_get("Config").unwrap());
|
19
|
+
|
20
|
+
pub static ITSI_REQUEST: Lazy<RClass> = Lazy::new(|ruby| {
|
21
|
+
ruby.get_inner(&ITSI_MODULE)
|
22
|
+
.define_class("HttpRequest", ruby.class_object())
|
23
|
+
.unwrap()
|
24
|
+
});
|
25
|
+
|
26
|
+
pub static ITSI_RESPONSE: Lazy<RClass> = Lazy::new(|ruby| {
|
27
|
+
ruby.get_inner(&ITSI_MODULE)
|
28
|
+
.define_class("HttpResponse", ruby.class_object())
|
29
|
+
.unwrap()
|
30
|
+
});
|
31
|
+
|
32
|
+
pub static ITSI_BODY_PROXY: Lazy<RClass> = Lazy::new(|ruby| {
|
33
|
+
ruby.get_inner(&ITSI_MODULE)
|
34
|
+
.define_class("BodyProxy", ruby.class_object())
|
35
|
+
.unwrap()
|
36
|
+
});
|
37
|
+
|
38
|
+
pub static ITSI_GRPC_CALL: Lazy<RClass> = Lazy::new(|ruby| {
|
39
|
+
ruby.get_inner(&ITSI_MODULE)
|
40
|
+
.define_class("GrpcCall", ruby.class_object())
|
41
|
+
.unwrap()
|
42
|
+
});
|
43
|
+
|
44
|
+
pub static ITSI_GRPC_RESPONSE_STREAM: Lazy<RClass> = Lazy::new(|ruby| {
|
45
|
+
ruby.get_inner(&ITSI_MODULE)
|
46
|
+
.define_class("GrpcResponseStream", ruby.class_object())
|
47
|
+
.unwrap()
|
48
|
+
});
|
@@ -2,6 +2,7 @@ use super::{
|
|
2
2
|
bind_protocol::BindProtocol,
|
3
3
|
tls::{configure_tls, ItsiTlsAcceptor},
|
4
4
|
};
|
5
|
+
use crate::prelude::*;
|
5
6
|
use itsi_error::ItsiError;
|
6
7
|
use std::{
|
7
8
|
collections::HashMap,
|
@@ -9,6 +10,7 @@ use std::{
|
|
9
10
|
path::PathBuf,
|
10
11
|
str::FromStr,
|
11
12
|
};
|
13
|
+
|
12
14
|
#[derive(Debug, Clone)]
|
13
15
|
pub enum BindAddress {
|
14
16
|
Ip(IpAddr),
|
@@ -27,16 +29,36 @@ pub struct Bind {
|
|
27
29
|
pub address: BindAddress,
|
28
30
|
pub port: Option<u16>, // None for Unix Sockets
|
29
31
|
pub protocol: BindProtocol,
|
30
|
-
pub tls_config: Option<
|
32
|
+
pub tls_config: Option<TlsOptions>,
|
33
|
+
}
|
34
|
+
|
35
|
+
#[derive(Default, Clone)]
|
36
|
+
pub struct TlsOptions {
|
37
|
+
pub host: String,
|
38
|
+
pub options: HashMap<String, String>,
|
39
|
+
}
|
40
|
+
|
41
|
+
impl TlsOptions {
|
42
|
+
pub fn build_acceptor(&self) -> Result<ItsiTlsAcceptor> {
|
43
|
+
configure_tls(&self.host, &self.options)
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
impl Bind {
|
48
|
+
pub fn listener_address_string(&self) -> String {
|
49
|
+
match &self.address {
|
50
|
+
BindAddress::Ip(ip) => format!("tcp://{}:{}", ip.to_canonical(), self.port.unwrap()),
|
51
|
+
BindAddress::UnixSocket(path) => {
|
52
|
+
format!("unix://{}", path.as_path().to_str().unwrap())
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
31
56
|
}
|
32
57
|
|
33
58
|
impl std::fmt::Debug for Bind {
|
34
59
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
35
60
|
match &self.address {
|
36
61
|
BindAddress::Ip(ip) => match self.protocol {
|
37
|
-
BindProtocol::Unix | BindProtocol::Unixs => {
|
38
|
-
write!(f, "{}://{}", self.protocol, ip)
|
39
|
-
}
|
40
62
|
BindProtocol::Https if self.port == Some(443) => {
|
41
63
|
write!(f, "{}://{}", self.protocol, ip)
|
42
64
|
}
|
@@ -64,7 +86,7 @@ impl std::fmt::Debug for Bind {
|
|
64
86
|
impl FromStr for Bind {
|
65
87
|
type Err = ItsiError;
|
66
88
|
|
67
|
-
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
89
|
+
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
68
90
|
let (protocol, remainder) = if let Some((proto, rest)) = s.split_once("://") {
|
69
91
|
(proto.parse::<BindProtocol>()?, rest)
|
70
92
|
} else {
|
@@ -100,7 +122,7 @@ impl FromStr for Bind {
|
|
100
122
|
"IPv6 addresses must use [ ] when specifying a port".to_owned(),
|
101
123
|
));
|
102
124
|
} else {
|
103
|
-
(h,
|
125
|
+
(h, p.parse::<u16>().ok()) // Treat as a hostname
|
104
126
|
}
|
105
127
|
} else {
|
106
128
|
(url, None)
|
@@ -109,33 +131,43 @@ impl FromStr for Bind {
|
|
109
131
|
let address = if let Ok(ip) = host.parse::<IpAddr>() {
|
110
132
|
BindAddress::Ip(ip)
|
111
133
|
} else {
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
134
|
+
match protocol {
|
135
|
+
BindProtocol::Https | BindProtocol::Http => resolve_hostname(host)
|
136
|
+
.map(BindAddress::Ip)
|
137
|
+
.ok_or(ItsiError::ArgumentError(format!(
|
138
|
+
"Failed to resolve hostname {}",
|
139
|
+
host
|
140
|
+
)))?,
|
141
|
+
BindProtocol::Unix | BindProtocol::Unixs => BindAddress::UnixSocket(host.into()),
|
142
|
+
}
|
118
143
|
};
|
119
|
-
|
120
|
-
|
121
|
-
BindProtocol::
|
122
|
-
BindProtocol::
|
123
|
-
BindProtocol::
|
144
|
+
|
145
|
+
let port = match protocol {
|
146
|
+
BindProtocol::Http => port.or(Some(80)),
|
147
|
+
BindProtocol::Https => port.or(Some(443)),
|
148
|
+
BindProtocol::Unix => None,
|
149
|
+
BindProtocol::Unixs => None,
|
124
150
|
};
|
125
151
|
|
126
152
|
let tls_config = match protocol {
|
127
153
|
BindProtocol::Http => None,
|
128
|
-
BindProtocol::Https => Some(
|
154
|
+
BindProtocol::Https => Some(TlsOptions {
|
155
|
+
host: host.to_owned(),
|
156
|
+
options,
|
157
|
+
}),
|
129
158
|
BindProtocol::Unix => None,
|
130
|
-
BindProtocol::Unixs => Some(
|
159
|
+
BindProtocol::Unixs => Some(TlsOptions {
|
160
|
+
host: host.to_owned(),
|
161
|
+
options,
|
162
|
+
}),
|
131
163
|
};
|
132
|
-
|
133
|
-
Ok(Self {
|
164
|
+
let bind = Self {
|
134
165
|
address,
|
135
166
|
port,
|
136
167
|
protocol,
|
137
168
|
tls_config,
|
138
|
-
}
|
169
|
+
};
|
170
|
+
Ok(bind)
|
139
171
|
}
|
140
172
|
}
|
141
173
|
|
@@ -153,8 +185,8 @@ fn resolve_hostname(hostname: &str) -> Option<IpAddr> {
|
|
153
185
|
.to_socket_addrs()
|
154
186
|
.ok()?
|
155
187
|
.find_map(|addr| {
|
156
|
-
if addr.
|
157
|
-
Some(addr.ip()) // Prefer
|
188
|
+
if addr.is_ipv4() {
|
189
|
+
Some(addr.ip()) // Prefer IPv4
|
158
190
|
} else {
|
159
191
|
None
|
160
192
|
}
|
@@ -1,19 +1,25 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
use crate::server::io_stream::IoStream;
|
3
|
+
use crate::server::serve_strategy::single_mode::RunningPhase;
|
4
|
+
|
1
5
|
use super::bind::{Bind, BindAddress};
|
2
6
|
use super::bind_protocol::BindProtocol;
|
3
|
-
|
7
|
+
|
4
8
|
use super::tls::ItsiTlsAcceptor;
|
5
9
|
use itsi_error::{ItsiError, Result};
|
6
10
|
use itsi_tracing::info;
|
7
11
|
use socket2::{Domain, Protocol, Socket, Type};
|
12
|
+
use std::fmt::Display;
|
8
13
|
use std::net::{IpAddr, SocketAddr, TcpListener};
|
14
|
+
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
9
15
|
use std::sync::Arc;
|
10
16
|
use std::{os::unix::net::UnixListener, path::PathBuf};
|
11
17
|
use tokio::net::TcpListener as TokioTcpListener;
|
12
18
|
use tokio::net::UnixListener as TokioUnixListener;
|
13
19
|
use tokio::net::{unix, TcpStream, UnixStream};
|
20
|
+
use tokio::sync::watch::Receiver;
|
14
21
|
use tokio_rustls::TlsAcceptor;
|
15
22
|
use tokio_stream::StreamExt;
|
16
|
-
use tracing::error;
|
17
23
|
|
18
24
|
pub(crate) enum Listener {
|
19
25
|
Tcp(TcpListener),
|
@@ -23,45 +29,79 @@ pub(crate) enum Listener {
|
|
23
29
|
}
|
24
30
|
|
25
31
|
pub(crate) enum TokioListener {
|
26
|
-
Tcp
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
Unix {
|
38
|
-
listener: TokioUnixListener,
|
39
|
-
},
|
40
|
-
UnixTls {
|
41
|
-
listener: TokioUnixListener,
|
42
|
-
acceptor: ItsiTlsAcceptor,
|
43
|
-
},
|
32
|
+
Tcp(TokioTcpListener),
|
33
|
+
TcpTls(TokioTcpListener, ItsiTlsAcceptor),
|
34
|
+
Unix(TokioUnixListener),
|
35
|
+
UnixTls(TokioUnixListener, ItsiTlsAcceptor),
|
36
|
+
}
|
37
|
+
|
38
|
+
#[derive(Debug, Clone)]
|
39
|
+
pub struct ListenerInfo {
|
40
|
+
pub host: String,
|
41
|
+
pub port: u16,
|
42
|
+
pub scheme: String,
|
44
43
|
}
|
45
44
|
|
46
45
|
impl TokioListener {
|
47
|
-
pub fn
|
46
|
+
pub fn listener_info(&self) -> ListenerInfo {
|
48
47
|
match self {
|
49
|
-
TokioListener::Tcp
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
TokioListener::Tcp(listener) => ListenerInfo {
|
49
|
+
host: listener
|
50
|
+
.local_addr()
|
51
|
+
.unwrap()
|
52
|
+
.ip()
|
53
|
+
.to_canonical()
|
54
|
+
.to_string(),
|
55
|
+
port: listener.local_addr().unwrap().port(),
|
56
|
+
scheme: "http".to_string(),
|
57
|
+
},
|
58
|
+
TokioListener::TcpTls(listener, _) => ListenerInfo {
|
59
|
+
host: listener
|
60
|
+
.local_addr()
|
61
|
+
.unwrap()
|
62
|
+
.ip()
|
63
|
+
.to_canonical()
|
64
|
+
.to_string(),
|
65
|
+
port: listener.local_addr().unwrap().port(),
|
66
|
+
scheme: "https".to_string(),
|
67
|
+
},
|
68
|
+
TokioListener::Unix(listener) => ListenerInfo {
|
69
|
+
host: listener
|
70
|
+
.local_addr()
|
71
|
+
.unwrap()
|
72
|
+
.as_pathname()
|
73
|
+
.unwrap()
|
74
|
+
.to_str()
|
75
|
+
.unwrap()
|
76
|
+
.to_owned(),
|
77
|
+
port: 0,
|
78
|
+
scheme: "unix".to_string(),
|
79
|
+
},
|
80
|
+
TokioListener::UnixTls(listener, _) => ListenerInfo {
|
81
|
+
host: listener
|
82
|
+
.local_addr()
|
83
|
+
.unwrap()
|
84
|
+
.as_pathname()
|
85
|
+
.unwrap()
|
86
|
+
.to_str()
|
87
|
+
.unwrap()
|
88
|
+
.to_owned(),
|
89
|
+
port: 0,
|
90
|
+
scheme: "ssl".to_string(),
|
91
|
+
},
|
92
|
+
}
|
54
93
|
}
|
94
|
+
|
55
95
|
pub(crate) async fn accept(&self) -> Result<IoStream> {
|
56
96
|
match self {
|
57
|
-
TokioListener::Tcp
|
58
|
-
TokioListener::TcpTls {
|
59
|
-
listener, acceptor
|
60
|
-
}
|
61
|
-
TokioListener::Unix
|
62
|
-
TokioListener::UnixTls {
|
63
|
-
listener, acceptor
|
64
|
-
}
|
97
|
+
TokioListener::Tcp(listener) => TokioListener::accept_tcp(listener).await,
|
98
|
+
TokioListener::TcpTls(listener, acceptor) => {
|
99
|
+
TokioListener::accept_tls(listener, acceptor).await
|
100
|
+
}
|
101
|
+
TokioListener::Unix(listener) => TokioListener::accept_unix(listener).await,
|
102
|
+
TokioListener::UnixTls(listener, acceptor) => {
|
103
|
+
TokioListener::accept_unix_tls(listener, acceptor).await
|
104
|
+
}
|
65
105
|
}
|
66
106
|
}
|
67
107
|
|
@@ -70,17 +110,24 @@ impl TokioListener {
|
|
70
110
|
Self::to_tokio_io(Stream::TcpStream(tcp_stream), None).await
|
71
111
|
}
|
72
112
|
|
73
|
-
pub async fn spawn_state_task(&self) {
|
74
|
-
if let TokioListener::TcpTls
|
75
|
-
|
76
|
-
|
77
|
-
|
113
|
+
pub async fn spawn_state_task(&self, mut shutdown_receiver: Receiver<RunningPhase>) {
|
114
|
+
if let TokioListener::TcpTls(
|
115
|
+
_,
|
116
|
+
ItsiTlsAcceptor::Automatic(_acme_acceptor, state, _server_config),
|
117
|
+
) = self
|
78
118
|
{
|
79
119
|
let mut state = state.lock().await;
|
80
120
|
loop {
|
81
|
-
|
82
|
-
|
83
|
-
|
121
|
+
tokio::select! {
|
122
|
+
stream_event = StreamExt::next(&mut *state) => {
|
123
|
+
match stream_event {
|
124
|
+
Some(event) => info!("ACME Event: {:?}", event),
|
125
|
+
None => error!("Received no acme event"),
|
126
|
+
}
|
127
|
+
},
|
128
|
+
_ = shutdown_receiver.changed() => {
|
129
|
+
break;
|
130
|
+
}
|
84
131
|
}
|
85
132
|
}
|
86
133
|
}
|
@@ -98,7 +145,7 @@ impl TokioListener {
|
|
98
145
|
ItsiTlsAcceptor::Automatic(acme_acceptor, _, rustls_config) => {
|
99
146
|
let accept_future = acme_acceptor.accept(tcp_stream.0);
|
100
147
|
match accept_future.await {
|
101
|
-
Ok(None) => Err(ItsiError::Pass
|
148
|
+
Ok(None) => Err(ItsiError::Pass),
|
102
149
|
Ok(Some(start_handshake)) => {
|
103
150
|
let tls_stream = start_handshake.into_stream(rustls_config.clone()).await?;
|
104
151
|
Ok(IoStream::TcpTls {
|
@@ -108,7 +155,7 @@ impl TokioListener {
|
|
108
155
|
}
|
109
156
|
Err(error) => {
|
110
157
|
error!(error = format!("{:?}", error));
|
111
|
-
Err(ItsiError::Pass
|
158
|
+
Err(ItsiError::Pass)
|
112
159
|
}
|
113
160
|
}
|
114
161
|
}
|
@@ -175,33 +222,6 @@ impl TokioListener {
|
|
175
222
|
},
|
176
223
|
}
|
177
224
|
}
|
178
|
-
|
179
|
-
pub(crate) fn scheme(&self) -> String {
|
180
|
-
match self {
|
181
|
-
TokioListener::Tcp { .. } => "http".to_string(),
|
182
|
-
TokioListener::TcpTls { .. } => "https".to_string(),
|
183
|
-
TokioListener::Unix { .. } => "http".to_string(),
|
184
|
-
TokioListener::UnixTls { .. } => "https".to_string(),
|
185
|
-
}
|
186
|
-
}
|
187
|
-
|
188
|
-
pub(crate) fn port(&self) -> u16 {
|
189
|
-
match self {
|
190
|
-
TokioListener::Tcp { port, .. } => *port,
|
191
|
-
TokioListener::TcpTls { port, .. } => *port,
|
192
|
-
TokioListener::Unix { .. } => 0,
|
193
|
-
TokioListener::UnixTls { .. } => 0,
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
|
-
pub(crate) fn host(&self) -> String {
|
198
|
-
match self {
|
199
|
-
TokioListener::Tcp { host, .. } => host.to_string(),
|
200
|
-
TokioListener::TcpTls { host, .. } => host.to_string(),
|
201
|
-
TokioListener::Unix { .. } => "unix".to_string(),
|
202
|
-
TokioListener::UnixTls { .. } => "unix".to_string(),
|
203
|
-
}
|
204
|
-
}
|
205
225
|
}
|
206
226
|
|
207
227
|
enum Stream {
|
@@ -225,51 +245,109 @@ impl std::fmt::Display for SockAddr {
|
|
225
245
|
}
|
226
246
|
}
|
227
247
|
}
|
248
|
+
impl Display for Listener {
|
249
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
250
|
+
match self {
|
251
|
+
Listener::Tcp(listener) | Listener::TcpTls((listener, _)) => write!(
|
252
|
+
f,
|
253
|
+
"{}",
|
254
|
+
listener
|
255
|
+
.local_addr()
|
256
|
+
.map(|addr| addr.to_string())
|
257
|
+
.unwrap_or_else(|_| "".to_string())
|
258
|
+
),
|
259
|
+
|
260
|
+
Listener::Unix(listener) | Listener::UnixTls((listener, _)) => write!(
|
261
|
+
f,
|
262
|
+
"{}",
|
263
|
+
listener
|
264
|
+
.local_addr()
|
265
|
+
.map(|addr| addr
|
266
|
+
.as_pathname()
|
267
|
+
.map(|path| path.to_str().unwrap_or("").to_owned())
|
268
|
+
.unwrap_or_default())
|
269
|
+
.unwrap_or_else(|_| "".to_string())
|
270
|
+
),
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
228
274
|
|
229
275
|
impl Listener {
|
230
|
-
pub fn
|
276
|
+
pub fn into_tokio_listener(self) -> TokioListener {
|
231
277
|
match self {
|
232
|
-
Listener::Tcp(listener) =>
|
233
|
-
|
234
|
-
|
235
|
-
Listener::
|
236
|
-
|
278
|
+
Listener::Tcp(listener) => {
|
279
|
+
TokioListener::Tcp(TokioTcpListener::from_std(listener).unwrap())
|
280
|
+
}
|
281
|
+
Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls(
|
282
|
+
TokioTcpListener::from_std(listener).unwrap(),
|
283
|
+
acceptor.clone(),
|
284
|
+
),
|
285
|
+
Listener::Unix(listener) => {
|
286
|
+
TokioListener::Unix(TokioUnixListener::from_std(listener).unwrap())
|
287
|
+
}
|
288
|
+
Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls(
|
289
|
+
TokioUnixListener::from_std(listener).unwrap(),
|
290
|
+
acceptor.clone(),
|
291
|
+
),
|
292
|
+
}
|
237
293
|
}
|
238
|
-
|
294
|
+
|
295
|
+
/// Handover information when using exec to hand over the listener to a replacement process.
|
296
|
+
pub fn handover(&self) -> Result<(String, i32)> {
|
239
297
|
match self {
|
240
|
-
Listener::Tcp(listener) =>
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
.
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
.unwrap()
|
258
|
-
.
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
.
|
298
|
+
Listener::Tcp(listener) => {
|
299
|
+
let addr = listener.local_addr()?;
|
300
|
+
Ok((
|
301
|
+
format!("tcp://{}:{}", addr.ip().to_canonical(), addr.port()),
|
302
|
+
listener.as_raw_fd(),
|
303
|
+
))
|
304
|
+
}
|
305
|
+
Listener::TcpTls((listener, _)) => {
|
306
|
+
let addr = listener.local_addr()?;
|
307
|
+
Ok((
|
308
|
+
format!("tcp://{}:{}", addr.ip().to_canonical(), addr.port()),
|
309
|
+
listener.as_raw_fd(),
|
310
|
+
))
|
311
|
+
}
|
312
|
+
Listener::Unix(listener) => {
|
313
|
+
let addr = listener.local_addr()?;
|
314
|
+
Ok((
|
315
|
+
format!("unix://{}", addr.as_pathname().unwrap().to_str().unwrap()),
|
316
|
+
listener.as_raw_fd(),
|
317
|
+
))
|
318
|
+
}
|
319
|
+
Listener::UnixTls((listener, _)) => {
|
320
|
+
let addr = listener.local_addr()?;
|
321
|
+
Ok((
|
322
|
+
format!("unix://{}", addr.as_pathname().unwrap().to_str().unwrap()),
|
323
|
+
listener.as_raw_fd(),
|
324
|
+
))
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
pub fn inherit_fd(bind: Bind, fd: RawFd) -> Result<Self> {
|
330
|
+
let bound = match bind.address {
|
331
|
+
BindAddress::Ip(_) => match bind.protocol {
|
332
|
+
BindProtocol::Http => Listener::Tcp(revive_tcp_socket(fd)?),
|
333
|
+
BindProtocol::Https => {
|
334
|
+
let tcp_listener = revive_tcp_socket(fd)?;
|
335
|
+
Listener::TcpTls((
|
336
|
+
tcp_listener,
|
337
|
+
bind.tls_config.unwrap().build_acceptor().unwrap(),
|
338
|
+
))
|
339
|
+
}
|
340
|
+
_ => unreachable!(),
|
266
341
|
},
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
342
|
+
BindAddress::UnixSocket(_) => match bind.tls_config {
|
343
|
+
Some(tls_config) => Listener::UnixTls((
|
344
|
+
revive_unix_socket(fd)?,
|
345
|
+
tls_config.build_acceptor().unwrap(),
|
346
|
+
)),
|
347
|
+
None => Listener::Unix(revive_unix_socket(fd)?),
|
271
348
|
},
|
272
|
-
}
|
349
|
+
};
|
350
|
+
Ok(bound)
|
273
351
|
}
|
274
352
|
}
|
275
353
|
|
@@ -282,12 +360,18 @@ impl TryFrom<Bind> for Listener {
|
|
282
360
|
BindProtocol::Http => Listener::Tcp(connect_tcp_socket(addr, bind.port.unwrap())?),
|
283
361
|
BindProtocol::Https => {
|
284
362
|
let tcp_listener = connect_tcp_socket(addr, bind.port.unwrap())?;
|
285
|
-
Listener::TcpTls((
|
363
|
+
Listener::TcpTls((
|
364
|
+
tcp_listener,
|
365
|
+
bind.tls_config.unwrap().build_acceptor().unwrap(),
|
366
|
+
))
|
286
367
|
}
|
287
368
|
_ => unreachable!(),
|
288
369
|
},
|
289
370
|
BindAddress::UnixSocket(path) => match bind.tls_config {
|
290
|
-
Some(tls_config) => Listener::UnixTls((
|
371
|
+
Some(tls_config) => Listener::UnixTls((
|
372
|
+
connect_unix_socket(&path)?,
|
373
|
+
tls_config.build_acceptor().unwrap(),
|
374
|
+
)),
|
291
375
|
None => Listener::Unix(connect_unix_socket(&path)?),
|
292
376
|
},
|
293
377
|
};
|
@@ -295,6 +379,27 @@ impl TryFrom<Bind> for Listener {
|
|
295
379
|
}
|
296
380
|
}
|
297
381
|
|
382
|
+
fn revive_tcp_socket(fd: RawFd) -> Result<TcpListener> {
|
383
|
+
let socket = unsafe { Socket::from_raw_fd(fd) };
|
384
|
+
socket.set_reuse_port(true).ok();
|
385
|
+
socket.set_reuse_address(true).ok();
|
386
|
+
socket.set_nonblocking(true).ok();
|
387
|
+
socket.set_nodelay(true).ok();
|
388
|
+
socket.set_recv_buffer_size(262_144).ok();
|
389
|
+
socket.set_cloexec(true)?;
|
390
|
+
socket.listen(1024)?;
|
391
|
+
Ok(socket.into())
|
392
|
+
}
|
393
|
+
|
394
|
+
fn revive_unix_socket(fd: RawFd) -> Result<UnixListener> {
|
395
|
+
let socket = unsafe { Socket::from_raw_fd(fd) };
|
396
|
+
socket.set_nonblocking(true).ok();
|
397
|
+
socket.listen(1024)?;
|
398
|
+
socket.set_cloexec(true)?;
|
399
|
+
|
400
|
+
Ok(socket.into())
|
401
|
+
}
|
402
|
+
|
298
403
|
fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
|
299
404
|
let domain = match addr {
|
300
405
|
IpAddr::V4(_) => Domain::IPV4,
|
@@ -302,11 +407,12 @@ fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
|
|
302
407
|
};
|
303
408
|
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
|
304
409
|
let socket_address: SocketAddr = SocketAddr::new(addr, port);
|
305
|
-
socket.set_reuse_port(true).ok();
|
306
410
|
socket.set_reuse_address(true).ok();
|
411
|
+
socket.set_reuse_port(true).ok();
|
307
412
|
socket.set_nonblocking(true).ok();
|
308
413
|
socket.set_nodelay(true).ok();
|
309
414
|
socket.set_recv_buffer_size(262_144).ok();
|
415
|
+
socket.set_only_v6(false).ok();
|
310
416
|
socket.bind(&socket_address.into())?;
|
311
417
|
socket.listen(1024)?;
|
312
418
|
Ok(socket.into())
|
@@ -319,7 +425,6 @@ fn connect_unix_socket(path: &PathBuf) -> Result<UnixListener> {
|
|
319
425
|
|
320
426
|
let socket_address = socket2::SockAddr::unix(path)?;
|
321
427
|
|
322
|
-
info!("Binding to {:?}", path);
|
323
428
|
socket.bind(&socket_address)?;
|
324
429
|
socket.listen(1024)?;
|
325
430
|
|