itsi 0.2.4 → 0.2.6
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/Cargo.lock +2 -2
- data/crates/itsi_rb_helpers/src/lib.rs +0 -1
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.toml +1 -1
- data/crates/itsi_server/src/services/static_file_server.rs +2 -2
- data/docs/content/getting_started/signals.md +0 -1
- data/docs/static/android-chrome-192x192.png +0 -0
- data/docs/static/android-chrome-310x310.png +0 -0
- data/docs/static/apple-touch-icon.png +0 -0
- data/docs/static/browserconfig.xml +12 -0
- data/docs/static/favicon-114x114.png +0 -0
- data/docs/static/favicon-120x120.png +0 -0
- data/docs/static/favicon-144x144.png +0 -0
- data/docs/static/favicon-150x150.png +0 -0
- data/docs/static/favicon-152x152.png +0 -0
- data/docs/static/favicon-16x16.png +0 -0
- data/docs/static/favicon-180x180.png +0 -0
- data/docs/static/favicon-192x192.png +0 -0
- data/docs/static/favicon-310x310.png +0 -0
- data/docs/static/favicon-32x32.png +0 -0
- data/docs/static/favicon-57x57.png +0 -0
- data/docs/static/favicon-60x60.png +0 -0
- data/docs/static/favicon-70x70.png +0 -0
- data/docs/static/favicon-72x72.png +0 -0
- data/docs/static/favicon-76x76.png +0 -0
- data/docs/static/favicon-96x96.png +0 -0
- data/docs/static/favicon-dark.svg +40 -0
- data/docs/static/favicon.ico +0 -0
- data/docs/static/favicon.svg +40 -0
- data/docs/static/site.webmanifest +20 -0
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +1 -1
- data/gems/server/lib/itsi/http_request.rb +62 -45
- data/gems/server/lib/itsi/server/config/middleware/auth_api_key.rb +4 -4
- data/gems/server/lib/itsi/server/config/middleware/auth_basic.rb +6 -4
- data/gems/server/lib/itsi/server/config/middleware/grpc.md +1 -3
- data/gems/server/lib/itsi/server/config/middleware/location.md +2 -2
- data/gems/server/lib/itsi/server/config/middleware/log_requests.md +3 -1
- data/gems/server/lib/itsi/server/config/middleware/proxy.md +7 -7
- data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +2 -2
- data/gems/server/lib/itsi/server/config/options/_index.md +9 -5
- data/gems/server/lib/itsi/server/config/options/reuse_address.md +2 -0
- data/gems/server/lib/itsi/server/config/options/reuse_address.rb +1 -1
- data/gems/server/lib/itsi/server/config/options/reuse_port.md +2 -0
- data/gems/server/lib/itsi/server/config/options/reuse_port.rb +1 -1
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/test/middleware/grpc/test_service.proto +0 -1
- data/gems/server/test/middleware/grpc/test_service_impl.rb +0 -4
- data/gems/server/test/middleware/grpc/test_service_services_pb.rb +1 -1
- data/lib/itsi/version.rb +1 -1
- data/tasks.txt +4 -2
- metadata +29 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 149fcb6ea7294774f71e351c52ae1caa173c66e5b3de4d9c949795a435a7f01b
|
4
|
+
data.tar.gz: f691a13139c6a5a43334b9f33da2896d173b48169f76cf206b4cf2f8d8c7da40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1abb41219076c668b01f6db8b5d7ec8577bc7b7d8573fd6e3ec9f707af16940aefd1c0003a414b5a9c3a409b7b6329d2f3cbc66853a618d0569ce5fd0f4be4e1
|
7
|
+
data.tar.gz: ed79a245af6a26cb5aaa3112c092de25ab6b47cdd1551178820e84ab617760e55ee25ab05bded85062dd13eacaa6026cca055f7dbf13096c679704c21ecf2868
|
data/Cargo.lock
CHANGED
@@ -1644,7 +1644,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|
1644
1644
|
|
1645
1645
|
[[package]]
|
1646
1646
|
name = "itsi-scheduler"
|
1647
|
-
version = "0.2.
|
1647
|
+
version = "0.2.6"
|
1648
1648
|
dependencies = [
|
1649
1649
|
"bytes",
|
1650
1650
|
"derive_more",
|
@@ -1662,7 +1662,7 @@ dependencies = [
|
|
1662
1662
|
|
1663
1663
|
[[package]]
|
1664
1664
|
name = "itsi-server"
|
1665
|
-
version = "0.2.
|
1665
|
+
version = "0.2.6"
|
1666
1666
|
dependencies = [
|
1667
1667
|
"argon2",
|
1668
1668
|
"async-channel",
|
@@ -662,7 +662,7 @@ impl StaticFileServer {
|
|
662
662
|
let range_length = end - start + 1;
|
663
663
|
let limited_reader = tokio::io::AsyncReadExt::take(file, range_length);
|
664
664
|
let path_clone = path.clone();
|
665
|
-
let stream = ReaderStream::
|
665
|
+
let stream = ReaderStream::with_capacity(limited_reader, 64 * 1024)
|
666
666
|
.map_ok(Frame::data)
|
667
667
|
.map_err(move |e| {
|
668
668
|
warn!("Error streaming file {}: {}", path_clone.display(), e);
|
@@ -681,7 +681,7 @@ impl StaticFileServer {
|
|
681
681
|
match File::open(&path).await {
|
682
682
|
Ok(file) => {
|
683
683
|
let path_clone = path.clone();
|
684
|
-
let stream = ReaderStream::
|
684
|
+
let stream = ReaderStream::with_capacity(file, 64 * 1024)
|
685
685
|
.map_ok(Frame::data)
|
686
686
|
.map_err(move |e| {
|
687
687
|
warn!("Error streaming file {}: {}", path_clone.display(), e);
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
<?xml version="1.0" encoding="utf-8"?>
|
3
|
+
<browserconfig>
|
4
|
+
<msapplication>
|
5
|
+
<tile>
|
6
|
+
<square70x70logo src="/favicon-70x70.png"/>
|
7
|
+
<square150x150logo src="/favicon-150x150.png"/>
|
8
|
+
<square310x310logo src="/favicon-310x310.png"/>
|
9
|
+
<TileColor>#ffffff</TileColor>
|
10
|
+
</tile>
|
11
|
+
</msapplication>
|
12
|
+
</browserconfig>
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
3
|
+
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
4
|
+
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
5
|
+
width="152.000000pt" height="152.000000pt" viewBox="0 0 152.000000 152.000000"
|
6
|
+
preserveAspectRatio="xMidYMid meet">
|
7
|
+
|
8
|
+
<g transform="translate(0.000000,152.000000) scale(0.100000,-0.100000)"
|
9
|
+
fill="#000000" stroke="none">
|
10
|
+
<path d="M390 1358 c-11 -12 -20 -31 -20 -43 0 -15 -12 -24 -49 -38 -100 -35
|
11
|
+
-194 -150 -208 -253 -5 -36 -11 -48 -29 -55 -18 -6 -24 -16 -24 -37 0 -45 15
|
12
|
+
-52 121 -52 l96 0 7 -42 c15 -94 78 -185 163 -235 34 -20 43 -31 43 -52 0 -45
|
13
|
+
28 -125 59 -168 23 -31 31 -58 40 -128 7 -49 17 -97 22 -107 14 -27 51 -38
|
14
|
+
120 -38 75 0 104 24 114 94 l7 46 58 0 58 0 13 -57 c17 -69 37 -83 121 -83 81
|
15
|
+
0 91 13 106 129 9 77 16 98 39 126 28 34 31 35 90 19 17 -4 31 2 54 26 31 31
|
16
|
+
32 32 26 105 -4 53 -15 98 -40 157 -23 53 -38 108 -42 153 -14 138 -59 239
|
17
|
+
-140 314 -113 105 -298 138 -447 81 l-50 -19 -50 34 c-27 19 -67 40 -89 46
|
18
|
+
-30 9 -39 17 -39 34 0 34 -36 65 -75 65 -22 0 -41 -8 -55 -22z m90 -43 c0 -10
|
19
|
+
-11 -15 -35 -15 -38 0 -48 22 -18 39 21 11 53 -3 53 -24z m104 -89 c30 -15 67
|
20
|
+
-41 82 -59 33 -39 71 -121 76 -162 l3 -30 -300 0 -300 0 3 30 c5 49 64 156
|
21
|
+
104 188 89 72 225 85 332 33z m408 -27 c153 -33 256 -138 292 -301 8 -35 18
|
22
|
+
-110 21 -168 11 -166 -15 -268 -89 -350 -28 -31 -33 -47 -44 -130 -7 -52 -15
|
23
|
+
-96 -18 -99 -10 -10 -113 -6 -124 5 -6 6 -14 30 -17 53 -5 37 -3 41 21 51 49
|
24
|
+
18 19 26 -96 24 l-113 -3 -11 -53 c-6 -30 -14 -59 -18 -66 -10 -17 -71 -25
|
25
|
+
-113 -15 -34 8 -39 13 -50 53 -6 25 -12 68 -12 96 -1 37 -7 59 -27 85 -38 51
|
26
|
+
-54 84 -63 136 -8 39 -6 49 7 59 14 10 9 15 -36 38 -28 14 -67 40 -86 57 -41
|
27
|
+
35 -96 140 -96 181 l0 28 69 0 69 0 37 -50 c34 -47 53 -59 68 -44 3 4 0 16 -8
|
28
|
+
28 -8 12 -12 31 -9 43 6 21 12 23 137 25 106 2 132 6 140 19 14 22 1 66 -21
|
29
|
+
71 -13 4 -21 18 -24 45 -5 32 -30 98 -55 144 -5 8 40 26 92 38 57 13 116 13
|
30
|
+
177 0z m-202 -274 c0 -13 -45 -15 -344 -15 -313 0 -369 4 -349 24 3 3 161 6
|
31
|
+
350 6 298 0 343 -2 343 -15z m580 -340 c26 -91 12 -165 -29 -165 -32 0 -40 19
|
32
|
+
-25 57 8 19 18 63 21 98 3 36 9 62 13 60 4 -2 13 -25 20 -50z"/>
|
33
|
+
<path d="M1107 953 c-11 -11 -8 -58 5 -71 34 -34 82 13 59 57 -11 20 -50 29
|
34
|
+
-64 14z"/>
|
35
|
+
<path d="M865 934 c-8 -9 -15 -24 -15 -34 0 -19 25 -50 40 -50 12 0 40 29 40
|
36
|
+
41 0 18 -19 46 -34 52 -9 4 -22 -1 -31 -9z"/>
|
37
|
+
<path d="M952 844 c4 -24 52 -48 81 -40 12 3 31 12 42 20 16 11 17 17 8 27
|
38
|
+
-10 10 -15 9 -27 -1 -16 -12 -54 -10 -90 5 -14 6 -17 4 -14 -11z"/>
|
39
|
+
</g>
|
40
|
+
</svg>
|
Binary file
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<?xml version="1.0" standalone="no"?>
|
2
|
+
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
3
|
+
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
4
|
+
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
5
|
+
width="152.000000pt" height="152.000000pt" viewBox="0 0 152.000000 152.000000"
|
6
|
+
preserveAspectRatio="xMidYMid meet">
|
7
|
+
|
8
|
+
<g transform="translate(0.000000,152.000000) scale(0.100000,-0.100000)"
|
9
|
+
fill="#000000" stroke="none">
|
10
|
+
<path d="M390 1358 c-11 -12 -20 -31 -20 -43 0 -15 -12 -24 -49 -38 -100 -35
|
11
|
+
-194 -150 -208 -253 -5 -36 -11 -48 -29 -55 -18 -6 -24 -16 -24 -37 0 -45 15
|
12
|
+
-52 121 -52 l96 0 7 -42 c15 -94 78 -185 163 -235 34 -20 43 -31 43 -52 0 -45
|
13
|
+
28 -125 59 -168 23 -31 31 -58 40 -128 7 -49 17 -97 22 -107 14 -27 51 -38
|
14
|
+
120 -38 75 0 104 24 114 94 l7 46 58 0 58 0 13 -57 c17 -69 37 -83 121 -83 81
|
15
|
+
0 91 13 106 129 9 77 16 98 39 126 28 34 31 35 90 19 17 -4 31 2 54 26 31 31
|
16
|
+
32 32 26 105 -4 53 -15 98 -40 157 -23 53 -38 108 -42 153 -14 138 -59 239
|
17
|
+
-140 314 -113 105 -298 138 -447 81 l-50 -19 -50 34 c-27 19 -67 40 -89 46
|
18
|
+
-30 9 -39 17 -39 34 0 34 -36 65 -75 65 -22 0 -41 -8 -55 -22z m90 -43 c0 -10
|
19
|
+
-11 -15 -35 -15 -38 0 -48 22 -18 39 21 11 53 -3 53 -24z m104 -89 c30 -15 67
|
20
|
+
-41 82 -59 33 -39 71 -121 76 -162 l3 -30 -300 0 -300 0 3 30 c5 49 64 156
|
21
|
+
104 188 89 72 225 85 332 33z m408 -27 c153 -33 256 -138 292 -301 8 -35 18
|
22
|
+
-110 21 -168 11 -166 -15 -268 -89 -350 -28 -31 -33 -47 -44 -130 -7 -52 -15
|
23
|
+
-96 -18 -99 -10 -10 -113 -6 -124 5 -6 6 -14 30 -17 53 -5 37 -3 41 21 51 49
|
24
|
+
18 19 26 -96 24 l-113 -3 -11 -53 c-6 -30 -14 -59 -18 -66 -10 -17 -71 -25
|
25
|
+
-113 -15 -34 8 -39 13 -50 53 -6 25 -12 68 -12 96 -1 37 -7 59 -27 85 -38 51
|
26
|
+
-54 84 -63 136 -8 39 -6 49 7 59 14 10 9 15 -36 38 -28 14 -67 40 -86 57 -41
|
27
|
+
35 -96 140 -96 181 l0 28 69 0 69 0 37 -50 c34 -47 53 -59 68 -44 3 4 0 16 -8
|
28
|
+
28 -8 12 -12 31 -9 43 6 21 12 23 137 25 106 2 132 6 140 19 14 22 1 66 -21
|
29
|
+
71 -13 4 -21 18 -24 45 -5 32 -30 98 -55 144 -5 8 40 26 92 38 57 13 116 13
|
30
|
+
177 0z m-202 -274 c0 -13 -45 -15 -344 -15 -313 0 -369 4 -349 24 3 3 161 6
|
31
|
+
350 6 298 0 343 -2 343 -15z m580 -340 c26 -91 12 -165 -29 -165 -32 0 -40 19
|
32
|
+
-25 57 8 19 18 63 21 98 3 36 9 62 13 60 4 -2 13 -25 20 -50z"/>
|
33
|
+
<path d="M1107 953 c-11 -11 -8 -58 5 -71 34 -34 82 13 59 57 -11 20 -50 29
|
34
|
+
-64 14z"/>
|
35
|
+
<path d="M865 934 c-8 -9 -15 -24 -15 -34 0 -19 25 -50 40 -50 12 0 40 29 40
|
36
|
+
41 0 18 -19 46 -34 52 -9 4 -22 -1 -31 -9z"/>
|
37
|
+
<path d="M952 844 c4 -24 52 -48 81 -40 12 3 31 12 42 20 16 11 17 17 8 27
|
38
|
+
-10 10 -15 9 -27 -1 -16 -12 -54 -10 -90 5 -14 6 -17 4 -14 -11z"/>
|
39
|
+
</g>
|
40
|
+
</svg>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"name": "Itsi",
|
3
|
+
"short_name": "Itsi",
|
4
|
+
"start_url": "index.html",
|
5
|
+
"icons": [
|
6
|
+
{
|
7
|
+
"src": "android-chrome-192x192.png",
|
8
|
+
"sizes": "192x192",
|
9
|
+
"type": "image/png"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"src": "android-chrome-310x310.png",
|
13
|
+
"sizes": "310x310",
|
14
|
+
"type": "image/png"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"theme_color": "#000000",
|
18
|
+
"background_color": "#000000",
|
19
|
+
"display": "standalone"
|
20
|
+
}
|
data/gems/scheduler/Cargo.lock
CHANGED
data/gems/server/Cargo.lock
CHANGED
@@ -25,56 +25,73 @@ module Itsi
|
|
25
25
|
hm.default_proc = proc { |_, key| "HTTP_#{key.upcase.gsub(/-/, "_")}" }
|
26
26
|
end
|
27
27
|
|
28
|
+
RACK_ENV_TEMPLATE = {
|
29
|
+
"SERVER_SOFTWARE" => "Itsi",
|
30
|
+
"rack.errors" => $stderr,
|
31
|
+
"rack.multithread" => true,
|
32
|
+
"rack.multiprocess" => true,
|
33
|
+
"rack.run_once" => false,
|
34
|
+
"rack.hijack?" => true,
|
35
|
+
"rack.multipart.buffer_size" => 16_384,
|
36
|
+
"SCRIPT_NAME" => "",
|
37
|
+
"REQUEST_METHOD" => "",
|
38
|
+
"PATH_INFO" => "",
|
39
|
+
"REQUEST_PATH" => "",
|
40
|
+
"QUERY_STRING" => "",
|
41
|
+
"REMOTE_ADDR" => "",
|
42
|
+
"SERVER_PORT" => "",
|
43
|
+
"SERVER_NAME" => "",
|
44
|
+
"SERVER_PROTOCOL" => "",
|
45
|
+
"HTTP_HOST" => "",
|
46
|
+
"HTTP_VERSION" => "",
|
47
|
+
"itsi.request" => "",
|
48
|
+
"itsi.response" => "",
|
49
|
+
"rack.version" => [nil],
|
50
|
+
"rack.url_scheme" => "",
|
51
|
+
"rack.input" => "",
|
52
|
+
"rack.hijack" => "",
|
53
|
+
"CONTENT_TYPE" => nil,
|
54
|
+
"CONTENT_LENGTH" => nil
|
55
|
+
}.freeze
|
56
|
+
|
28
57
|
def to_rack_env
|
29
58
|
path = self.path
|
30
59
|
host = self.host
|
31
60
|
version = self.version
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
when "accept-encoding" then "HTTP_ACCEPT_ENCODING"
|
65
|
-
when "accept-language" then "HTTP_ACCEPT_LANGUAGE"
|
66
|
-
when "user-agent" then "HTTP_USER_AGENT"
|
67
|
-
when "referer" then "HTTP_REFERER"
|
68
|
-
when "origin" then "HTTP_ORIGIN"
|
69
|
-
when "cookie" then "HTTP_COOKIE"
|
70
|
-
when "authorization" then "HTTP_AUTHORIZATION"
|
71
|
-
when "x-forwarded-for" then "HTTP_X_FORWARDED_FOR"
|
72
|
-
when "x-forwarded-proto" then "HTTP_X_FORWARDED_PROTO"
|
73
|
-
else RACK_HEADER_MAP[k]
|
74
|
-
end
|
75
|
-
] = v
|
76
|
-
end
|
61
|
+
env = RACK_ENV_TEMPLATE.dup
|
62
|
+
env["SCRIPT_NAME"] = script_name
|
63
|
+
env["REQUEST_METHOD"] = request_method
|
64
|
+
env["REQUEST_PATH"] = env["PATH_INFO"] = path
|
65
|
+
env["QUERY_STRING"] = query_string
|
66
|
+
env["REMOTE_ADDR"] = remote_addr
|
67
|
+
env["SERVER_PORT"] = port.to_s
|
68
|
+
env["HTTP_HOST"] = env["SERVER_NAME"] = host
|
69
|
+
env["HTTP_VERSION"] = env["SERVER_PROTOCOL"] = version
|
70
|
+
env["itsi.request"] = self
|
71
|
+
env["itsi.response"] = response
|
72
|
+
env["rack.version"][0] = version
|
73
|
+
env["rack.url_scheme"] = scheme
|
74
|
+
env["rack.input"] = build_input_io
|
75
|
+
env["rack.hijack"] = method(:hijack)
|
76
|
+
headers.each do |(k, v)|
|
77
|
+
env[case k
|
78
|
+
when "content-type" then "CONTENT_TYPE"
|
79
|
+
when "content-length" then "CONTENT_LENGTH"
|
80
|
+
when "accept" then "HTTP_ACCEPT"
|
81
|
+
when "accept-encoding" then "HTTP_ACCEPT_ENCODING"
|
82
|
+
when "accept-language" then "HTTP_ACCEPT_LANGUAGE"
|
83
|
+
when "user-agent" then "HTTP_USER_AGENT"
|
84
|
+
when "referer" then "HTTP_REFERER"
|
85
|
+
when "origin" then "HTTP_ORIGIN"
|
86
|
+
when "cookie" then "HTTP_COOKIE"
|
87
|
+
when "authorization" then "HTTP_AUTHORIZATION"
|
88
|
+
when "x-forwarded-for" then "HTTP_X_FORWARDED_FOR"
|
89
|
+
when "x-forwarded-proto" then "HTTP_X_FORWARDED_PROTO"
|
90
|
+
else RACK_HEADER_MAP[k]
|
91
|
+
end
|
92
|
+
] = v
|
77
93
|
end
|
94
|
+
env
|
78
95
|
end
|
79
96
|
|
80
97
|
def respond(
|
@@ -33,12 +33,12 @@ module Itsi
|
|
33
33
|
@params[:key_id_source] = nil
|
34
34
|
end
|
35
35
|
|
36
|
-
if File.exist?(".itsi-credentials") && !@params[:
|
37
|
-
@params[:
|
36
|
+
if File.exist?(".itsi-credentials") && !@params[:credentials_file]
|
37
|
+
@params[:credentials_file] = ".itsi-credentials"
|
38
38
|
end
|
39
39
|
|
40
|
-
if @params[:
|
41
|
-
@params[:valid_keys] = Passfile.load(@params[:
|
40
|
+
if @params[:credentials_file] && File.exist?(@params[:credentials_file])
|
41
|
+
@params[:valid_keys] = Passfile.load(@params[:credentials_file])
|
42
42
|
end
|
43
43
|
|
44
44
|
unless @params[:valid_keys]&.any?
|
@@ -21,16 +21,18 @@ module Itsi
|
|
21
21
|
|
22
22
|
def initialize(location, params={})
|
23
23
|
super
|
24
|
+
|
24
25
|
unless @params[:credential_pairs]&.any?
|
25
|
-
if File.exist?(".itsi-credentials") && !@params[:
|
26
|
-
@params[:
|
26
|
+
if File.exist?(".itsi-credentials") && !@params[:credentials_file]
|
27
|
+
@params[:credentials_file] = ".itsi-credentials"
|
27
28
|
end
|
28
29
|
|
29
|
-
if @params[:
|
30
|
-
@params[:credential_pairs] = Passfile.load(@params[:
|
30
|
+
if @params[:credentials_file] && File.exist?(@params[:credentials_file])
|
31
|
+
@params[:credential_pairs] = Passfile.load(@params[:credentials_file])
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
35
|
+
raise "No credentials provided" unless @params[:credential_pairs]
|
34
36
|
@params[:credential_pairs].compact!
|
35
37
|
|
36
38
|
unless @params[:credential_pairs]&.any?
|
@@ -13,7 +13,6 @@ Under the covers it:
|
|
13
13
|
3. Automatically enables `gRPC` reflection (so client like `evans`, `grpcurl` or `Postman` can discover your service endpoints without needing access to raw `.proto` files).
|
14
14
|
4. Supports optional per‑call compression (`none`, `deflate`, `gzip`) and a non‑blocking execution mode.
|
15
15
|
|
16
|
-
---
|
17
16
|
|
18
17
|
## Usage
|
19
18
|
|
@@ -97,8 +96,7 @@ require_relative 'echo_service_impl'
|
|
97
96
|
|
98
97
|
bind "https://localhost:3000"
|
99
98
|
grpc EchoServiceImpl.new,
|
100
|
-
nonblocking: false
|
101
|
-
compression: 'gzip' do
|
99
|
+
nonblocking: false do
|
102
100
|
# Nested middleware still works:
|
103
101
|
response_headers additions: { 'X-Service' => ['Echo'] }
|
104
102
|
end
|
@@ -48,7 +48,7 @@ end
|
|
48
48
|
```ruby {filename="Itsi.rb"}
|
49
49
|
# Match on non-route options.
|
50
50
|
# Redirect http requests to https requests
|
51
|
-
location
|
51
|
+
location schemes: ["http"]
|
52
52
|
redirect type: :permanent, to: "https://{host}{path_and_query}"
|
53
53
|
end
|
54
54
|
```
|
@@ -101,7 +101,7 @@ Pass these to the location block using keyword arguments, e.g.
|
|
101
101
|
|
102
102
|
```ruby
|
103
103
|
# Redirect all http JSON requests to use https exclusively.
|
104
|
-
location
|
104
|
+
location schemes: ["http"], content_types: ["application/json"]
|
105
105
|
redirect type: :permanent, to: "https://{host}{path_and_query}"
|
106
106
|
end
|
107
107
|
```
|
@@ -21,7 +21,7 @@ log_requests \
|
|
21
21
|
```
|
22
22
|
|
23
23
|
|
24
|
-
The log statement can populated with several different placeholders.
|
24
|
+
The log statement can populated with several different placeholders, using [String Rewrite](/middleware/string_rewrite) functionality.
|
25
25
|
Available values are:
|
26
26
|
|
27
27
|
### `before` Format String
|
@@ -46,6 +46,8 @@ Available values are:
|
|
46
46
|
* `response_time` - The response time in milliseconds
|
47
47
|
* `<Header-Name>`: Any existing response header. For example `{Content-Type}` or `{Set-Cookie}` will be replaced with its current value.
|
48
48
|
|
49
|
+
See [String Rewrite](/middleware/string_rewrite) for more advanced string manipulation options.
|
50
|
+
|
49
51
|
|
50
52
|
### Path Attributes
|
51
53
|
In addition to this, any capture groups referenced by container location blocks
|
@@ -9,13 +9,13 @@ The Reverse Proxy middleware enables reverse proxying by forwarding incoming HTT
|
|
9
9
|
|
10
10
|
```ruby
|
11
11
|
proxy \
|
12
|
-
to: "http://backend.example.com/api{path}{query}",
|
13
|
-
backends: ["127.0.0.1:3001", "127.0.0.1:3002"],
|
14
|
-
backend_priority: "round_robin",
|
15
|
-
headers: { "X-Forwarded-For" => { rewrite: "{addr}" } },
|
16
|
-
verify_ssl: false,
|
17
|
-
timeout: 30,
|
18
|
-
tls_sni: true,
|
12
|
+
to: "http://backend.example.com/api{path}{query}",
|
13
|
+
backends: ["127.0.0.1:3001", "127.0.0.1:3002"],
|
14
|
+
backend_priority: "round_robin",
|
15
|
+
headers: { "X-Forwarded-For" => { rewrite: "{addr}" } },
|
16
|
+
verify_ssl: false,
|
17
|
+
timeout: 30,
|
18
|
+
tls_sni: true,
|
19
19
|
error_response: "bad_gateway"
|
20
20
|
```
|
21
21
|
## Options
|
@@ -63,9 +63,9 @@ module Itsi
|
|
63
63
|
root_dir = @params[:root_dir] || "."
|
64
64
|
|
65
65
|
if !File.exist?(root_dir)
|
66
|
-
|
66
|
+
raise "Warning: static_assets root_dir '#{root_dir}' does not exist!"
|
67
67
|
elsif !File.directory?(root_dir)
|
68
|
-
|
68
|
+
raise "Warning: static_assets root_dir '#{root_dir}' is not a directory!"
|
69
69
|
end
|
70
70
|
|
71
71
|
@params[:relative_path] = true unless @params.key?(:relative_path)
|
@@ -18,20 +18,24 @@ For the best development experience, be sure to use [RubyLSP](https://shopify.gi
|
|
18
18
|
|
19
19
|
```ruby {filename="Itsi.rb"}
|
20
20
|
workers 2
|
21
|
+
|
21
22
|
threads 2
|
22
|
-
scheduler_threads 3
|
23
23
|
|
24
24
|
fiber_scheduler true
|
25
25
|
|
26
|
-
|
26
|
+
auth_basic realm: "Restricted Area", credentials_file: "./credentials.txt"
|
27
|
+
|
28
|
+
auto_reload_config! # Auto-reload the server configuration each time it changes.
|
27
29
|
|
28
|
-
|
30
|
+
location "/app*" do
|
31
|
+
rate_limit requests: 3, seconds: 5
|
32
|
+
rackup_file "config.ru"
|
33
|
+
end
|
29
34
|
|
30
|
-
location "/
|
35
|
+
location "/inline*" do
|
31
36
|
get "/" do |req|
|
32
37
|
req.ok "Hello, World!"
|
33
38
|
end
|
34
39
|
end
|
35
|
-
|
36
40
|
```
|
37
41
|
{{< /details >}}
|
@@ -6,6 +6,8 @@ url: /options/reuse_address
|
|
6
6
|
Configures whether the server should bind to the underlying socket using the `SO_REUSEADDR` option.
|
7
7
|
This option determines whether the server allows the reuse of local addresses during binding. This can be useful in scenarios where a socket needs to be quickly rebound without waiting for the operating system to release the address.
|
8
8
|
|
9
|
+
The default value is `false`.
|
10
|
+
|
9
11
|
## Configuration
|
10
12
|
```ruby {filename=Itsi.rb}
|
11
13
|
reuse_address true
|
@@ -6,6 +6,8 @@ url: /options/reuse_port
|
|
6
6
|
Configures whether the server should bind to the underlying socket using the `SO_REUSEPORT` option.
|
7
7
|
This option determines whether multiple sockets can listen on the same IP and port combination, which can improve load balancing and fault tolerance in multi-threaded or multi-process server applications.
|
8
8
|
|
9
|
+
The default value is `false`.
|
10
|
+
|
9
11
|
## Configuration
|
10
12
|
```ruby {filename=Itsi.rb}
|
11
13
|
reuse_port true
|
@@ -2,7 +2,6 @@ syntax = "proto3";
|
|
2
2
|
|
3
3
|
package test;
|
4
4
|
|
5
|
-
// A service with one of each RPC type [oai_citation_attribution:0‡Википедия — свободная энциклопедия](https://ru.wikipedia.org/wiki/GRPC?utm_source=chatgpt.com)
|
6
5
|
service TestService {
|
7
6
|
// Unary RPC
|
8
7
|
rpc UnaryEcho (EchoRequest) returns (EchoResponse) {}
|
@@ -1,25 +1,21 @@
|
|
1
1
|
require_relative 'test_service_services_pb' # generated by grpc_tools_ruby_protoc
|
2
2
|
|
3
3
|
class TestServiceImpl < Test::TestService::Service
|
4
|
-
# Unary: echo back the message [oai_citation_attribution:2‡Gustavo Caso](https://gustavocaso.dev/posts/grpc-tutorial-with-ruby/)
|
5
4
|
def unary_echo(req, _unused_call)
|
6
5
|
Test::EchoResponse.new(message: req.message)
|
7
6
|
end
|
8
7
|
|
9
|
-
# Client‑streaming: collect all incoming messages into one response [oai_citation_attribution:3‡Medium](https://alessiobussolari.medium.com/integrating-grpc-with-ruby-on-rails-2b2a203107d5?utm_source=chatgpt.com)
|
10
8
|
def client_stream(stream, _call)
|
11
9
|
msgs = stream.map(&:message)
|
12
10
|
Test::StreamResponse.new(messages: msgs)
|
13
11
|
end
|
14
12
|
|
15
|
-
# Server‑streaming: send back one StreamResponse per incoming request, with each char [oai_citation_attribution:4‡Medium](https://alessiobussolari.medium.com/integrating-grpc-with-ruby-on-rails-2b2a203107d5?utm_source=chatgpt.com)
|
16
13
|
def server_stream(req, _call)
|
17
14
|
Enumerator.new do |y|
|
18
15
|
req.message.each_char { |c| y << Test::StreamResponse.new(messages: [c]) }
|
19
16
|
end
|
20
17
|
end
|
21
18
|
|
22
|
-
# Bidirectional: for each incoming EchoRequest, immediately echo it back [oai_citation_attribution:5‡Medium](https://alessiobussolari.medium.com/integrating-grpc-with-ruby-on-rails-2b2a203107d5?utm_source=chatgpt.com)
|
23
19
|
def bidi_stream(stream, _call)
|
24
20
|
Enumerator.new do |y|
|
25
21
|
stream.each { |req| y << Test::EchoResponse.new(message: req.message.upcase) }
|
@@ -6,7 +6,7 @@ require_relative 'test_service_pb'
|
|
6
6
|
|
7
7
|
module Test
|
8
8
|
module TestService
|
9
|
-
|
9
|
+
|
10
10
|
class Service
|
11
11
|
|
12
12
|
include ::GRPC::GenericService
|
data/lib/itsi/version.rb
CHANGED
data/tasks.txt
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
0.2.6:
|
2
|
+
- Opt in to gRPC compression override, per endpoint or per service
|
3
|
+
|
2
4
|
- Static ruby build
|
3
|
-
- Add
|
5
|
+
- Add hook to opt non Itsi.rb files into LSP
|
4
6
|
- OTel
|
5
7
|
- Even faster Hash creation for Rack
|
6
8
|
- Image resizer
|
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.6
|
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.6
|
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.6
|
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.6
|
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.6
|
40
40
|
description: Wrapper Gem for both the Itsi server and the Itsi Fiber scheduler
|
41
41
|
email:
|
42
42
|
- wc@pico.net.nz
|
@@ -217,6 +217,30 @@ files:
|
|
217
217
|
- docs/go.mod
|
218
218
|
- docs/go.sum
|
219
219
|
- docs/hugo.yaml
|
220
|
+
- docs/static/android-chrome-192x192.png
|
221
|
+
- docs/static/android-chrome-310x310.png
|
222
|
+
- docs/static/apple-touch-icon.png
|
223
|
+
- docs/static/browserconfig.xml
|
224
|
+
- docs/static/favicon-114x114.png
|
225
|
+
- docs/static/favicon-120x120.png
|
226
|
+
- docs/static/favicon-144x144.png
|
227
|
+
- docs/static/favicon-150x150.png
|
228
|
+
- docs/static/favicon-152x152.png
|
229
|
+
- docs/static/favicon-16x16.png
|
230
|
+
- docs/static/favicon-180x180.png
|
231
|
+
- docs/static/favicon-192x192.png
|
232
|
+
- docs/static/favicon-310x310.png
|
233
|
+
- docs/static/favicon-32x32.png
|
234
|
+
- docs/static/favicon-57x57.png
|
235
|
+
- docs/static/favicon-60x60.png
|
236
|
+
- docs/static/favicon-70x70.png
|
237
|
+
- docs/static/favicon-72x72.png
|
238
|
+
- docs/static/favicon-76x76.png
|
239
|
+
- docs/static/favicon-96x96.png
|
240
|
+
- docs/static/favicon-dark.svg
|
241
|
+
- docs/static/favicon.ico
|
242
|
+
- docs/static/favicon.svg
|
243
|
+
- docs/static/site.webmanifest
|
220
244
|
- examples/api_with_schema_and_controllers/Itsi.rb
|
221
245
|
- examples/api_with_schema_and_controllers/README.md
|
222
246
|
- examples/api_with_schema_and_controllers/controllers.rb
|