itsi-scheduler 0.2.22-aarch64-linux

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.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +8 -0
  3. data/Cargo.lock +997 -0
  4. data/Cargo.toml +7 -0
  5. data/Rakefile +39 -0
  6. data/ext/itsi_acme/Cargo.toml +86 -0
  7. data/ext/itsi_acme/examples/high_level.rs +63 -0
  8. data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
  9. data/ext/itsi_acme/examples/low_level.rs +87 -0
  10. data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
  11. data/ext/itsi_acme/src/acceptor.rs +81 -0
  12. data/ext/itsi_acme/src/acme.rs +354 -0
  13. data/ext/itsi_acme/src/axum.rs +86 -0
  14. data/ext/itsi_acme/src/cache.rs +39 -0
  15. data/ext/itsi_acme/src/caches/boxed.rs +80 -0
  16. data/ext/itsi_acme/src/caches/composite.rs +69 -0
  17. data/ext/itsi_acme/src/caches/dir.rs +106 -0
  18. data/ext/itsi_acme/src/caches/mod.rs +11 -0
  19. data/ext/itsi_acme/src/caches/no.rs +78 -0
  20. data/ext/itsi_acme/src/caches/test.rs +136 -0
  21. data/ext/itsi_acme/src/config.rs +172 -0
  22. data/ext/itsi_acme/src/https_helper.rs +69 -0
  23. data/ext/itsi_acme/src/incoming.rs +142 -0
  24. data/ext/itsi_acme/src/jose.rs +161 -0
  25. data/ext/itsi_acme/src/lib.rs +142 -0
  26. data/ext/itsi_acme/src/resolver.rs +59 -0
  27. data/ext/itsi_acme/src/state.rs +424 -0
  28. data/ext/itsi_error/Cargo.lock +368 -0
  29. data/ext/itsi_error/Cargo.toml +12 -0
  30. data/ext/itsi_error/src/lib.rs +140 -0
  31. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  32. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  33. data/ext/itsi_rb_helpers/Cargo.lock +355 -0
  34. data/ext/itsi_rb_helpers/Cargo.toml +11 -0
  35. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  36. data/ext/itsi_rb_helpers/src/lib.rs +232 -0
  37. data/ext/itsi_scheduler/Cargo.toml +24 -0
  38. data/ext/itsi_scheduler/extconf.rb +11 -0
  39. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  40. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  41. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  42. data/ext/itsi_scheduler/src/itsi_scheduler.rs +320 -0
  43. data/ext/itsi_scheduler/src/lib.rs +39 -0
  44. data/ext/itsi_server/Cargo.lock +2956 -0
  45. data/ext/itsi_server/Cargo.toml +94 -0
  46. data/ext/itsi_server/src/default_responses/mod.rs +14 -0
  47. data/ext/itsi_server/src/env.rs +43 -0
  48. data/ext/itsi_server/src/lib.rs +154 -0
  49. data/ext/itsi_server/src/prelude.rs +2 -0
  50. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +116 -0
  51. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +149 -0
  52. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +346 -0
  53. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +265 -0
  54. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +399 -0
  55. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +447 -0
  56. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +545 -0
  57. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +650 -0
  58. data/ext/itsi_server/src/ruby_types/itsi_server.rs +102 -0
  59. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  60. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  61. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  62. data/ext/itsi_server/src/server/binds/listener.rs +485 -0
  63. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  64. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  65. data/ext/itsi_server/src/server/binds/tls.rs +278 -0
  66. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  67. data/ext/itsi_server/src/server/frame_stream.rs +143 -0
  68. data/ext/itsi_server/src/server/http_message_types.rs +230 -0
  69. data/ext/itsi_server/src/server/io_stream.rs +128 -0
  70. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  71. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  72. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
  73. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  74. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +93 -0
  75. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  76. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  77. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +329 -0
  78. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +300 -0
  79. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  80. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  81. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +188 -0
  82. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +168 -0
  83. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +183 -0
  84. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  85. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
  86. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +133 -0
  87. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  88. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +122 -0
  89. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +407 -0
  90. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +155 -0
  91. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +54 -0
  92. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  93. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
  94. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +138 -0
  95. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +269 -0
  96. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +62 -0
  97. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +218 -0
  98. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  99. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  100. data/ext/itsi_server/src/server/mod.rs +14 -0
  101. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  102. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  103. data/ext/itsi_server/src/server/request_job.rs +11 -0
  104. data/ext/itsi_server/src/server/serve_strategy/acceptor.rs +100 -0
  105. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +411 -0
  106. data/ext/itsi_server/src/server/serve_strategy/mod.rs +31 -0
  107. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +449 -0
  108. data/ext/itsi_server/src/server/signal.rs +129 -0
  109. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  110. data/ext/itsi_server/src/server/thread_worker.rs +504 -0
  111. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  112. data/ext/itsi_server/src/services/itsi_http_service.rs +270 -0
  113. data/ext/itsi_server/src/services/mime_types.rs +2896 -0
  114. data/ext/itsi_server/src/services/mod.rs +6 -0
  115. data/ext/itsi_server/src/services/password_hasher.rs +89 -0
  116. data/ext/itsi_server/src/services/rate_limiter.rs +609 -0
  117. data/ext/itsi_server/src/services/static_file_server.rs +1400 -0
  118. data/ext/itsi_tracing/Cargo.lock +274 -0
  119. data/ext/itsi_tracing/Cargo.toml +17 -0
  120. data/ext/itsi_tracing/src/lib.rs +370 -0
  121. data/itsi-scheduler-100.png +0 -0
  122. data/lib/itsi/schedule_refinement.rb +96 -0
  123. data/lib/itsi/scheduler/3.1/itsi_scheduler.so +0 -0
  124. data/lib/itsi/scheduler/3.2/itsi_scheduler.so +0 -0
  125. data/lib/itsi/scheduler/3.3/itsi_scheduler.so +0 -0
  126. data/lib/itsi/scheduler/3.4/itsi_scheduler.so +0 -0
  127. data/lib/itsi/scheduler/4.0/itsi_scheduler.so +0 -0
  128. data/lib/itsi/scheduler/native_extension.rb +34 -0
  129. data/lib/itsi/scheduler/version.rb +7 -0
  130. data/lib/itsi/scheduler.rb +153 -0
  131. data/vendor/rb-sys-build/.cargo-ok +1 -0
  132. data/vendor/rb-sys-build/.cargo_vcs_info.json +6 -0
  133. data/vendor/rb-sys-build/Cargo.lock +294 -0
  134. data/vendor/rb-sys-build/Cargo.toml +71 -0
  135. data/vendor/rb-sys-build/Cargo.toml.orig +32 -0
  136. data/vendor/rb-sys-build/LICENSE-APACHE +190 -0
  137. data/vendor/rb-sys-build/LICENSE-MIT +21 -0
  138. data/vendor/rb-sys-build/src/bindings/sanitizer.rs +185 -0
  139. data/vendor/rb-sys-build/src/bindings/stable_api.rs +247 -0
  140. data/vendor/rb-sys-build/src/bindings/wrapper.h +71 -0
  141. data/vendor/rb-sys-build/src/bindings.rs +280 -0
  142. data/vendor/rb-sys-build/src/cc.rs +421 -0
  143. data/vendor/rb-sys-build/src/lib.rs +12 -0
  144. data/vendor/rb-sys-build/src/rb_config/flags.rs +101 -0
  145. data/vendor/rb-sys-build/src/rb_config/library.rs +132 -0
  146. data/vendor/rb-sys-build/src/rb_config/search_path.rs +57 -0
  147. data/vendor/rb-sys-build/src/rb_config.rs +906 -0
  148. data/vendor/rb-sys-build/src/utils.rs +53 -0
  149. metadata +210 -0
