itsi 0.2.23 → 0.2.24
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Cargo.lock +2 -2
- data/Dockerfile +2 -2
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.lock +2 -2
- data/crates/itsi_server/Cargo.toml +1 -1
- data/crates/itsi_server/src/server/binds/listener.rs +113 -68
- data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +35 -11
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +2 -1
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +28 -1
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/test/helpers/test_helper.rb +2 -0
- data/gems/server/test/options/tls_handshake_timeout.rb +19 -0
- data/lib/itsi/version.rb +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0450be0cae2f0d3822874ee35e312cc258d6adb33bcbdd9fe659c2ed7c368ea9
|
|
4
|
+
data.tar.gz: fc08b8ee180b6241e14dd421e68de982cb3f39e7bf04e791a79ea17a77f99ec3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8a4b3ed767538405a7aa311dd3c498ee7182072d6e8013d1a620f21abb55012d20b0d919b86ff03798dd8207b94048d8947acf78a32dd641a548e9e947ce2555
|
|
7
|
+
data.tar.gz: 9ce0a92e963013836721b5d9b43a05b4e146d6d96ed122a20554a52d9731e0d805480a207687a3d2734e127b0eccf95276354d31e29a38bbb4b16a34481f3eda
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
## [0.2.24] - 2026-04-18
|
|
2
|
+
- Move TLS handshakes out of the listener accept loop so a slow or incomplete TLS client cannot block later HTTPS accepts.
|
|
3
|
+
- Keep malformed proxy-style requests isolated to their connection task instead of disrupting the listener.
|
|
4
|
+
|
|
1
5
|
## [0.2.23] - 2026-04-18
|
|
2
6
|
- Return a normal 404 for unmatched proxy-style requests such as CONNECT instead of panicking the HTTP listener.
|
|
3
7
|
|
data/Cargo.lock
CHANGED
|
@@ -1662,7 +1662,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|
|
1662
1662
|
|
|
1663
1663
|
[[package]]
|
|
1664
1664
|
name = "itsi-scheduler"
|
|
1665
|
-
version = "0.2.
|
|
1665
|
+
version = "0.2.24"
|
|
1666
1666
|
dependencies = [
|
|
1667
1667
|
"bytes",
|
|
1668
1668
|
"derive_more",
|
|
@@ -1680,7 +1680,7 @@ dependencies = [
|
|
|
1680
1680
|
|
|
1681
1681
|
[[package]]
|
|
1682
1682
|
name = "itsi-server"
|
|
1683
|
-
version = "0.2.
|
|
1683
|
+
version = "0.2.24"
|
|
1684
1684
|
dependencies = [
|
|
1685
1685
|
"argon2",
|
|
1686
1686
|
"async-channel",
|
data/Dockerfile
CHANGED
|
@@ -3,7 +3,7 @@ FROM ruby:3.4
|
|
|
3
3
|
RUN apt-get update && apt-get install build-essential libclang-dev -y && apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
4
4
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
|
5
5
|
|
|
6
|
-
COPY pkg/itsi-server-0.2.
|
|
7
|
-
RUN gem install itsi-server-0.2.
|
|
6
|
+
COPY pkg/itsi-server-0.2.24.gem .
|
|
7
|
+
RUN gem install itsi-server-0.2.24.gem
|
|
8
8
|
|
|
9
9
|
CMD ["itsi", "serve"]
|
|
@@ -984,7 +984,7 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
|
|
|
984
984
|
|
|
985
985
|
[[package]]
|
|
986
986
|
name = "itsi-scheduler"
|
|
987
|
-
version = "0.2.
|
|
987
|
+
version = "0.2.24"
|
|
988
988
|
dependencies = [
|
|
989
989
|
"bytes",
|
|
990
990
|
"derive_more",
|
|
@@ -1002,7 +1002,7 @@ dependencies = [
|
|
|
1002
1002
|
|
|
1003
1003
|
[[package]]
|
|
1004
1004
|
name = "itsi-server"
|
|
1005
|
-
version = "0.2.
|
|
1005
|
+
version = "0.2.24"
|
|
1006
1006
|
dependencies = [
|
|
1007
1007
|
"async-channel",
|
|
1008
1008
|
"async-trait",
|
|
@@ -14,12 +14,13 @@ use std::fmt::Display;
|
|
|
14
14
|
use std::net::{IpAddr, SocketAddr, TcpListener};
|
|
15
15
|
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
|
|
16
16
|
use std::sync::Arc;
|
|
17
|
+
use std::time::Duration;
|
|
17
18
|
use std::{os::unix::net::UnixListener, path::PathBuf};
|
|
18
19
|
use tokio::net::TcpListener as TokioTcpListener;
|
|
19
20
|
use tokio::net::UnixListener as TokioUnixListener;
|
|
20
21
|
use tokio::net::{unix, TcpStream, UnixStream};
|
|
21
22
|
use tokio::sync::watch::Receiver;
|
|
22
|
-
use
|
|
23
|
+
use tokio::time::timeout;
|
|
23
24
|
use tokio_stream::StreamExt;
|
|
24
25
|
|
|
25
26
|
pub(crate) enum Listener {
|
|
@@ -93,7 +94,7 @@ impl TokioListener {
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
pub(crate) async fn accept(&self) -> Result<
|
|
97
|
+
pub(crate) async fn accept(&self) -> Result<AcceptedStream> {
|
|
97
98
|
match self {
|
|
98
99
|
TokioListener::Tcp(listener) => TokioListener::accept_tcp(listener).await,
|
|
99
100
|
TokioListener::TcpTls(listener, acceptor) => {
|
|
@@ -106,9 +107,11 @@ impl TokioListener {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
async fn accept_tcp(listener: &TokioTcpListener) -> Result<
|
|
110
|
+
async fn accept_tcp(listener: &TokioTcpListener) -> Result<AcceptedStream> {
|
|
110
111
|
let tcp_stream = listener.accept().await?;
|
|
111
|
-
Self::
|
|
112
|
+
Ok(AcceptedStream::Ready(Self::to_plain_io(Stream::TcpStream(
|
|
113
|
+
tcp_stream,
|
|
114
|
+
))))
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
pub async fn spawn_acme_event_task(&self, mut shutdown_receiver: Receiver<RunningPhase>) {
|
|
@@ -137,89 +140,131 @@ impl TokioListener {
|
|
|
137
140
|
async fn accept_tls(
|
|
138
141
|
listener: &TokioTcpListener,
|
|
139
142
|
acceptor: &ItsiTlsAcceptor,
|
|
140
|
-
) -> Result<
|
|
141
|
-
let
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
let accept_future = acme_acceptor.accept(tcp_stream.0);
|
|
148
|
-
match accept_future.await {
|
|
149
|
-
Ok(None) => Err(ItsiError::Pass),
|
|
150
|
-
Ok(Some(start_handshake)) => {
|
|
151
|
-
let tls_stream = start_handshake.into_stream(rustls_config.clone()).await?;
|
|
152
|
-
Ok(IoStream::TcpTls {
|
|
153
|
-
stream: tls_stream,
|
|
154
|
-
addr: SockAddr::Tcp(Arc::new(tcp_stream.1)),
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
Err(error) => {
|
|
158
|
-
error!(error = format!("{:?}", error));
|
|
159
|
-
Err(ItsiError::Pass)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
143
|
+
) -> Result<AcceptedStream> {
|
|
144
|
+
let (stream, addr) = listener.accept().await?;
|
|
145
|
+
Ok(AcceptedStream::TcpTls {
|
|
146
|
+
stream,
|
|
147
|
+
addr,
|
|
148
|
+
acceptor: acceptor.clone(),
|
|
149
|
+
})
|
|
164
150
|
}
|
|
165
151
|
|
|
166
|
-
async fn accept_unix(listener: &TokioUnixListener) -> Result<
|
|
152
|
+
async fn accept_unix(listener: &TokioUnixListener) -> Result<AcceptedStream> {
|
|
167
153
|
let unix_stream = listener.accept().await?;
|
|
168
|
-
|
|
154
|
+
Ok(AcceptedStream::Ready(Self::to_plain_io(
|
|
155
|
+
Stream::UnixStream(unix_stream),
|
|
156
|
+
)))
|
|
169
157
|
}
|
|
170
158
|
|
|
171
159
|
async fn accept_unix_tls(
|
|
172
160
|
listener: &TokioUnixListener,
|
|
173
161
|
acceptor: &ItsiTlsAcceptor,
|
|
174
|
-
) -> Result<
|
|
175
|
-
let
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
162
|
+
) -> Result<AcceptedStream> {
|
|
163
|
+
let (stream, addr) = listener.accept().await?;
|
|
164
|
+
Ok(AcceptedStream::UnixTls {
|
|
165
|
+
stream,
|
|
166
|
+
addr,
|
|
167
|
+
acceptor: acceptor.clone(),
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
fn to_plain_io(input_stream: Stream) -> IoStream {
|
|
172
|
+
match input_stream {
|
|
173
|
+
Stream::TcpStream((tcp_stream, socket_address)) => IoStream::Tcp {
|
|
174
|
+
stream: tcp_stream,
|
|
175
|
+
addr: SockAddr::Tcp(Arc::new(socket_address)),
|
|
176
|
+
},
|
|
177
|
+
Stream::UnixStream((unix_stream, socket_address)) => IoStream::Unix {
|
|
178
|
+
stream: unix_stream,
|
|
179
|
+
addr: SockAddr::Unix(Arc::new(socket_address)),
|
|
180
|
+
},
|
|
186
181
|
}
|
|
187
182
|
}
|
|
183
|
+
}
|
|
188
184
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
185
|
+
pub(crate) enum AcceptedStream {
|
|
186
|
+
Ready(IoStream),
|
|
187
|
+
TcpTls {
|
|
188
|
+
stream: TcpStream,
|
|
189
|
+
addr: SocketAddr,
|
|
190
|
+
acceptor: ItsiTlsAcceptor,
|
|
191
|
+
},
|
|
192
|
+
UnixTls {
|
|
193
|
+
stream: UnixStream,
|
|
194
|
+
addr: unix::SocketAddr,
|
|
195
|
+
acceptor: ItsiTlsAcceptor,
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
impl AcceptedStream {
|
|
200
|
+
pub(crate) async fn into_io_stream(self, handshake_timeout: Duration) -> Result<IoStream> {
|
|
201
|
+
match self {
|
|
202
|
+
AcceptedStream::Ready(stream) => Ok(stream),
|
|
203
|
+
AcceptedStream::TcpTls {
|
|
204
|
+
stream,
|
|
205
|
+
addr,
|
|
206
|
+
acceptor,
|
|
207
|
+
} => match acceptor {
|
|
208
|
+
ItsiTlsAcceptor::Manual(tls_acceptor) => {
|
|
209
|
+
match timeout(handshake_timeout, tls_acceptor.accept(stream)).await {
|
|
210
|
+
Ok(Ok(tls_stream)) => Ok(IoStream::TcpTls {
|
|
198
211
|
stream: tls_stream,
|
|
199
|
-
addr: SockAddr::Tcp(Arc::new(
|
|
212
|
+
addr: SockAddr::Tcp(Arc::new(addr)),
|
|
200
213
|
}),
|
|
201
|
-
Err(
|
|
214
|
+
Ok(Err(error)) => Err(error.into()),
|
|
215
|
+
Err(_) => Err(ItsiError::Pass),
|
|
202
216
|
}
|
|
203
217
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
218
|
+
ItsiTlsAcceptor::Automatic(acme_acceptor, _, rustls_config) => {
|
|
219
|
+
let accept_future = acme_acceptor.accept(stream);
|
|
220
|
+
match timeout(handshake_timeout, accept_future).await {
|
|
221
|
+
Err(_) => Err(ItsiError::Pass),
|
|
222
|
+
Ok(accept_result) => match accept_result {
|
|
223
|
+
Ok(None) => Err(ItsiError::Pass),
|
|
224
|
+
Ok(Some(start_handshake)) => {
|
|
225
|
+
match timeout(
|
|
226
|
+
handshake_timeout,
|
|
227
|
+
start_handshake.into_stream(rustls_config.clone()),
|
|
228
|
+
)
|
|
229
|
+
.await
|
|
230
|
+
{
|
|
231
|
+
Ok(Ok(tls_stream)) => Ok(IoStream::TcpTls {
|
|
232
|
+
stream: tls_stream,
|
|
233
|
+
addr: SockAddr::Tcp(Arc::new(addr)),
|
|
234
|
+
}),
|
|
235
|
+
Ok(Err(error)) => Err(error.into()),
|
|
236
|
+
Err(_) => Err(ItsiError::Pass),
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
Err(error) => {
|
|
240
|
+
error!(error = format!("{:?}", error));
|
|
241
|
+
Err(ItsiError::Pass)
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
AcceptedStream::UnixTls {
|
|
248
|
+
stream,
|
|
249
|
+
addr,
|
|
250
|
+
acceptor,
|
|
251
|
+
} => match acceptor {
|
|
252
|
+
ItsiTlsAcceptor::Manual(tls_acceptor) => {
|
|
253
|
+
match timeout(handshake_timeout, tls_acceptor.accept(stream)).await {
|
|
254
|
+
Ok(Ok(tls_stream)) => Ok(IoStream::UnixTls {
|
|
207
255
|
stream: tls_stream,
|
|
208
|
-
addr: SockAddr::Unix(Arc::new(
|
|
256
|
+
addr: SockAddr::Unix(Arc::new(addr)),
|
|
209
257
|
}),
|
|
210
|
-
Err(
|
|
258
|
+
Ok(Err(error)) => Err(error.into()),
|
|
259
|
+
Err(_) => Err(ItsiError::Pass),
|
|
211
260
|
}
|
|
212
261
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
Stream::UnixStream((unix_stream, socket_address)) => Ok(IoStream::Unix {
|
|
220
|
-
stream: unix_stream,
|
|
221
|
-
addr: SockAddr::Unix(Arc::new(socket_address)),
|
|
222
|
-
}),
|
|
262
|
+
ItsiTlsAcceptor::Automatic(_, _, _) => {
|
|
263
|
+
error!("Automatic TLS not supported on Unix sockets");
|
|
264
|
+
Err(ItsiError::UnsupportedProtocol(
|
|
265
|
+
"Automatic TLS on Unix Sockets".to_owned(),
|
|
266
|
+
))
|
|
267
|
+
}
|
|
223
268
|
},
|
|
224
269
|
}
|
|
225
270
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
use hyper_util::rt::TokioIo;
|
|
2
|
-
use std::{ops::Deref, pin::Pin, sync::Arc, time::Duration};
|
|
2
|
+
use std::{future::Future, ops::Deref, pin::Pin, sync::Arc, time::Duration};
|
|
3
3
|
use tokio::task::JoinSet;
|
|
4
4
|
use tracing::debug;
|
|
5
5
|
|
|
6
6
|
use crate::{
|
|
7
7
|
ruby_types::itsi_server::itsi_server_config::ServerParams,
|
|
8
|
-
server::{
|
|
8
|
+
server::{
|
|
9
|
+
binds::listener::{AcceptedStream, ListenerInfo},
|
|
10
|
+
io_stream::IoStream,
|
|
11
|
+
request_job::RequestJob,
|
|
12
|
+
},
|
|
9
13
|
services::itsi_http_service::{ItsiHttpService, ItsiHttpServiceInner},
|
|
10
14
|
};
|
|
11
15
|
|
|
@@ -34,19 +38,39 @@ pub struct AcceptorArgs {
|
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
impl Acceptor {
|
|
37
|
-
pub(crate) async fn
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
pub(crate) async fn serve_accepted_connection(
|
|
42
|
+
&mut self,
|
|
43
|
+
stream: AcceptedStream,
|
|
44
|
+
tls_handshake_timeout: Duration,
|
|
45
|
+
) {
|
|
46
|
+
self.spawn_connection(async move { stream.into_io_stream(tls_handshake_timeout).await });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fn spawn_connection<F>(&mut self, stream_future: F)
|
|
50
|
+
where
|
|
51
|
+
F: Future<Output = itsi_error::Result<IoStream>> + Send + 'static,
|
|
52
|
+
{
|
|
40
53
|
let mut shutdown_channel = self.shutdown_receiver.clone();
|
|
41
54
|
let acceptor_args = self.acceptor_args.clone();
|
|
42
|
-
let service = ItsiHttpService {
|
|
43
|
-
inner: Arc::new(ItsiHttpServiceInner {
|
|
44
|
-
acceptor_args: acceptor_args.clone(),
|
|
45
|
-
addr,
|
|
46
|
-
}),
|
|
47
|
-
};
|
|
48
55
|
|
|
49
56
|
self.join_set.spawn(async move {
|
|
57
|
+
let stream = match stream_future.await {
|
|
58
|
+
Ok(stream) => stream,
|
|
59
|
+
Err(error) => {
|
|
60
|
+
debug!("Connection setup failed: {:?}", error);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
let addr = stream.addr();
|
|
66
|
+
let io: TokioIo<Pin<Box<IoStream>>> = TokioIo::new(Box::pin(stream));
|
|
67
|
+
let service = ItsiHttpService {
|
|
68
|
+
inner: Arc::new(ItsiHttpServiceInner {
|
|
69
|
+
acceptor_args: acceptor_args.clone(),
|
|
70
|
+
addr,
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
|
|
50
74
|
let executor = &acceptor_args.strategy.executor;
|
|
51
75
|
let svc = hyper::service::service_fn(move |req| {
|
|
52
76
|
let service = service.clone();
|
|
@@ -314,6 +314,7 @@ impl SingleMode {
|
|
|
314
314
|
|
|
315
315
|
let shutdown_rx_for_acme_task = shutdown_receiver.clone();
|
|
316
316
|
let acme_task_listener_clone = listener.clone();
|
|
317
|
+
let tls_handshake_timeout = server_params.header_read_timeout;
|
|
317
318
|
|
|
318
319
|
let mut after_accept_wait: Option<Duration> = None::<Duration>;
|
|
319
320
|
|
|
@@ -337,7 +338,7 @@ impl SingleMode {
|
|
|
337
338
|
tokio::select! {
|
|
338
339
|
accept_result = listener.accept() => {
|
|
339
340
|
match accept_result {
|
|
340
|
-
Ok(accepted) => acceptor.
|
|
341
|
+
Ok(accepted) => acceptor.serve_accepted_connection(accepted, tls_handshake_timeout).await,
|
|
341
342
|
Err(e) => debug!("Listener.accept failed: {:?}", e)
|
|
342
343
|
}
|
|
343
344
|
if cfg!(target_os = "macos") {
|
data/gems/scheduler/Cargo.lock
CHANGED
data/gems/server/Cargo.lock
CHANGED
|
@@ -1660,9 +1660,27 @@ version = "1.0.15"
|
|
|
1660
1660
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1661
1661
|
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|
1662
1662
|
|
|
1663
|
+
[[package]]
|
|
1664
|
+
name = "itsi-scheduler"
|
|
1665
|
+
version = "0.2.24"
|
|
1666
|
+
dependencies = [
|
|
1667
|
+
"bytes",
|
|
1668
|
+
"derive_more",
|
|
1669
|
+
"itsi_error",
|
|
1670
|
+
"itsi_instrument_entry",
|
|
1671
|
+
"itsi_rb_helpers",
|
|
1672
|
+
"itsi_tracing",
|
|
1673
|
+
"magnus",
|
|
1674
|
+
"mio",
|
|
1675
|
+
"nix",
|
|
1676
|
+
"parking_lot",
|
|
1677
|
+
"rb-sys",
|
|
1678
|
+
"tracing",
|
|
1679
|
+
]
|
|
1680
|
+
|
|
1663
1681
|
[[package]]
|
|
1664
1682
|
name = "itsi-server"
|
|
1665
|
-
version = "0.2.
|
|
1683
|
+
version = "0.2.24"
|
|
1666
1684
|
dependencies = [
|
|
1667
1685
|
"argon2",
|
|
1668
1686
|
"async-channel",
|
|
@@ -1772,6 +1790,15 @@ dependencies = [
|
|
|
1772
1790
|
"thiserror 2.0.12",
|
|
1773
1791
|
]
|
|
1774
1792
|
|
|
1793
|
+
[[package]]
|
|
1794
|
+
name = "itsi_instrument_entry"
|
|
1795
|
+
version = "0.1.0"
|
|
1796
|
+
dependencies = [
|
|
1797
|
+
"proc-macro2",
|
|
1798
|
+
"quote",
|
|
1799
|
+
"syn 1.0.109",
|
|
1800
|
+
]
|
|
1801
|
+
|
|
1775
1802
|
[[package]]
|
|
1776
1803
|
name = "itsi_rb_helpers"
|
|
1777
1804
|
version = "0.1.0"
|
|
@@ -8,6 +8,7 @@ require "itsi/server"
|
|
|
8
8
|
require "itsi/scheduler"
|
|
9
9
|
require "socket"
|
|
10
10
|
require "net/http"
|
|
11
|
+
require "openssl"
|
|
11
12
|
require "minitest/autorun"
|
|
12
13
|
|
|
13
14
|
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
|
@@ -157,6 +158,7 @@ class RequestContext
|
|
|
157
158
|
@uri.host,
|
|
158
159
|
@uri.port,
|
|
159
160
|
use_ssl: @uri.scheme == "https",
|
|
161
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
|
160
162
|
**opts
|
|
161
163
|
)
|
|
162
164
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require_relative "../helpers/test_helper"
|
|
2
|
+
|
|
3
|
+
class TestTlsHandshakeTimeout < Minitest::Test
|
|
4
|
+
def test_incomplete_tls_handshake_does_not_block_listener_indefinitely
|
|
5
|
+
server(
|
|
6
|
+
protocol: "https",
|
|
7
|
+
itsi_rb: lambda do
|
|
8
|
+
header_read_timeout 5.0
|
|
9
|
+
get("/ok") { |r| r.ok "ok" }
|
|
10
|
+
end
|
|
11
|
+
) do
|
|
12
|
+
socket = TCPSocket.new("127.0.0.1", @uri.port)
|
|
13
|
+
|
|
14
|
+
assert_equal "ok", get("/ok")
|
|
15
|
+
ensure
|
|
16
|
+
socket&.close
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/itsi/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: itsi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.24
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wouter Coppieters
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.24
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.2.
|
|
25
|
+
version: 0.2.24
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: itsi-server
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.2.
|
|
32
|
+
version: 0.2.24
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.2.
|
|
39
|
+
version: 0.2.24
|
|
40
40
|
description: Wrapper Gem for both the Itsi server and the Itsi Fiber scheduler
|
|
41
41
|
email:
|
|
42
42
|
- wc@pico.net.nz
|
|
@@ -1139,6 +1139,7 @@ files:
|
|
|
1139
1139
|
- gems/server/test/options/test_request_timeout.rb
|
|
1140
1140
|
- gems/server/test/options/test_threads.rb
|
|
1141
1141
|
- gems/server/test/options/test_workers.rb
|
|
1142
|
+
- gems/server/test/options/tls_handshake_timeout.rb
|
|
1142
1143
|
- gems/server/test/options/unmatched_request.rb
|
|
1143
1144
|
- gems/server/test/rack/test_rack_server.rb
|
|
1144
1145
|
- gems/server/vendor/rb-sys-build/.cargo-ok
|