itsi-server 0.1.1
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 +7 -0
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +22 -0
- data/exe/itsi +84 -0
- data/ext/itsi_error/Cargo.lock +368 -0
- data/ext/itsi_error/Cargo.toml +9 -0
- data/ext/itsi_error/src/lib.rs +49 -0
- data/ext/itsi_rb_helpers/Cargo.lock +355 -0
- data/ext/itsi_rb_helpers/Cargo.toml +8 -0
- data/ext/itsi_rb_helpers/src/lib.rs +98 -0
- data/ext/itsi_server/Cargo.toml +29 -0
- data/ext/itsi_server/extconf.rb +6 -0
- data/ext/itsi_server/src/lib.rs +52 -0
- data/ext/itsi_server/src/request/itsi_request.rs +143 -0
- data/ext/itsi_server/src/request/mod.rs +1 -0
- data/ext/itsi_server/src/server/bind.rs +138 -0
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +32 -0
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +52 -0
- data/ext/itsi_server/src/server/itsi_server.rs +182 -0
- data/ext/itsi_server/src/server/listener.rs +218 -0
- data/ext/itsi_server/src/server/mod.rs +5 -0
- data/ext/itsi_server/src/server/tls.rs +138 -0
- data/ext/itsi_server/src/server/transfer_protocol.rs +23 -0
- data/ext/itsi_server/src/stream_writer/mod.rs +21 -0
- data/ext/itsi_tracing/Cargo.lock +274 -0
- data/ext/itsi_tracing/Cargo.toml +12 -0
- data/ext/itsi_tracing/src/lib.rs +11 -0
- data/lib/itsi/request.rb +39 -0
- data/lib/itsi/server/version.rb +7 -0
- data/lib/itsi/server.rb +21 -0
- data/sig/itsi_server.rbs +4 -0
- metadata +121 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
use base64::{engine::general_purpose, Engine as _};
|
2
|
+
use itsi_error::Result;
|
3
|
+
use itsi_tracing::{info, warn};
|
4
|
+
use rcgen::{CertificateParams, DnType, KeyPair, SanType};
|
5
|
+
use rustls_pemfile::{certs, pkcs8_private_keys};
|
6
|
+
use std::{collections::HashMap, fs, io::BufReader};
|
7
|
+
use tokio_rustls::rustls::{Certificate, PrivateKey, ServerConfig};
|
8
|
+
|
9
|
+
const ITS_CA_CERT: &str = include_str!("./itsi_ca/itsi_ca.crt");
|
10
|
+
const ITS_CA_KEY: &str = include_str!("./itsi_ca/itsi_ca.key");
|
11
|
+
|
12
|
+
// Generates a TLS configuration based on either :
|
13
|
+
// * Input "cert" and "key" options (either paths or Base64-encoded strings) or
|
14
|
+
// * Performs automatic certificate generation/retrieval. Generated certs use an internal self-signed Isti CA.
|
15
|
+
// If a non-local host or optional domain parameter is provided,
|
16
|
+
// an automated certificate will attempt to be fetched using let's encrypt.
|
17
|
+
pub fn configure_tls(host: &str, query_params: &HashMap<String, String>) -> Result<ServerConfig> {
|
18
|
+
let (certs, key) = if let (Some(cert_path), Some(key_path)) =
|
19
|
+
(query_params.get("cert"), query_params.get("key"))
|
20
|
+
{
|
21
|
+
// Load from file or Base64
|
22
|
+
let certs = load_certs(cert_path);
|
23
|
+
let key = load_private_key(key_path);
|
24
|
+
(certs, key)
|
25
|
+
} else if query_params
|
26
|
+
.get("cert")
|
27
|
+
.map(|v| v == "auto")
|
28
|
+
.unwrap_or(false)
|
29
|
+
{
|
30
|
+
let domain_param = query_params.get("domain");
|
31
|
+
let host_string = host.to_string();
|
32
|
+
let domain = domain_param.or_else(|| {
|
33
|
+
if host_string != "localhost" {
|
34
|
+
Some(&host_string)
|
35
|
+
} else {
|
36
|
+
None
|
37
|
+
}
|
38
|
+
});
|
39
|
+
|
40
|
+
if let Some(domain) = domain {
|
41
|
+
retrieve_acme_cert(domain)?
|
42
|
+
} else {
|
43
|
+
generate_ca_signed_cert(host)?
|
44
|
+
}
|
45
|
+
} else {
|
46
|
+
generate_ca_signed_cert(host)?
|
47
|
+
};
|
48
|
+
|
49
|
+
let mut config = ServerConfig::builder()
|
50
|
+
.with_safe_defaults()
|
51
|
+
.with_no_client_auth()
|
52
|
+
.with_single_cert(certs, key)
|
53
|
+
.expect("Failed to build TLS config");
|
54
|
+
|
55
|
+
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
|
56
|
+
Ok(config)
|
57
|
+
}
|
58
|
+
|
59
|
+
pub fn load_certs(path: &str) -> Vec<Certificate> {
|
60
|
+
let data = if let Some(stripped) = path.strip_prefix("base64:") {
|
61
|
+
general_purpose::STANDARD
|
62
|
+
.decode(stripped)
|
63
|
+
.expect("Invalid base64 certificate")
|
64
|
+
} else {
|
65
|
+
fs::read(path).expect("Failed to read certificate file")
|
66
|
+
};
|
67
|
+
|
68
|
+
if data.starts_with(b"-----BEGIN ") {
|
69
|
+
let mut reader = BufReader::new(&data[..]);
|
70
|
+
let certs_der: Vec<Vec<u8>> = certs(&mut reader)
|
71
|
+
.map(|r| {
|
72
|
+
r.map(|der| der.as_ref().to_vec())
|
73
|
+
.map_err(itsi_error::ItsiError::from)
|
74
|
+
})
|
75
|
+
.collect::<Result<_>>()
|
76
|
+
.expect("Failed to parse certificate file");
|
77
|
+
certs_der.into_iter().map(Certificate).collect()
|
78
|
+
} else {
|
79
|
+
vec![Certificate(data)]
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
/// Loads a private key from a file or Base64.
|
84
|
+
pub fn load_private_key(path: &str) -> PrivateKey {
|
85
|
+
let key_data = if let Some(stripped) = path.strip_prefix("base64:") {
|
86
|
+
general_purpose::STANDARD
|
87
|
+
.decode(stripped)
|
88
|
+
.expect("Invalid base64 private key")
|
89
|
+
} else {
|
90
|
+
fs::read(path).expect("Failed to read private key file")
|
91
|
+
};
|
92
|
+
|
93
|
+
if key_data.starts_with(b"-----BEGIN ") {
|
94
|
+
let mut reader = BufReader::new(&key_data[..]);
|
95
|
+
let keys: Vec<Vec<u8>> = pkcs8_private_keys(&mut reader)
|
96
|
+
.map(|r| {
|
97
|
+
r.map(|key| key.secret_pkcs8_der().to_vec())
|
98
|
+
.map_err(itsi_error::ItsiError::from)
|
99
|
+
})
|
100
|
+
.collect::<Result<_>>()
|
101
|
+
.expect("Failed to parse private key");
|
102
|
+
if !keys.is_empty() {
|
103
|
+
return PrivateKey(keys[0].clone());
|
104
|
+
}
|
105
|
+
}
|
106
|
+
PrivateKey(key_data)
|
107
|
+
}
|
108
|
+
|
109
|
+
pub fn generate_ca_signed_cert(domain: &str) -> Result<(Vec<Certificate>, PrivateKey)> {
|
110
|
+
info!("Generating New Itsi CA - Self signed Certificate. Use `itsi ca export` to export the CA certificate for import into your local trust store.");
|
111
|
+
|
112
|
+
let ca_kp = KeyPair::from_pem(ITS_CA_KEY).unwrap();
|
113
|
+
let params = CertificateParams::from_ca_cert_pem(ITS_CA_CERT).unwrap();
|
114
|
+
|
115
|
+
let ca_cert = params.self_signed(&ca_kp).unwrap();
|
116
|
+
let ee_key = KeyPair::generate().unwrap();
|
117
|
+
let mut ee_params = CertificateParams::default();
|
118
|
+
|
119
|
+
// Set the domain in the subject alternative names (SAN)
|
120
|
+
ee_params.subject_alt_names = vec![SanType::DnsName(domain.try_into()?)];
|
121
|
+
// Optionally, set the Common Name (CN) in the distinguished name:
|
122
|
+
ee_params
|
123
|
+
.distinguished_name
|
124
|
+
.push(DnType::CommonName, domain);
|
125
|
+
|
126
|
+
ee_params.use_authority_key_identifier_extension = true;
|
127
|
+
|
128
|
+
let ee_cert = ee_params.signed_by(&ee_key, &ca_cert, &ee_key).unwrap();
|
129
|
+
let ee_cert_der = ee_cert.der().to_vec();
|
130
|
+
let ee_cert = Certificate(ee_cert_der);
|
131
|
+
Ok((vec![ee_cert], PrivateKey(ee_key.serialize_der())))
|
132
|
+
}
|
133
|
+
|
134
|
+
/// Retrieves an ACME certificate for a given domain.
|
135
|
+
pub fn retrieve_acme_cert(domain: &str) -> Result<(Vec<Certificate>, PrivateKey)> {
|
136
|
+
warn!("Retrieving ACME cert for {}", domain);
|
137
|
+
generate_ca_signed_cert(domain)
|
138
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
use itsi_error::ItsiError;
|
2
|
+
use std::str::FromStr;
|
3
|
+
|
4
|
+
#[derive(Debug, Default, Clone)]
|
5
|
+
pub enum TransferProtocol {
|
6
|
+
#[default]
|
7
|
+
Https,
|
8
|
+
Http,
|
9
|
+
Unix,
|
10
|
+
}
|
11
|
+
|
12
|
+
impl FromStr for TransferProtocol {
|
13
|
+
type Err = ItsiError;
|
14
|
+
|
15
|
+
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
16
|
+
match s {
|
17
|
+
"http" => Ok(TransferProtocol::Http),
|
18
|
+
"https" => Ok(TransferProtocol::Https),
|
19
|
+
"unix" => Ok(TransferProtocol::Unix),
|
20
|
+
_ => Err(ItsiError::UnsupportedProtocol(s.to_string())),
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
use bytes::Bytes;
|
2
|
+
use magnus::{error::Result as MagnusResult, exception::io_error, Error};
|
3
|
+
use tokio::sync::mpsc::Sender;
|
4
|
+
|
5
|
+
#[magnus::wrap(class = "Itsi::StreamWriter", free_immediately, size)]
|
6
|
+
pub struct StreamWriter {
|
7
|
+
sender: Sender<Bytes>,
|
8
|
+
}
|
9
|
+
|
10
|
+
impl StreamWriter {
|
11
|
+
pub fn new(sender: Sender<Bytes>) -> Self {
|
12
|
+
StreamWriter { sender }
|
13
|
+
}
|
14
|
+
|
15
|
+
pub fn write(&self, bytes: Bytes) -> MagnusResult<()> {
|
16
|
+
self.sender
|
17
|
+
.blocking_send(bytes)
|
18
|
+
.map_err(|e| Error::new(io_error(), format!("{:?}", e)))?;
|
19
|
+
Ok(())
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,274 @@
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
2
|
+
# It is not intended for manual editing.
|
3
|
+
version = 4
|
4
|
+
|
5
|
+
[[package]]
|
6
|
+
name = "aho-corasick"
|
7
|
+
version = "1.1.3"
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
9
|
+
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
10
|
+
dependencies = [
|
11
|
+
"memchr",
|
12
|
+
]
|
13
|
+
|
14
|
+
[[package]]
|
15
|
+
name = "cfg-if"
|
16
|
+
version = "1.0.0"
|
17
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
18
|
+
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
19
|
+
|
20
|
+
[[package]]
|
21
|
+
name = "itsi_tracing"
|
22
|
+
version = "0.1.0"
|
23
|
+
dependencies = [
|
24
|
+
"tracing",
|
25
|
+
"tracing-subscriber",
|
26
|
+
]
|
27
|
+
|
28
|
+
[[package]]
|
29
|
+
name = "lazy_static"
|
30
|
+
version = "1.5.0"
|
31
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
32
|
+
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
33
|
+
|
34
|
+
[[package]]
|
35
|
+
name = "log"
|
36
|
+
version = "0.4.26"
|
37
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
38
|
+
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
39
|
+
|
40
|
+
[[package]]
|
41
|
+
name = "matchers"
|
42
|
+
version = "0.1.0"
|
43
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
44
|
+
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
45
|
+
dependencies = [
|
46
|
+
"regex-automata 0.1.10",
|
47
|
+
]
|
48
|
+
|
49
|
+
[[package]]
|
50
|
+
name = "memchr"
|
51
|
+
version = "2.7.4"
|
52
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
53
|
+
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
54
|
+
|
55
|
+
[[package]]
|
56
|
+
name = "nu-ansi-term"
|
57
|
+
version = "0.46.0"
|
58
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
59
|
+
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
60
|
+
dependencies = [
|
61
|
+
"overload",
|
62
|
+
"winapi",
|
63
|
+
]
|
64
|
+
|
65
|
+
[[package]]
|
66
|
+
name = "once_cell"
|
67
|
+
version = "1.20.3"
|
68
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
69
|
+
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
70
|
+
|
71
|
+
[[package]]
|
72
|
+
name = "overload"
|
73
|
+
version = "0.1.1"
|
74
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
75
|
+
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
76
|
+
|
77
|
+
[[package]]
|
78
|
+
name = "pin-project-lite"
|
79
|
+
version = "0.2.16"
|
80
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
81
|
+
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
82
|
+
|
83
|
+
[[package]]
|
84
|
+
name = "proc-macro2"
|
85
|
+
version = "1.0.93"
|
86
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
87
|
+
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
88
|
+
dependencies = [
|
89
|
+
"unicode-ident",
|
90
|
+
]
|
91
|
+
|
92
|
+
[[package]]
|
93
|
+
name = "quote"
|
94
|
+
version = "1.0.38"
|
95
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
96
|
+
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
97
|
+
dependencies = [
|
98
|
+
"proc-macro2",
|
99
|
+
]
|
100
|
+
|
101
|
+
[[package]]
|
102
|
+
name = "regex"
|
103
|
+
version = "1.11.1"
|
104
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
105
|
+
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
106
|
+
dependencies = [
|
107
|
+
"aho-corasick",
|
108
|
+
"memchr",
|
109
|
+
"regex-automata 0.4.9",
|
110
|
+
"regex-syntax 0.8.5",
|
111
|
+
]
|
112
|
+
|
113
|
+
[[package]]
|
114
|
+
name = "regex-automata"
|
115
|
+
version = "0.1.10"
|
116
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
117
|
+
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
118
|
+
dependencies = [
|
119
|
+
"regex-syntax 0.6.29",
|
120
|
+
]
|
121
|
+
|
122
|
+
[[package]]
|
123
|
+
name = "regex-automata"
|
124
|
+
version = "0.4.9"
|
125
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
126
|
+
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
127
|
+
dependencies = [
|
128
|
+
"aho-corasick",
|
129
|
+
"memchr",
|
130
|
+
"regex-syntax 0.8.5",
|
131
|
+
]
|
132
|
+
|
133
|
+
[[package]]
|
134
|
+
name = "regex-syntax"
|
135
|
+
version = "0.6.29"
|
136
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
137
|
+
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
138
|
+
|
139
|
+
[[package]]
|
140
|
+
name = "regex-syntax"
|
141
|
+
version = "0.8.5"
|
142
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
143
|
+
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
144
|
+
|
145
|
+
[[package]]
|
146
|
+
name = "sharded-slab"
|
147
|
+
version = "0.1.7"
|
148
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
149
|
+
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
|
150
|
+
dependencies = [
|
151
|
+
"lazy_static",
|
152
|
+
]
|
153
|
+
|
154
|
+
[[package]]
|
155
|
+
name = "smallvec"
|
156
|
+
version = "1.14.0"
|
157
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
158
|
+
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
159
|
+
|
160
|
+
[[package]]
|
161
|
+
name = "syn"
|
162
|
+
version = "2.0.98"
|
163
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
164
|
+
checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1"
|
165
|
+
dependencies = [
|
166
|
+
"proc-macro2",
|
167
|
+
"quote",
|
168
|
+
"unicode-ident",
|
169
|
+
]
|
170
|
+
|
171
|
+
[[package]]
|
172
|
+
name = "thread_local"
|
173
|
+
version = "1.1.8"
|
174
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
175
|
+
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
176
|
+
dependencies = [
|
177
|
+
"cfg-if",
|
178
|
+
"once_cell",
|
179
|
+
]
|
180
|
+
|
181
|
+
[[package]]
|
182
|
+
name = "tracing"
|
183
|
+
version = "0.1.41"
|
184
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
185
|
+
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
186
|
+
dependencies = [
|
187
|
+
"pin-project-lite",
|
188
|
+
"tracing-attributes",
|
189
|
+
"tracing-core",
|
190
|
+
]
|
191
|
+
|
192
|
+
[[package]]
|
193
|
+
name = "tracing-attributes"
|
194
|
+
version = "0.1.28"
|
195
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
196
|
+
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
197
|
+
dependencies = [
|
198
|
+
"proc-macro2",
|
199
|
+
"quote",
|
200
|
+
"syn",
|
201
|
+
]
|
202
|
+
|
203
|
+
[[package]]
|
204
|
+
name = "tracing-core"
|
205
|
+
version = "0.1.33"
|
206
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
207
|
+
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
208
|
+
dependencies = [
|
209
|
+
"once_cell",
|
210
|
+
"valuable",
|
211
|
+
]
|
212
|
+
|
213
|
+
[[package]]
|
214
|
+
name = "tracing-log"
|
215
|
+
version = "0.2.0"
|
216
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
217
|
+
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
|
218
|
+
dependencies = [
|
219
|
+
"log",
|
220
|
+
"once_cell",
|
221
|
+
"tracing-core",
|
222
|
+
]
|
223
|
+
|
224
|
+
[[package]]
|
225
|
+
name = "tracing-subscriber"
|
226
|
+
version = "0.3.19"
|
227
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
228
|
+
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
229
|
+
dependencies = [
|
230
|
+
"matchers",
|
231
|
+
"nu-ansi-term",
|
232
|
+
"once_cell",
|
233
|
+
"regex",
|
234
|
+
"sharded-slab",
|
235
|
+
"smallvec",
|
236
|
+
"thread_local",
|
237
|
+
"tracing",
|
238
|
+
"tracing-core",
|
239
|
+
"tracing-log",
|
240
|
+
]
|
241
|
+
|
242
|
+
[[package]]
|
243
|
+
name = "unicode-ident"
|
244
|
+
version = "1.0.17"
|
245
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
246
|
+
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
|
247
|
+
|
248
|
+
[[package]]
|
249
|
+
name = "valuable"
|
250
|
+
version = "0.1.1"
|
251
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
252
|
+
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
253
|
+
|
254
|
+
[[package]]
|
255
|
+
name = "winapi"
|
256
|
+
version = "0.3.9"
|
257
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
258
|
+
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
259
|
+
dependencies = [
|
260
|
+
"winapi-i686-pc-windows-gnu",
|
261
|
+
"winapi-x86_64-pc-windows-gnu",
|
262
|
+
]
|
263
|
+
|
264
|
+
[[package]]
|
265
|
+
name = "winapi-i686-pc-windows-gnu"
|
266
|
+
version = "0.4.0"
|
267
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
268
|
+
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
269
|
+
|
270
|
+
[[package]]
|
271
|
+
name = "winapi-x86_64-pc-windows-gnu"
|
272
|
+
version = "0.4.0"
|
273
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
274
|
+
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
pub use tracing::{debug, error, info, trace, warn};
|
2
|
+
use tracing_subscriber::{EnvFilter, fmt};
|
3
|
+
|
4
|
+
pub fn init() {
|
5
|
+
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
|
6
|
+
let format = fmt::format().with_level(true).with_target(false).compact();
|
7
|
+
tracing_subscriber::fmt()
|
8
|
+
.with_env_filter(env_filter)
|
9
|
+
.event_format(format)
|
10
|
+
.init();
|
11
|
+
}
|
data/lib/itsi/request.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
module Itsi
|
6
|
+
class Request
|
7
|
+
def to_env
|
8
|
+
{
|
9
|
+
"SERVER_SOFTWARE" => "Itsi",
|
10
|
+
"SCRIPT_NAME" => script_name,
|
11
|
+
"REQUEST_METHOD" => method,
|
12
|
+
"PATH_INFO" => path,
|
13
|
+
"REQUEST_PATH" => path,
|
14
|
+
"QUERY_STRING" => query_string,
|
15
|
+
"REMOTE_ADDR" => remote_addr,
|
16
|
+
"SERVER_NAME" => host,
|
17
|
+
"SERVER_PORT" => port.to_s,
|
18
|
+
"SERVER_PROTOCOL" => version,
|
19
|
+
"HTTP_VERSION" => version,
|
20
|
+
"HTTP_HOST" => host,
|
21
|
+
"rack.input" => StringIO.new(body),
|
22
|
+
"rack.errors" => $stderr,
|
23
|
+
"rack.version" => version,
|
24
|
+
"rack.multithread" => true,
|
25
|
+
"rack.multiprocess" => true,
|
26
|
+
"rack.run_once" => false,
|
27
|
+
"rack.multipart.buffer_size" => 16_384
|
28
|
+
}.merge(
|
29
|
+
headers.transform_keys do |k|
|
30
|
+
case k
|
31
|
+
when "content-length" then "CONTENT_LENGTH"
|
32
|
+
when "content-type" then "CONTENT_TYPE"
|
33
|
+
else "HTTP_#{k.upcase.tr("-", "_")}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/itsi/server.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "server/version"
|
4
|
+
require_relative "server/itsi_server"
|
5
|
+
|
6
|
+
module Itsi
|
7
|
+
class Server
|
8
|
+
# Call our Rack app with our request ENV.
|
9
|
+
def self.call(app, request)
|
10
|
+
app.call(request.to_env)
|
11
|
+
end
|
12
|
+
|
13
|
+
# If scheduler is enabled
|
14
|
+
# Each request is wrapped in a Fiber.
|
15
|
+
def self.schedule(app, request)
|
16
|
+
Fiber.schedule do
|
17
|
+
call(app, request)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/sig/itsi_server.rbs
ADDED
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: itsi-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Wouter Coppieters
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-03-01 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: libclang
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '14.0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '14.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rb_sys
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.9.91
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.9.91
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: rack
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '2'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2'
|
54
|
+
description: Itsi Server - A light-weight Rack Server implementation for Ruby
|
55
|
+
email:
|
56
|
+
- wc@pico.net.nz
|
57
|
+
executables:
|
58
|
+
- itsi
|
59
|
+
extensions:
|
60
|
+
- ext/itsi_server/extconf.rb
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".rubocop.yml"
|
64
|
+
- CHANGELOG.md
|
65
|
+
- CODE_OF_CONDUCT.md
|
66
|
+
- LICENSE.txt
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- exe/itsi
|
70
|
+
- ext/itsi_error/Cargo.lock
|
71
|
+
- ext/itsi_error/Cargo.toml
|
72
|
+
- ext/itsi_error/src/lib.rs
|
73
|
+
- ext/itsi_rb_helpers/Cargo.lock
|
74
|
+
- ext/itsi_rb_helpers/Cargo.toml
|
75
|
+
- ext/itsi_rb_helpers/src/lib.rs
|
76
|
+
- ext/itsi_server/Cargo.toml
|
77
|
+
- ext/itsi_server/extconf.rb
|
78
|
+
- ext/itsi_server/src/lib.rs
|
79
|
+
- ext/itsi_server/src/request/itsi_request.rs
|
80
|
+
- ext/itsi_server/src/request/mod.rs
|
81
|
+
- ext/itsi_server/src/server/bind.rs
|
82
|
+
- ext/itsi_server/src/server/itsi_ca/itsi_ca.crt
|
83
|
+
- ext/itsi_server/src/server/itsi_ca/itsi_ca.key
|
84
|
+
- ext/itsi_server/src/server/itsi_server.rs
|
85
|
+
- ext/itsi_server/src/server/listener.rs
|
86
|
+
- ext/itsi_server/src/server/mod.rs
|
87
|
+
- ext/itsi_server/src/server/tls.rs
|
88
|
+
- ext/itsi_server/src/server/transfer_protocol.rs
|
89
|
+
- ext/itsi_server/src/stream_writer/mod.rs
|
90
|
+
- ext/itsi_tracing/Cargo.lock
|
91
|
+
- ext/itsi_tracing/Cargo.toml
|
92
|
+
- ext/itsi_tracing/src/lib.rs
|
93
|
+
- lib/itsi/request.rb
|
94
|
+
- lib/itsi/server.rb
|
95
|
+
- lib/itsi/server/version.rb
|
96
|
+
- sig/itsi_server.rbs
|
97
|
+
homepage: https://itsi.fyi
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata:
|
101
|
+
homepage_uri: https://itsi.fyi
|
102
|
+
source_code_uri: https://github.com/wouterken/itsi/server
|
103
|
+
changelog_uri: https://github.com/wouterken/itsi/server/blob/main/CHANGELOG.md
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 3.1.0
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: 3.3.11
|
117
|
+
requirements: []
|
118
|
+
rubygems_version: 3.6.2
|
119
|
+
specification_version: 4
|
120
|
+
summary: Itsi Server - A light-weight Rack Server implementation for Ruby.
|
121
|
+
test_files: []
|