itsi-server 0.2.2 → 0.2.4

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +28 -29
  3. data/ext/itsi_scheduler/Cargo.toml +1 -1
  4. data/ext/itsi_server/Cargo.toml +1 -1
  5. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +26 -3
  6. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +28 -11
  7. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +1 -1
  8. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +1 -2
  9. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +14 -2
  10. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +86 -41
  11. data/ext/itsi_server/src/services/itsi_http_service.rs +46 -35
  12. data/ext/itsi_server/src/services/static_file_server.rs +31 -3
  13. data/lib/itsi/http_request.rb +31 -34
  14. data/lib/itsi/http_response.rb +10 -8
  15. data/lib/itsi/passfile.rb +6 -6
  16. data/lib/itsi/server/config/config_helpers.rb +33 -33
  17. data/lib/itsi/server/config/dsl.rb +16 -21
  18. data/lib/itsi/server/config/known_paths.rb +11 -7
  19. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +0 -4
  20. data/lib/itsi/server/config/middleware/error_response.md +13 -0
  21. data/lib/itsi/server/config/middleware/location.rb +25 -21
  22. data/lib/itsi/server/config/middleware/proxy.rb +15 -14
  23. data/lib/itsi/server/config/middleware/rackup_file.rb +7 -10
  24. data/lib/itsi/server/config/middleware/static_assets.md +40 -0
  25. data/lib/itsi/server/config/middleware/static_assets.rb +8 -4
  26. data/lib/itsi/server/config/middleware/string_rewrite.md +14 -0
  27. data/lib/itsi/server/config/option.rb +0 -1
  28. data/lib/itsi/server/config/options/include.rb +1 -1
  29. data/lib/itsi/server/config/options/nodelay.md +2 -2
  30. data/lib/itsi/server/config/options/reuse_address.md +1 -1
  31. data/lib/itsi/server/config/typed_struct.rb +32 -35
  32. data/lib/itsi/server/config.rb +107 -92
  33. data/lib/itsi/server/default_app/default_app.rb +1 -1
  34. data/lib/itsi/server/grpc/grpc_call.rb +4 -5
  35. data/lib/itsi/server/grpc/grpc_interface.rb +6 -7
  36. data/lib/itsi/server/rack/handler/itsi.rb +0 -1
  37. data/lib/itsi/server/rack_interface.rb +1 -2
  38. data/lib/itsi/server/route_tester.rb +26 -24
  39. data/lib/itsi/server/typed_handlers/param_parser.rb +25 -0
  40. data/lib/itsi/server/typed_handlers/source_parser.rb +9 -7
  41. data/lib/itsi/server/version.rb +1 -1
  42. data/lib/itsi/server.rb +22 -22
  43. data/lib/itsi/standard_headers.rb +80 -80
  44. metadata +3 -3
data/lib/itsi/server.rb CHANGED
@@ -27,7 +27,6 @@ module Itsi
27
27
  extend RouteTester
28
28
 
29
29
  class << self
30
-
31
30
  def running?
32
31
  @running && !@running.empty?
33
32
  end
@@ -62,9 +61,8 @@ module Itsi
62
61
  server
63
62
  end
64
63
  background ? [server, Thread.new(&run)] : run[]
65
- rescue Exception => e
64
+ rescue Exception => e # rubocop:disable Lint/RescueException
66
65
  Itsi.log_error e.message
67
- raise e
68
66
  end
69
67
 
70
68
  def static(cli_params)
@@ -72,7 +70,8 @@ module Itsi
72
70
  end
73
71
 
74
72
  def stop
75
- return unless pid = get_pid
73
+ return unless (pid = get_pid)
74
+
76
75
  Process.kill(:INT, pid)
77
76
  i = 0
78
77
  while i < 10
@@ -96,7 +95,7 @@ module Itsi
96
95
  File.write(Itsi::Server::Config.pid_file_path, Process.pid)
97
96
  end
98
97
 
99
- def get_pid(warn=true)
98
+ def get_pid(warn = true)
100
99
  pid = File.read(Itsi::Server::Config.pid_file_path).to_i