@@ -0,0 +1,270 @@
1
+ use crate::default_responses::{NOT_FOUND_RESPONSE, TIMEOUT_RESPONSE};
2
+ use crate::ruby_types::itsi_server::itsi_server_config::ItsiServerTokenPreference;
3
+ use crate::server::http_message_types::{
4
+ ConversionExt, HttpRequest, HttpResponse, RequestExt, ResponseFormat,
5
+ };
6
+ use crate::server::lifecycle_event::LifecycleEvent;
7
+ use crate::server::middleware_stack::MiddlewareLayer;
8
+ use crate::server::serve_strategy::acceptor::AcceptorArgs;
9
+ use crate::server::signal::{send_lifecycle_event, SHUTDOWN_REQUESTED};
10
+ use chrono::{self, DateTime, Local};
11
+ use either::Either;
12
+ use http::header::ACCEPT_ENCODING;
13
+ use http::{HeaderValue, Request};
14
+ use hyper::body::Incoming;
15
+ use regex::Regex;
16
+ use smallvec::SmallVec;
17
+ use std::ops::Deref;
18
+ use std::sync::atomic::{AtomicBool, Ordering};
19
+ use std::sync::{Arc, OnceLock};
20
+ use std::time::{Duration, Instant};
21
+ use tokio::time::timeout;
22
+ use tracing::error;
23
+
24
+ #[derive(Clone)]
25
+ pub struct ItsiHttpService {
26
+ pub inner: Arc<ItsiHttpServiceInner>,
27
+ }
28
+
29
+ impl Deref for ItsiHttpService {
30
+ type Target = Arc<ItsiHttpServiceInner>;
31
+
32
+ fn deref(&self) -> &Self::Target {
33
+ &self.inner
34
+ }
35
+ }
36
+
37
+ pub struct ItsiHttpServiceInner {
38
+ pub acceptor_args: Arc<AcceptorArgs>,
39
+ pub addr: String,
40
+ }
41
+
42
+ impl Deref for ItsiHttpServiceInner {
43
+ type Target = Arc<AcceptorArgs>;
44
+
45
+ fn deref(&self) -> &Self::Target {
46
+ &self.acceptor_args
47
+ }
48
+ }
49
+
50
+ #[derive(Clone)]
51
+ pub struct HttpRequestContext {
52
+ inner: Arc<RequestContextInner>,
53
+ }
54
+
55
+ impl Deref for HttpRequestContext {
56
+ type Target = Arc<RequestContextInner>;
57
+
58
+ fn deref(&self) -> &Self::Target {
59
+ &self.inner
60
+ }
61
+ }
62
+
63
+ impl Deref for RequestContextInner {
64
+ type Target = ItsiHttpService;
65
+
66
+ fn deref(&self) -> &Self::Target {
67
+ &self.service
68
+ }
69
+ }
70
+
71
+ pub struct RequestContextInner {
72
+ pub request_id: u64,
73
+ pub service: ItsiHttpService,
74
+ pub accept: ResponseFormat,
75
+ pub matching_pattern: Option<Arc<Regex>>,
76
+ pub origin: OnceLock<Option<String>>,
77
+ pub response_format: OnceLock<ResponseFormat>,
78
+ pub request_start_time: OnceLock<DateTime<Local>>,
79
+ pub start_instant: Instant,
80
+ pub if_none_match: OnceLock<Option<String>>,
81
+ pub supported_encoding_set: OnceLock<AcceptEncodingSet>,
82
+ pub is_ruby_request: Arc<AtomicBool>,
83
+ }
84
+
85
+ type AcceptEncodingSet = SmallVec<[HeaderValue; 2]>;
86
+
87
+ impl HttpRequestContext {
88
+ pub fn new(
89
+ service: ItsiHttpService,
90
+ matching_pattern: Option<Arc<Regex>>,
91
+ accept: ResponseFormat,
92
+ is_ruby_request: Arc<AtomicBool>,
93
+ ) -> Self {
94
+ HttpRequestContext {
95
+ inner: Arc::new(RequestContextInner {
96
+ request_id: rand::random::<u64>(),
97
+ service,
98
+ matching_pattern,
99
+ accept,
100
+ origin: OnceLock::new(),
101
+ response_format: OnceLock::new(),
102
+ request_start_time: OnceLock::new(),
103
+ start_instant: Instant::now(),
104
+ if_none_match: OnceLock::new(),
105
+ supported_encoding_set: OnceLock::new(),
106
+ is_ruby_request,
107
+ }),
108
+ }
109
+ }
110
+
111
+ pub fn set_supported_encoding_set(&self, req: &HttpRequest) {
112
+ self.inner.supported_encoding_set.get_or_init(|| {
113
+ let mut set: AcceptEncodingSet = SmallVec::new();
114
+
115
+ for hv in req.headers().get_all(ACCEPT_ENCODING) {
116
+ set.push(hv.clone()); // clone ≈ 16 B struct copy
117
+ }
118
+
119
+ set
120
+ });
121
+ }
122
+
123
+ pub fn set_origin(&self, origin: Option<String>) {
124
+ self.inner.origin.set(origin).unwrap();
125
+ }
126
+
127
+ pub fn set_if_none_match(&self, value: Option<String>) {
128
+ self.inner.if_none_match.set(value).unwrap();
129
+ }
130
+
131
+ pub fn get_if_none_match(&self) -> Option<String> {
132
+ self.inner.if_none_match.get().cloned().flatten()
133
+ }
134
+
135
+ pub fn short_request_id(&self) -> String {
136
+ format!("{:08x}", self.inner.request_id & 0xffff_ffff)
137
+ }
138
+
139
+ pub fn request_id(&self) -> String {
140
+ format!("{:08x}", self.inner.request_id)
141
+ }
142
+
143
+ pub fn init_logging_params(&self) {
144
+ self.inner
145
+ .request_start_time
146
+ .get_or_init(chrono::Local::now);
147
+ }
148
+
149
+ pub fn start_instant(&self) -> Instant {
150
+ self.inner.start_instant
151
+ }
152
+
153
+ pub fn start_time(&self) -> Option<DateTime<Local>> {
154
+ self.inner.request_start_time.get().cloned()
155
+ }
156
+
157
+ pub fn get_response_time(&self) -> Duration {
158
+ self.inner.start_instant.elapsed()
159
+ }
160
+
161
+ pub fn set_response_format(&self, format: ResponseFormat) {
162
+ self.inner.response_format.set(format).unwrap()
163
+ }
164
+
165
+ pub fn response_format(&self) -> &ResponseFormat {
166
+ self.inner.response_format.get().unwrap()
167
+ }
168
+
169
+ pub fn supported_encoding_set(&self) -> Option<&AcceptEncodingSet> {
170
+ self.inner.supported_encoding_set.get()
171
+ }
172
+ }
173
+
174
+ const SERVER_TOKEN_VERSION: HeaderValue =
175
+ HeaderValue::from_static(concat!("Itsi/", env!("CARGO_PKG_VERSION")));
176
+ const SERVER_TOKEN_NAME: HeaderValue = HeaderValue::from_static("Itsi");
177
+
178
+ impl ItsiHttpService {
179
+ pub async fn handle_request(&self, req: Request<Incoming>) -> itsi_error::Result<HttpResponse> {
180
+ let mut req = req.limit();
181
+ let accept: ResponseFormat = req.accept().into();
182
+ let is_single_mode = self.server_params.workers == 1;
183
+
184
+ let request_timeout = self.server_params.request_timeout;
185
+ let is_ruby_request = Arc::new(AtomicBool::new(false));
186
+ let irr_clone = is_ruby_request.clone();
187
+
188
+ let token_preference = self.server_params.itsi_server_token_preference;
189
+
190
+ let service_future = async move {
191
+ let middleware_stack = self
192
+ .server_params
193
+ .middleware
194
+ .get()
195
+ .unwrap()
196
+ .stack_for(&req)
197
+ .unwrap();
198
+ let (stack, matching_pattern) = middleware_stack;
199
+ let mut resp: Option<HttpResponse> = None;
200
+
201
+ let mut context =
202
+ HttpRequestContext::new(self.clone(), matching_pattern, accept, irr_clone);
203
+ let mut depth = 0;
204
+
205
+ for (index, elm) in stack.iter().enumerate() {
206
+ match elm.before(req, &mut context).await {
207
+ Ok(Either::Left(r)) => req = r,
208
+ Ok(Either::Right(r)) => {
209
+ resp = Some(r);
210
+ depth = index;
211
+ break;
212
+ }
213
+ Err(e) => {
214
+ error!("Middleware error: {}", e);
215
+ break;
216
+ }
217
+ }
218
+ }
219
+
220
+ let mut resp = match resp {
221
+ Some(r) => r,
222
+ None => return Ok(NOT_FOUND_RESPONSE.to_http_response(accept).await),
223
+ };
224
+
225
+ for elm in stack.iter().rev().skip(stack.len() - depth - 1) {
226
+ resp = elm.after(resp, &mut context).await;
227
+ }
228
+
229
+ match token_preference {
230
+ ItsiServerTokenPreference::Version => {
231
+ resp.headers_mut().insert("Server", SERVER_TOKEN_VERSION);
232
+ }
233
+ ItsiServerTokenPreference::Name => {
234
+ resp.headers_mut().insert("Server", SERVER_TOKEN_NAME);
235
+ }
236
+ ItsiServerTokenPreference::None => {}
237
+ }
238
+
239
+ Ok(resp)
240
+ };
241
+
242
+ if let Some(timeout_duration) = request_timeout {
243
+ match timeout(timeout_duration, service_future).await {
244
+ Ok(result) => result,
245
+ Err(_) => {
246
+ // If we're still running Ruby at this point, we can't just kill the
247
+ // thread as it might be in a critical section.
248
+ // Instead we must ask the worker to hot restart.
249
+ // But only if we're not already shutting down
250
+ if is_ruby_request.load(Ordering::Relaxed)
251
+ && !SHUTDOWN_REQUESTED.load(Ordering::SeqCst)
252
+ {
253
+ // When we've detected a timeout, use the safer send_lifecycle_event
254
+ // which will properly handle signal-safe state transitions
255
+ if is_single_mode {
256
+ // If we're in single mode, re-exec the whole process
257
+ send_lifecycle_event(LifecycleEvent::Restart);
258
+ } else {
259
+ // Otherwise we can shutdown the worker and rely on the master to restart it
260
+ send_lifecycle_event(LifecycleEvent::Shutdown);
261
+ }
262
+ }
263
+ Ok(TIMEOUT_RESPONSE.to_http_response(accept).await)
264
+ }
265
+ }
266
+ } else {
267
+ service_future.await
268
+ }
269
+ }
270
+ }