101
100
  if Process.kill(0, pid)
102
101
  pid
@@ -110,7 +109,7 @@ module Itsi
110
109
  end
111
110
 
112
111
  def test
113
- Itsi::Server::Config.test!(cli_params = {})
112
+ Itsi::Server::Config.test!({})
114
113
  end
115
114
 
116
115
  def init
@@ -118,25 +117,25 @@ module Itsi
118
117
  end
119
118
 
120
119
  def reload
121
- return unless pid = get_pid
120
+ return unless (pid = get_pid)
122
121
 
123
122
  Process.kill(:HUP, pid)
124
123
  end
125
124
 
126
125
  def restart
127
- return unless pid = get_pid
126
+ return unless (pid = get_pid)
128
127
 
129
128
  Process.kill(:USR1, pid)
130
129
  end
131
130
 
132
131
  def passfile(options, subcmd)
133
132
  filename = options[:passfile]
134
- unless filename || subcmd == 'echo'
133
+ unless filename || subcmd == "echo"
135
134
  puts "Error: passfile not set. Use --passfile option to provide a path to a file containing hashed credentials."
136
135
  puts "This file contains hashed credentials and should not be included in source control without additional protection."
137
136
  exit(1)
138
137
  end
139
- algorithm = options.fetch(:algorithm, 'sha256')
138
+ algorithm = options.fetch(:algorithm, "sha256")
140
139
 
141
140
  unless %w[sha256 sha512 bcrypt argon2 none].include?(algorithm)
142
141
  puts "Invalid algorithm"
@@ -144,9 +143,9 @@ module Itsi
144
143
  end
145
144
 
146
145
  case subcmd
147
- when 'add', 'echo'
146
+ when "add", "echo"
148
147
  Passfile.send(subcmd, filename, algorithm)
149
- when 'remove', 'list'
148
+ when "remove", "list"
150
149
  Passfile.send(subcmd, filename)
151
150
  else
152
151
  puts "Valid subcommands are: add | remove | list"
@@ -165,6 +164,7 @@ module Itsi
165
164
  new_name = "#{base}_#{i}#{ext}"
166
165
  candidate = File.join(dir, new_name)
167
166
  return candidate unless File.exist?(candidate)
167
+
168
168
  i += 1
169
169
  end
170
170
  end
@@ -189,11 +189,11 @@ module Itsi
189
189
 
190
190
  case alg
191
191
  when /^HS(\d+)$/
192
- bits = $1.to_i
192
+ bits = ::Regexp.last_match(1).to_i
193
193
  bytes = bits / 8
194
194
  key = SecureRandom.random_bytes(bytes)
195
195
  pem = Base64.strict_encode64(key)
196
- content = "=== HMAC #{bits}-bit Secret (base64) ===\n#{pem}\n"
196
+ content = "=== HMAC #{bits}-bit Secret (base64) ===\n#{pem}\n"
197
197
  save_or_print("hmac_#{bits}_secret.txt", content, options)
198
198
 
199
199
  when /^RS/, /^PS/
@@ -215,32 +215,33 @@ module Itsi
215
215
  save_or_print("ecdsa_public.pem", "=== ECDSA Public Key ===\n#{pub}", options)
216
216
 
217
217
  else
218
- STDERR.puts "Unsupported algorithm: #{alg}"
218
+ warn "Unsupported algorithm: #{alg}"
219
219
  exit 1
220
220
  end
221
221
  end
222
222
 
223
-
224
223
  def add_worker
225
- return unless pid = get_pid
224
+ return unless (pid = get_pid)
226
225
 
227
226
  Process.kill(:TTIN, pid)
228
227
  end
229
228
 
230
229
  def remove_worker
231
- return unless pid = get_pid
230
+ return unless (pid = get_pid)
232
231
 
233
232
  Process.kill(:TTOU, pid)
234
233
  end
235
234
 
236
235
  def status
237
- return unless pid = get_pid
236
+ return unless (pid = get_pid)
237
+
238
238
  Itsi.log_info("Itsi running on #{pid}")
239
239
  Process.kill(:USR2, pid)
240
240
  end
241
241
 
242
242
  def load_route_middleware_stack(cli_params)
243
- middleware, errors = Config.build_config(cli_params, Itsi::Server::Config.config_file_path(cli_params[:config_file_path]))
243
+ middleware, errors = Config.build_config(cli_params,
244
+ Itsi::Server::Config.config_file_path(cli_params[:config_file_path]))
244
245
  if errors.any?
245
246
  puts errors
246
247
  []
@@ -261,7 +262,7 @@ module Itsi
261
262
  end
262
263
 
263
264
  def routes(cli_params = {})
264
- load_route_middleware_stack(cli_params).each do |stack|
265
+ load_route_middleware_stack(cli_params).first.each do |stack|
265
266
  routes = explode_route_pattern(stack["route"].source)
266
267
  routes.each do |route|
267
268
  print_route(route, stack)
@@ -271,7 +272,6 @@ module Itsi
271
272
  end
272
273
 
273
274
  alias serve start
274
-
275
275
  end
276
276
  end
277
277
  end
@@ -1,86 +1,86 @@
1
1
  module Itsi
2
2
  module StandardHeaders
3
3
  ALL = [
4
- ACCEPT = "accept",
5
- ACCEPT_CHARSET = "accept-charset",
6
- ACCEPT_ENCODING = "accept-encoding",
7
- ACCEPT_LANGUAGE = "accept-language",
8
- ACCEPT_RANGES = "accept-ranges",
9
- ACCESS_CONTROL_ALLOW_CREDENTIALS = "access-control-allow-credentials",
10
- ACCESS_CONTROL_ALLOW_HEADERS = "access-control-allow-headers",
11
- ACCESS_CONTROL_ALLOW_METHODS = "access-control-allow-methods",
12
- ACCESS_CONTROL_ALLOW_ORIGIN = "access-control-allow-origin",
13
- ACCESS_CONTROL_EXPOSE_HEADERS = "access-control-expose-headers",
14
- ACCESS_CONTROL_MAX_AGE = "access-control-max-age",
15
- ACCESS_CONTROL_REQUEST_HEADERS = "access-control-request-headers",
16
- ACCESS_CONTROL_REQUEST_METHOD = "access-control-request-method",
17
- AGE = "age",
18
- ALLOW = "allow",
19
- ALT_SVC = "alt-svc",
20
- AUTHORIZATION = "authorization",
21
- CACHE_CONTROL = "cache-control",
22
- CACHE_STATUS = "cache-status",
23
- CDN_CACHE_CONTROL = "cdn-cache-control",
24
- CONNECTION = "connection",
25
- CONTENT_DISPOSITION = "content-disposition",
26
- CONTENT_ENCODING = "content-encoding",
27
- CONTENT_LANGUAGE = "content-language",
28
- CONTENT_LENGTH = "content-length",
29
- CONTENT_LOCATION = "content-location",
30
- CONTENT_RANGE = "content-range",
31
- CONTENT_SECURITY_POLICY_REPORT_ONLY = "content-security-policy-report-only",
32
- CONTENT_TYPE = "content-type",
33
- COOKIE = "cookie",
34
- DNT = "dnt",
35
- DATE = "date",
36
- ETAG = "etag",
37
- EXPECT = "expect",
38
- EXPIRES = "expires",
39
- FORWARDED = "forwarded",
40
- FROM = "from",
41
- HOST = "host",
42
- IF_MATCH = "if-match",
43
- IF_MODIFIED_SINCE = "if-modified-since",
44
- IF_NONE_MATCH = "if-none-match",
45
- IF_RANGE = "if-range",
46
- IF_UNMODIFIED_SINCE = "if-unmodified-since",
47
- LAST_MODIFIED = "last-modified",
48
- LINK = "link",
49
- LOCATION = "location",
50
- MAX_FORWARDS = "max-forwards",
51
- ORIGIN = "origin",
52
- PRAGMA = "pragma",
53
- PROXY_AUTHENTICATE = "proxy-authenticate",
54
- PROXY_AUTHORIZATION = "proxy-authorization",
55
- PUBLIC_KEY_PINS = "public-key-pins",
56
- PUBLIC_KEY_PINS_REPORT_ONLY = "public-key-pins-report-only",
57
- RANGE = "range",
58
- REFERER = "referer",
59
- REFERRER_POLICY = "referrer-policy",
60
- REFRESH = "refresh",
61
- RETRY_AFTER = "retry-after",
62
- SEC_WEBSOCKET_ACCEPT = "sec-websocket-accept",
63
- SEC_WEBSOCKET_EXTENSIONS = "sec-websocket-extensions",
64
- SEC_WEBSOCKET_KEY = "sec-websocket-key",
65
- SEC_WEBSOCKET_PROTOCOL = "sec-websocket-protocol",
66
- SEC_WEBSOCKET_VERSION = "sec-websocket-version",
67
- SERVER = "server",
68
- SET_COOKIE = "set-cookie",
69
- STRICT_TRANSPORT_SECURITY = "strict-transport-security",
70
- TE = "te",
71
- TRAILER = "trailer",
72
- TRANSFER_ENCODING = "transfer-encoding",
73
- USER_AGENT = "user-agent",
74
- UPGRADE = "upgrade",
75
- UPGRADE_INSECURE_REQUESTS = "upgrade-insecure-requests",
76
- VARY = "vary",
77
- VIA = "via",
78
- WARNING = "warning",
79
- WWW_AUTHENTICATE = "www-authenticate",
80
- X_CONTENT_TYPE_OPTIONS = "x-content-type-options",
81
- X_DNS_PREFETCH_CONTROL = "x-dns-prefetch-control",
82
- X_FRAME_OPTIONS = "x-frame-options",
83
- X_XSS_PROTECTION = "x-xss-protection",
4
+ ACCEPT = "accept".freeze,
5
+ ACCEPT_CHARSET = "accept-charset".freeze,
6
+ ACCEPT_ENCODING = "accept-encoding".freeze,
7
+ ACCEPT_LANGUAGE = "accept-language".freeze,
8
+ ACCEPT_RANGES = "accept-ranges".freeze,
9
+ ACCESS_CONTROL_ALLOW_CREDENTIALS = "access-control-allow-credentials".freeze,
10
+ ACCESS_CONTROL_ALLOW_HEADERS = "access-control-allow-headers".freeze,
11
+ ACCESS_CONTROL_ALLOW_METHODS = "access-control-allow-methods".freeze,
12
+ ACCESS_CONTROL_ALLOW_ORIGIN = "access-control-allow-origin".freeze,
13
+ ACCESS_CONTROL_EXPOSE_HEADERS = "access-control-expose-headers".freeze,
14
+ ACCESS_CONTROL_MAX_AGE = "access-control-max-age".freeze,
15
+ ACCESS_CONTROL_REQUEST_HEADERS = "access-control-request-headers".freeze,
16
+ ACCESS_CONTROL_REQUEST_METHOD = "access-control-request-method".freeze,
17
+ AGE = "age".freeze,
18
+ ALLOW = "allow".freeze,
19
+ ALT_SVC = "alt-svc".freeze,
20
+ AUTHORIZATION = "authorization".freeze,
21
+ CACHE_CONTROL = "cache-control".freeze,
22
+ CACHE_STATUS = "cache-status".freeze,
23
+ CDN_CACHE_CONTROL = "cdn-cache-control".freeze,
24
+ CONNECTION = "connection".freeze,
25
+ CONTENT_DISPOSITION = "content-disposition".freeze,
26
+ CONTENT_ENCODING = "content-encoding".freeze,
27
+ CONTENT_LANGUAGE = "content-language".freeze,
28
+ CONTENT_LENGTH = "content-length".freeze,
29
+ CONTENT_LOCATION = "content-location".freeze,
30
+ CONTENT_RANGE = "content-range".freeze,
31
+ CONTENT_SECURITY_POLICY_REPORT_ONLY = "content-security-policy-report-only".freeze,
32
+ CONTENT_TYPE = "content-type".freeze,
33
+ COOKIE = "cookie".freeze,
34
+ DNT = "dnt".freeze,
35
+ DATE = "date".freeze,
36
+ ETAG = "etag".freeze,
37
+ EXPECT = "expect".freeze,
38
+ EXPIRES = "expires".freeze,
39
+ FORWARDED = "forwarded".freeze,
40
+ FROM = "from".freeze,
41
+ HOST = "host".freeze,
42
+ IF_MATCH = "if-match".freeze,
43
+ IF_MODIFIED_SINCE = "if-modified-since".freeze,
44
+ IF_NONE_MATCH = "if-none-match".freeze,
45
+ IF_RANGE = "if-range".freeze,
46
+ IF_UNMODIFIED_SINCE = "if-unmodified-since".freeze,
47
+ LAST_MODIFIED = "last-modified".freeze,
48
+ LINK = "link".freeze,
49
+ LOCATION = "location".freeze,
50
+ MAX_FORWARDS = "max-forwards".freeze,
51
+ ORIGIN = "origin".freeze,
52
+ PRAGMA = "pragma".freeze,
53
+ PROXY_AUTHENTICATE = "proxy-authenticate".freeze,
54
+ PROXY_AUTHORIZATION = "proxy-authorization".freeze,
55
+ PUBLIC_KEY_PINS = "public-key-pins".freeze,
56
+ PUBLIC_KEY_PINS_REPORT_ONLY = "public-key-pins-report-only".freeze,
57
+ RANGE = "range".freeze,
58
+ REFERER = "referer".freeze,
59
+ REFERRER_POLICY = "referrer-policy".freeze,
60
+ REFRESH = "refresh".freeze,
61
+ RETRY_AFTER = "retry-after".freeze,
62
+ SEC_WEBSOCKET_ACCEPT = "sec-websocket-accept".freeze,
63
+ SEC_WEBSOCKET_EXTENSIONS = "sec-websocket-extensions".freeze,
64
+ SEC_WEBSOCKET_KEY = "sec-websocket-key".freeze,
65
+ SEC_WEBSOCKET_PROTOCOL = "sec-websocket-protocol".freeze,
66
+ SEC_WEBSOCKET_VERSION = "sec-websocket-version".freeze,
67
+ SERVER = "server".freeze,
68
+ SET_COOKIE = "set-cookie".freeze,
69
+ STRICT_TRANSPORT_SECURITY = "strict-transport-security".freeze,
70
+ TE = "te".freeze,
71
+ TRAILER = "trailer".freeze,
72
+ TRANSFER_ENCODING = "transfer-encoding".freeze,
73
+ USER_AGENT = "user-agent".freeze,
74
+ UPGRADE = "upgrade".freeze,
75
+ UPGRADE_INSECURE_REQUESTS = "upgrade-insecure-requests".freeze,
76
+ VARY = "vary".freeze,
77
+ VIA = "via".freeze,
78
+ WARNING = "warning".freeze,
79
+ WWW_AUTHENTICATE = "www-authenticate".freeze,
80
+ X_CONTENT_TYPE_OPTIONS = "x-content-type-options".freeze,
81
+ X_DNS_PREFETCH_CONTROL = "x-dns-prefetch-control".freeze,
82
+ X_FRAME_OPTIONS = "x-frame-options".freeze,
83
+ X_XSS_PROTECTION = "x-xss-protection".freeze
84
84
  ]
85
85
  end
86
86
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itsi-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter Coppieters
@@ -525,8 +525,8 @@ licenses:
525
525
  - MIT
526
526
  metadata:
527
527
  homepage_uri: https://itsi.fyi
528
- source_code_uri: https://github.com/wouterken/itsi/server
529
- changelog_uri: https://github.com/wouterken/itsi/server/blob/main/CHANGELOG.md
528
+ source_code_uri: https://github.com/wouterken/itsi
529
+ changelog_uri: https://github.com/wouterken/itsi/blob/main/CHANGELOG.md
530
530
  rdoc_options: []
531
531
  require_paths:
532
532
  - lib