itsi-server 0.1.1 → 0.2.2

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 (457) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +4487 -0
  3. data/Cargo.toml +7 -0
  4. data/README.md +6 -0
  5. data/Rakefile +7 -4
  6. data/exe/itsi +152 -46
  7. data/ext/itsi_acme/Cargo.toml +86 -0
  8. data/ext/itsi_acme/examples/high_level.rs +63 -0
  9. data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
  10. data/ext/itsi_acme/examples/low_level.rs +87 -0
  11. data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
  12. data/ext/itsi_acme/src/acceptor.rs +81 -0
  13. data/ext/itsi_acme/src/acme.rs +354 -0
  14. data/ext/itsi_acme/src/axum.rs +86 -0
  15. data/ext/itsi_acme/src/cache.rs +39 -0
  16. data/ext/itsi_acme/src/caches/boxed.rs +80 -0
  17. data/ext/itsi_acme/src/caches/composite.rs +69 -0
  18. data/ext/itsi_acme/src/caches/dir.rs +106 -0
  19. data/ext/itsi_acme/src/caches/mod.rs +11 -0
  20. data/ext/itsi_acme/src/caches/no.rs +78 -0
  21. data/ext/itsi_acme/src/caches/test.rs +136 -0
  22. data/ext/itsi_acme/src/config.rs +172 -0
  23. data/ext/itsi_acme/src/https_helper.rs +69 -0
  24. data/ext/itsi_acme/src/incoming.rs +142 -0
  25. data/ext/itsi_acme/src/jose.rs +161 -0
  26. data/ext/itsi_acme/src/lib.rs +142 -0
  27. data/ext/itsi_acme/src/resolver.rs +59 -0
  28. data/ext/itsi_acme/src/state.rs +424 -0
  29. data/ext/itsi_error/Cargo.toml +3 -0
  30. data/ext/itsi_error/src/lib.rs +98 -24
  31. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  32. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  33. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  34. data/ext/itsi_error/target/debug/build/rb-sys-49f554618693db24/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  35. data/ext/itsi_error/target/debug/incremental/itsi_error-1mmt5sux7jb0i/s-h510z7m8v9-0bxu7yd.lock +0 -0
  36. data/ext/itsi_error/target/debug/incremental/itsi_error-2vn3jey74oiw0/s-h5113n0e7e-1v5qzs6.lock +0 -0
  37. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510ykifhe-0tbnep2.lock +0 -0
  38. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510yyocpj-0tz7ug7.lock +0 -0
  39. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510z0xc8g-14ol18k.lock +0 -0
  40. data/ext/itsi_error/target/debug/incremental/itsi_error-3g5qf4y7d54uj/s-h5113n0e7d-1trk8on.lock +0 -0
  41. data/ext/itsi_error/target/debug/incremental/itsi_error-3lpfftm45d3e2/s-h510z7m8r3-1pxp20o.lock +0 -0
  42. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510ykifek-1uxasnk.lock +0 -0
  43. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510yyocki-11u37qm.lock +0 -0
  44. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510z0xc93-0pmy0zm.lock +0 -0
  45. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  46. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  47. data/ext/itsi_rb_helpers/Cargo.toml +3 -0
  48. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  49. data/ext/itsi_rb_helpers/src/lib.rs +141 -10
  50. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  51. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  52. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  53. data/ext/itsi_rb_helpers/target/debug/build/rb-sys-eb9ed4ff3a60f995/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  54. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-040pxg6yhb3g3/s-h5113n7a1b-03bwlt4.lock +0 -0
  55. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h51113xnh3-1eik1ip.lock +0 -0
  56. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h5111704jj-0g4rj8x.lock +0 -0
  57. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-1q2d3drtxrzs5/s-h5113n79yl-0bxcqc5.lock +0 -0
  58. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h51113xoox-10de2hp.lock +0 -0
  59. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h5111704w7-0vdq7gq.lock +0 -0
  60. data/ext/itsi_scheduler/Cargo.toml +24 -0
  61. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  62. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  63. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  64. data/ext/itsi_scheduler/src/itsi_scheduler.rs +314 -0
  65. data/ext/itsi_scheduler/src/lib.rs +39 -0
  66. data/ext/itsi_server/Cargo.lock +2956 -0
  67. data/ext/itsi_server/Cargo.toml +75 -14
  68. data/ext/itsi_server/extconf.rb +1 -1
  69. data/ext/itsi_server/src/default_responses/html/401.html +68 -0
  70. data/ext/itsi_server/src/default_responses/html/403.html +68 -0
  71. data/ext/itsi_server/src/default_responses/html/404.html +68 -0
  72. data/ext/itsi_server/src/default_responses/html/413.html +71 -0
  73. data/ext/itsi_server/src/default_responses/html/429.html +68 -0
  74. data/ext/itsi_server/src/default_responses/html/500.html +71 -0
  75. data/ext/itsi_server/src/default_responses/html/502.html +71 -0
  76. data/ext/itsi_server/src/default_responses/html/503.html +68 -0
  77. data/ext/itsi_server/src/default_responses/html/504.html +69 -0
  78. data/ext/itsi_server/src/default_responses/html/index.html +238 -0
  79. data/ext/itsi_server/src/default_responses/json/401.json +6 -0
  80. data/ext/itsi_server/src/default_responses/json/403.json +6 -0
  81. data/ext/itsi_server/src/default_responses/json/404.json +6 -0
  82. data/ext/itsi_server/src/default_responses/json/413.json +6 -0
  83. data/ext/itsi_server/src/default_responses/json/429.json +6 -0
  84. data/ext/itsi_server/src/default_responses/json/500.json +6 -0
  85. data/ext/itsi_server/src/default_responses/json/502.json +6 -0
  86. data/ext/itsi_server/src/default_responses/json/503.json +6 -0
  87. data/ext/itsi_server/src/default_responses/json/504.json +6 -0
  88. data/ext/itsi_server/src/default_responses/mod.rs +11 -0
  89. data/ext/itsi_server/src/env.rs +43 -0
  90. data/ext/itsi_server/src/lib.rs +133 -40
  91. data/ext/itsi_server/src/prelude.rs +2 -0
  92. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +109 -0
  93. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +143 -0
  94. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +344 -0
  95. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +264 -0
  96. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +362 -0
  97. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +391 -0
  98. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +233 -0
  99. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +565 -0
  100. data/ext/itsi_server/src/ruby_types/itsi_server.rs +86 -0
  101. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  102. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  103. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  104. data/ext/itsi_server/src/server/binds/listener.rs +444 -0
  105. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  106. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  107. data/ext/itsi_server/src/server/binds/tls.rs +278 -0
  108. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  109. data/ext/itsi_server/src/server/http_message_types.rs +97 -0
  110. data/ext/itsi_server/src/server/io_stream.rs +105 -0
  111. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  112. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  113. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +94 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +316 -0
  119. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +301 -0
  120. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  121. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  122. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +192 -0
  123. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +171 -0
  124. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +198 -0
  125. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  126. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
  127. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
  128. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  129. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +116 -0
  130. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +411 -0
  131. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +142 -0
  132. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +55 -0
  133. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  134. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
  135. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +126 -0
  136. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +187 -0
  137. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +55 -0
  138. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +173 -0
  139. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  140. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  141. data/ext/itsi_server/src/server/mod.rs +13 -5
  142. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  143. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  144. data/ext/itsi_server/src/server/request_job.rs +11 -0
  145. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +354 -0
  146. data/ext/itsi_server/src/server/serve_strategy/mod.rs +30 -0
  147. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +481 -0
  148. data/ext/itsi_server/src/server/signal.rs +77 -0
  149. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  150. data/ext/itsi_server/src/server/thread_worker.rs +479 -0
  151. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  152. data/ext/itsi_server/src/services/itsi_http_service.rs +257 -0
  153. data/ext/itsi_server/src/services/mime_types.rs +1416 -0
  154. data/ext/itsi_server/src/services/mod.rs +6 -0
  155. data/ext/itsi_server/src/services/password_hasher.rs +83 -0
  156. data/ext/itsi_server/src/services/rate_limiter.rs +580 -0
  157. data/ext/itsi_server/src/services/static_file_server.rs +1340 -0
  158. data/ext/itsi_tracing/Cargo.toml +5 -0
  159. data/ext/itsi_tracing/src/lib.rs +366 -7
  160. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
  161. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
  162. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
  163. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
  164. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
  165. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
  166. data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
  167. data/lib/itsi/http_request.rb +218 -0
  168. data/lib/itsi/http_response.rb +42 -0
  169. data/lib/itsi/passfile.rb +108 -0
  170. data/lib/itsi/server/config/config_helpers.rb +105 -0
  171. data/lib/itsi/server/config/dsl.rb +211 -0
  172. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  173. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  174. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  175. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  176. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  177. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  178. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  179. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  180. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  181. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  182. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  183. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  184. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  185. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  186. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  187. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  188. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  189. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  190. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  191. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  192. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  193. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  194. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  212. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  213. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  214. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  215. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  216. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  217. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  218. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  219. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  220. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  221. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  222. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  223. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  224. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  225. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  226. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  227. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  228. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  229. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  230. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  231. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  232. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  233. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  234. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  235. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  236. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  237. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  238. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  239. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  240. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  241. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  242. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  254. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  255. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  256. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  257. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  258. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  259. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  260. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  261. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  262. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  263. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  264. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  265. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  266. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  267. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  268. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  269. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  270. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  271. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  272. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  273. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  274. data/lib/itsi/server/config/known_paths.rb +20 -0
  275. data/lib/itsi/server/config/middleware/_index.md +56 -0
  276. data/lib/itsi/server/config/middleware/allow_list.md +46 -0
  277. data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  278. data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  279. data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  280. data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  281. data/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
  282. data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  283. data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  284. data/lib/itsi/server/config/middleware/cache_control.md +78 -0
  285. data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  286. data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  287. data/lib/itsi/server/config/middleware/compression.md +50 -0
  288. data/lib/itsi/server/config/middleware/compression.rb +37 -0
  289. data/lib/itsi/server/config/middleware/cors.md +93 -0
  290. data/lib/itsi/server/config/middleware/cors.rb +32 -0
  291. data/lib/itsi/server/config/middleware/csp.md +37 -0
  292. data/lib/itsi/server/config/middleware/csp.rb +44 -0
  293. data/lib/itsi/server/config/middleware/deny_list.md +45 -0
  294. data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  295. data/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
  296. data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  297. data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  298. data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  299. data/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
  300. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
  301. data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  302. data/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
  303. data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  304. data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  305. data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  306. data/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
  307. data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  308. data/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
  309. data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  310. data/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
  311. data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  312. data/lib/itsi/server/config/middleware/error_response.md +61 -0
  313. data/lib/itsi/server/config/middleware/error_response.rb +36 -0
  314. data/lib/itsi/server/config/middleware/etag.md +59 -0
  315. data/lib/itsi/server/config/middleware/etag.rb +27 -0
  316. data/lib/itsi/server/config/middleware/grpc.md +172 -0
  317. data/lib/itsi/server/config/middleware/grpc.rb +54 -0
  318. data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  319. data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  320. data/lib/itsi/server/config/middleware/location.md +107 -0
  321. data/lib/itsi/server/config/middleware/location.rb +99 -0
  322. data/lib/itsi/server/config/middleware/log_requests.md +65 -0
  323. data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  324. data/lib/itsi/server/config/middleware/max_body.md +18 -0
  325. data/lib/itsi/server/config/middleware/max_body.rb +21 -0
  326. data/lib/itsi/server/config/middleware/proxy.md +62 -0
  327. data/lib/itsi/server/config/middleware/proxy.rb +41 -0
  328. data/lib/itsi/server/config/middleware/rackup_file.md +54 -0
  329. data/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
  330. data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  331. data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  332. data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  333. data/lib/itsi/server/config/middleware/redirect.md +55 -0
  334. data/lib/itsi/server/config/middleware/redirect.rb +25 -0
  335. data/lib/itsi/server/config/middleware/request_headers.md +34 -0
  336. data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  337. data/lib/itsi/server/config/middleware/response_headers.md +33 -0
  338. data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  339. data/lib/itsi/server/config/middleware/run.md +60 -0
  340. data/lib/itsi/server/config/middleware/run.rb +43 -0
  341. data/lib/itsi/server/config/middleware/static_assets.md +73 -0
  342. data/lib/itsi/server/config/middleware/static_assets.rb +87 -0
  343. data/lib/itsi/server/config/middleware/static_response.md +44 -0
  344. data/lib/itsi/server/config/middleware/static_response.rb +29 -0
  345. data/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
  346. data/lib/itsi/server/config/middleware/token_source.rb +32 -0
  347. data/lib/itsi/server/config/middleware.rb +13 -0
  348. data/lib/itsi/server/config/option.rb +14 -0
  349. data/lib/itsi/server/config/options/_index.md +37 -0
  350. data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  351. data/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
  352. data/lib/itsi/server/config/options/bind.md +71 -0
  353. data/lib/itsi/server/config/options/bind.rb +26 -0
  354. data/lib/itsi/server/config/options/certificates.md +65 -0
  355. data/lib/itsi/server/config/options/daemonize.md +14 -0
  356. data/lib/itsi/server/config/options/daemonize.rb +19 -0
  357. data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  358. data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  359. data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  360. data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  361. data/lib/itsi/server/config/options/hooks/_index.md +11 -0
  362. data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  363. data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  364. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  365. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  366. data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  367. data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  368. data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  369. data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  370. data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  371. data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  372. data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  373. data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  374. data/lib/itsi/server/config/options/include.md +20 -0
  375. data/lib/itsi/server/config/options/include.rb +36 -0
  376. data/lib/itsi/server/config/options/listen_backlog.md +11 -0
  377. data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  378. data/lib/itsi/server/config/options/log_format.md +18 -0
  379. data/lib/itsi/server/config/options/log_format.rb +19 -0
  380. data/lib/itsi/server/config/options/log_level.md +34 -0
  381. data/lib/itsi/server/config/options/log_level.rb +20 -0
  382. data/lib/itsi/server/config/options/log_target.md +38 -0
  383. data/lib/itsi/server/config/options/log_target.rb +19 -0
  384. data/lib/itsi/server/config/options/log_target_filters.md +17 -0
  385. data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  386. data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  387. data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  388. data/lib/itsi/server/config/options/nodelay.md +16 -0
  389. data/lib/itsi/server/config/options/nodelay.rb +19 -0
  390. data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  391. data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  392. data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  393. data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  394. data/lib/itsi/server/config/options/preload.md +21 -0
  395. data/lib/itsi/server/config/options/preload.rb +18 -0
  396. data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  397. data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  398. data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  399. data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  400. data/lib/itsi/server/config/options/request_timeout.md +23 -0
  401. data/lib/itsi/server/config/options/request_timeout.rb +19 -0
  402. data/lib/itsi/server/config/options/reuse_address.md +16 -0
  403. data/lib/itsi/server/config/options/reuse_address.rb +19 -0
  404. data/lib/itsi/server/config/options/reuse_port.md +16 -0
  405. data/lib/itsi/server/config/options/reuse_port.rb +19 -0
  406. data/lib/itsi/server/config/options/scheduler_threads.md +34 -0
  407. data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  408. data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  409. data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  410. data/lib/itsi/server/config/options/stream_body.md +32 -0
  411. data/lib/itsi/server/config/options/stream_body.rb +18 -0
  412. data/lib/itsi/server/config/options/threads.md +44 -0
  413. data/lib/itsi/server/config/options/threads.rb +17 -0
  414. data/lib/itsi/server/config/options/watch.md +16 -0
  415. data/lib/itsi/server/config/options/watch.rb +28 -0
  416. data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  417. data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  418. data/lib/itsi/server/config/options/workers.md +42 -0
  419. data/lib/itsi/server/config/options/workers.rb +17 -0
  420. data/lib/itsi/server/config/typed_struct.rb +242 -0
  421. data/lib/itsi/server/config.rb +289 -0
  422. data/lib/itsi/server/default_app/default_app.rb +34 -0
  423. data/lib/itsi/server/default_app/index.html +115 -0
  424. data/lib/itsi/server/default_config/Itsi.rb +107 -0
  425. data/lib/itsi/server/grpc/grpc_call.rb +246 -0
  426. data/lib/itsi/server/grpc/grpc_interface.rb +107 -0
  427. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  428. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  429. data/lib/itsi/server/rack/handler/itsi.rb +27 -0
  430. data/lib/itsi/server/rack_interface.rb +94 -0
  431. data/lib/itsi/server/route_tester.rb +157 -0
  432. data/lib/itsi/server/scheduler_interface.rb +21 -0
  433. data/lib/itsi/server/scheduler_mode.rb +10 -0
  434. data/lib/itsi/server/signal_trap.rb +33 -0
  435. data/lib/itsi/server/typed_handlers/param_parser.rb +196 -0
  436. data/lib/itsi/server/typed_handlers/source_parser.rb +56 -0
  437. data/lib/itsi/server/typed_handlers.rb +25 -0
  438. data/lib/itsi/server/version.rb +1 -1
  439. data/lib/itsi/server.rb +265 -9
  440. data/lib/itsi/standard_headers.rb +86 -0
  441. data/lib/ruby_lsp/itsi/addon.rb +129 -0
  442. data/lib/shell_completions/completions.rb +26 -0
  443. metadata +454 -28
  444. data/CHANGELOG.md +0 -5
  445. data/CODE_OF_CONDUCT.md +0 -132
  446. data/LICENSE.txt +0 -21
  447. data/ext/itsi_server/src/request/itsi_request.rs +0 -143
  448. data/ext/itsi_server/src/request/mod.rs +0 -1
  449. data/ext/itsi_server/src/server/bind.rs +0 -138
  450. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -32
  451. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -52
  452. data/ext/itsi_server/src/server/itsi_server.rs +0 -182
  453. data/ext/itsi_server/src/server/listener.rs +0 -218
  454. data/ext/itsi_server/src/server/tls.rs +0 -138
  455. data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
  456. data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
  457. data/lib/itsi/request.rb +0 -39
@@ -0,0 +1,122 @@
1
+ ---
2
+ title: Schemas
3
+ url: /middleware/endpoint/schemas
4
+ next: error_response/
5
+ ---
6
+
7
+ Endpoints also support basic schema enforcement for both request and and response bodies. Endpoint **Schemas** are simply plain-old Ruby hashes, which map named keys to allowed types.
8
+
9
+ E.g.
10
+ ```ruby {filename=Itsi.rb}
11
+ # This is a valid schema
12
+ SimpleSchema = {
13
+ score: Integer
14
+ }
15
+ ```
16
+
17
+ A few special rules/conventions apply:
18
+
19
+ * Regexp patterns are used in place of symbol keys to define dynamic parameters that must match a specific pattern (A key of `/.*/` matches any string).
20
+ * A `:Boolean` symbol can be used instead of a class to require boolean parameters (as a proxy for the combination of TrueClass and FalseClass)
21
+ * `Array` keys are used to define arrays of values.
22
+ * Objects can be nested
23
+ * A special `_required` key indicates which parameters in the current object are required.
24
+ * Arrays must be homogeneous (No support for union types).
25
+ * Schema validation *only* supports primitive Ruby types, Date, Time, Datetime, arrays and hashes (no unions or advanced coercion).
26
+
27
+
28
+ ## Supported types
29
+ ```ruby {filename=Itsi.rb}
30
+ # Demo schema with all supported types included
31
+ SupportedTypesSchema = {
32
+ _required: %i[name age active preferences created_at last_login],
33
+ name: String, # A user's name
34
+ age: Integer, # The user's age
35
+ active: :Boolean, # Whether the user is active
36
+ preferences: {
37
+ _required: %i[theme notifications],
38
+ theme: Symbol, # Preferred theme (e.g., :dark, :light)
39
+ notifications: :Boolean # Whether notifications are enabled
40
+ },
41
+ scores: Array[Float], # A list of user scores
42
+ metadata: {
43
+ _required: %i[signup_date last_purchase],
44
+ signup_date: Date, # The date the user signed up
45
+ last_purchase: DateTime # The timestamp of the last purchase
46
+ },
47
+ last_login: Time # The last login time
48
+ }
49
+ ```
50
+
51
+ {{< callout >}}
52
+ Itsi will check for the presence and structure of all:
53
+ * [Schemas](/middleware/schemas)
54
+ * [Controller methods](/middleware/controller)
55
+
56
+ at **boot time** ensuring that you can't be caught out by naming mismatches at runtime, or during a hot-reload.
57
+ If Itsi boots successfully, the referenced schemas objects can be found.
58
+ {{</ callout >}}
59
+
60
+
61
+ ## Request Body Schemas
62
+
63
+ ```ruby {filename=Itsi.rb}
64
+ AddressSchema = {
65
+ _required: %i[street city postcode],
66
+ street: String,
67
+ city: String,
68
+ postcode: String,
69
+ country: String # Optional
70
+ }
71
+
72
+ UserInputSchema = {
73
+ _required: %i[first_name last_name email address],
74
+ first_name: String,
75
+ last_name: String,
76
+ email: String,
77
+ age: Integer,
78
+ active: :Boolean,
79
+ roles: Array[String],
80
+ address: AddressSchema
81
+ }
82
+
83
+ UserResponseSchema = {
84
+ _required: %i[id email full_name],
85
+ id: Integer,
86
+ email: String,
87
+ full_name: String,
88
+ created_at: String,
89
+ address: AddressSchema
90
+ }
91
+
92
+ post "/users" do |request, params: UserInputSchema, response_format: UserResponseSchema|
93
+ user = User.create!(params)
94
+ request.created \
95
+ json: {
96
+ id: user.id,
97
+ email: user.email,
98
+ full_name: "#{user.first_name} #{user.last_name}",
99
+ created_at: user.created_at.iso8601,
100
+ address: {
101
+ street: user.address.street,
102
+ city: user.address.city,
103
+ postcode: user.address.postcode
104
+ }
105
+ },
106
+ as: response_format
107
+ end
108
+ ```
109
+ Endpoints with schema validation applied can count on requests *only* being invoked with correctly formed parameters (and descriptive errors being returned if schema enforcement fails.)
110
+
111
+ You can *optionally* choose to apply a corresponding response schema validation to response objects.
112
+
113
+ ## Response Body Schemas
114
+ ```ruby {filename=Itsi.rb}
115
+ PingSchema = {
116
+ status: String
117
+ }
118
+
119
+ get "/ping" do |req, response_format: PingSchema|
120
+ req.ok json: { status: "ok" }, as: response_format
121
+ end
122
+ ```
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Error Response
3
+ url: /middleware/error_response
4
+ prev: schemas/
5
+ ---
6
+
7
+ All of the below middlewares allow error responses to be customized (though will select a sane default if left unspecified).
8
+ * [`allow_list`](/middleware/allow_list)
9
+ * [`auth_api_key`](/middleware/auth_api_key)
10
+ * [`auth_jwt`](/middleware/auth_jwt)
11
+ * [`deny_list`](/middleware/deny_list)
12
+ * [`intrusion_protection`](/middleware/intrusion_protection)
13
+ * [`max_body`](/middleware/max_body)
14
+ * [`proxy`](/middleware/proxy)
15
+ * [`rate_limit`](/middleware/rate_limit)
16
+
17
+ You can override the default error responses by providing a custom error response, either selecting a different built-in type,
18
+ or providing a completely overridden options.
19
+ The following built-in types are available:
20
+ * `internal_server_error` (500)
21
+ * `not_found` (404)
22
+ * `unauthorized` (401)
23
+ * `forbidden` (403)
24
+ * `payload_too_large` (413)
25
+ * `too_many_requests` (429)
26
+ * `bad_gateway` (502)
27
+ * `service_unavailable` (503)
28
+ * `gateway_timeout` (504)
29
+
30
+ ## Reuse a built-in type
31
+ To reuse a built-in type you can provide a string option for the `error_response` property.
32
+ E.g.
33
+ ```ruby
34
+ auth_api_key .. other options.., error_response: 'forbidden'
35
+ ```
36
+
37
+ ## Override the error response
38
+ You may instead wish to completely override the error response. You can provide a status code, and a message in up to three
39
+ formats: plain-text, JSON, or HTML (at least one must be provided). Itsi will serve the appropriate type based on the `Accept` header of the incoming request, or fall back to the default if the requested type is not available.
40
+ Each of these three response formats can either be provided as an in-memory string, or a file path.
41
+
42
+ E.g.
43
+
44
+ ```ruby
45
+ auth_api_key .. other options.., error_response: {
46
+ status: 403,
47
+ plaintext: nil, # No plain-text response provided
48
+ json: { inline: {"message": "Forbidden"} }, # We provide the JSON response inline
49
+ html: { file: './forbidden.html'}, # We provide the HTML response as a file path
50
+ default: 'json' # When the Accept header doesn't match a supported response type, we'll default to JSON
51
+ }
52
+
53
+ # Or, e.g.
54
+ auth_api_key .. other options.., error_response: {
55
+ status: 401,
56
+ plaintext: "Unauthorized",
57
+ json: { file: "unauthorized.json" },
58
+ html: { inline: "<h1>Unauthorized</h1>" },
59
+ default: 'html'
60
+ }
61
+ ```
@@ -0,0 +1,36 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ InlineContentSource = TypedStruct.new do
5
+ {
6
+ inline: Type(String)
7
+ }
8
+ end
9
+
10
+ FileContentSource = TypedStruct.new do
11
+ {
12
+ file: Type(String)
13
+ }
14
+ end
15
+
16
+ ContentSource = TypedStruct.new do
17
+ Or(Type(InlineContentSource), Type(FileContentSource))
18
+ end
19
+
20
+ ErrorResponse = TypedStruct.new do
21
+ {
22
+ code: Type(Integer) & Required(),
23
+ plaintext: Type(ContentSource),
24
+ html: Type(ContentSource),
25
+ json: Type(ContentSource),
26
+ default: Enum(["plaintext", "html", "json"]) & Required()
27
+ }
28
+ end
29
+
30
+ ErrorResponseDef = TypedStruct.new do
31
+ Or(Enum(%w[internal_server_error not_found unauthorized forbidden payload_too_large
32
+ too_many_requests bad_gateway service_unavailable gateway_timeout]), Type(ErrorResponse)) & Required()
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: ETag
3
+ url: /middleware/etag
4
+ ---
5
+
6
+ The ETag middleware enables HTTP entity tag generation for responses. It provides cache validation by automatically computing and attaching an ETag to outgoing responses, and optionally responding with `304 Not Modified` if the client includes a matching `If-None-Match` header.
7
+
8
+ ETags are useful for optimizing client-side caching, conditional GETs, and reducing unnecessary data transfer.
9
+
10
+
11
+ ## ETag configuration
12
+ ```ruby {filename=Itsi.rb}
13
+ etag \
14
+ type: "strong",
15
+ algorithm: "sha256",
16
+ min_body_size: 0,
17
+ handle_if_none_match: true
18
+ ```
19
+
20
+ ## ETag Applied to a sub-location
21
+ ```ruby {filename=Itsi.rb}
22
+ location "/assets" do
23
+ etag \
24
+ type: "weak",
25
+ algorithm: "md5",
26
+ min_body_size: 1024,
27
+ handle_if_none_match: true
28
+ end
29
+ ```
30
+
31
+ ## Configuration Options
32
+
33
+ - **type**: Specifies whether the generated ETag is `"strong"` or `"weak"`.
34
+ - `strong`: ETag changes with any byte-level difference in the body.
35
+ - `weak`: Indicates a semantic equivalence rather than byte-level identity.
36
+
37
+ - **algorithm**: Specifies the hash algorithm used to compute the ETag.
38
+ - `sha256` (default)
39
+ - `md5`
40
+
41
+ - **min_body_size**: Minimum response body size (in bytes) required before an ETag is generated. Use this to skip ETags for small or trivial responses.
42
+
43
+ - **handle_if_none_match**: When `true`, incoming requests with a matching `If-None-Match` header will receive a `304 Not Modified` response (instead of a full body), if the ETag matches the computed value.
44
+
45
+ ## How It Works
46
+
47
+ ### Before the Response
48
+ If `handle_if_none_match` is enabled and the request includes an `If-None-Match` header, the value is stored in the request context for comparison later.
49
+
50
+ ### After the Response
51
+
52
+ 1. If the status code is cacheable (e.g., 200 OK, 201 Created), the middleware proceeds.
53
+ 2. If an ETag header is already present or if `Cache-Control: no-store` is set, it skips computation.
54
+ 3. If the response body is not streamable and meets the `min_body_size`, it is buffered.
55
+ 4. A hash (SHA-256 or MD5) is computed from the full body content.
56
+ 5. The ETag header is inserted using either strong (`"abc123"`) or weak (`W/"abc123"`) formatting.
57
+ 6. If the incoming request had a matching `If-None-Match`, the response is replaced with a 304 Not Modified.
58
+
59
+ ---
@@ -0,0 +1,27 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Etag < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ etag \\
8
+ type: ${1|"strong","weak"|},
9
+ algorithm: ${2|"sha256","md5"|},
10
+ min_body_size: ${3|0,1024|},
11
+ handle_if_none_match: ${4|true,false|}
12
+ SNIPPET
13
+
14
+ detail "Enables ETag generation for the server."
15
+
16
+ schema do
17
+ {
18
+ type: (Enum(["strong", "weak"]) & Required()).default("strong"),
19
+ algorithm: (Enum(["sha256", "md5"]) & Required()).default("sha256"),
20
+ min_body_size: Range(0...1024 ** 3).default(0),
21
+ handle_if_none_match: Bool().default(true)
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,172 @@
1
+ ---
2
+ title: gRPC
3
+ url: /middleware/grpc
4
+ ---
5
+
6
+ The **gRPC** middleware lets you expose one or more Ruby gRPC service handlers directly in Itsi.
7
+ This allows you to use Itsi's efficient asynchronous server to serve requests and gain enhanced performance and asynchronous capabilities.
8
+
9
+ Under the covers it:
10
+
11
+ 1. Serves a full HTTP/2 gRPC endpoint (with binary frames, trailers, `HTTP/2` compression, and reflection).
12
+ 2. Provides a **JSON‑over‑HTTP** gateway for each unary or streaming method—so you can POST JSON and receive JSON arrays without a gRPC client.
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
+ 4. Supports optional per‑call compression (`none`, `deflate`, `gzip`) and a non‑blocking execution mode.
15
+
16
+ ---
17
+
18
+ ## Usage
19
+
20
+ ```ruby
21
+ # Define (or require) your service implementation:
22
+ # Mount it in your Itsi.rb:
23
+ grpc EchoServiceImpl.new,
24
+ nonblocking: false do # prepend response with grpc‑encoding:gzip
25
+ # any additional middleware can nest here, e.g.:
26
+ response_headers additions: { "X-Service" => ["Echo"] }
27
+ end
28
+ ```
29
+
30
+ ## Options
31
+
32
+ | Option | Type | Default | Description |
33
+ |---------------|---------|---------|---------------------------------------------------------------|
34
+ | `*handlers` | Object | – | One or more gRPC service implementations |
35
+ | `nonblocking` | Boolean | false | Run handler in fiber/thread‑pool (nonblocking mode). Only effective if using [hybrid mode](/options/scheduler_threads), otherwise the gRPC handler will adopt the server global concurrency mode (threads or fibers) |
36
+ | `reflection` | Boolean | true | Determines whether to serve reflection endpoints. (Useful for clients to auto-discover services) |
37
+ | `&block` | Proc | – | **Optional** You can add additional middleware inside an optional block, to apply to all gRPC requests (e.g. rate limiters, deny lists, max body etc. etc.). |
38
+
39
+ Reflection is served only over HTTP/2; JSON‑over‑HTTP works with HTTP/1.1.
40
+
41
+
42
+
43
+ ## Walkthrough
44
+ The below is a simple walkthrough of using Itsi and the [Ruby gRPC](https://grpc.io/docs/languages/ruby/basics/) library to expose a simple "Echo" service in Itsi, complete with both native gRPC/HTTP2 and a JSON‑over‑HTTP gateway.
45
+
46
+ {{% steps %}}
47
+
48
+ ### Step 1 — Define your gRPC contract
49
+
50
+ Create a file `echo.proto` with:
51
+ ```proto
52
+ syntax = "proto3";
53
+ package echo;
54
+
55
+ service EchoService {
56
+ rpc Echo(EchoRequest) returns (EchoResponse);
57
+ }
58
+
59
+ message EchoRequest {
60
+ string message = 1;
61
+ }
62
+
63
+ message EchoResponse {
64
+ string message = 1;
65
+ }
66
+ ```
67
+
68
+ ### Step 2 — Generate Ruby stubs
69
+
70
+ Install the Ruby gRPC tools and run:
71
+ ```bash
72
+ gem install grpc-tools
73
+ grpc_tools_ruby_protoc -I . --ruby_out=./ --grpc_out=./ echo.proto
74
+ ```
75
+ This produces `echo_services_pb.rb` and supporting files.
76
+
77
+ ### Step 3 — Implement the service
78
+
79
+ Create `echo_service_impl.rb`:
80
+ ```ruby {filename=echo_service_impl.rb}
81
+ require_relative 'echo_services_pb'
82
+
83
+ class EchoServiceImpl < Echo::EchoService::Service
84
+ # Unary RPC implementation
85
+ def echo(req, _unused_call)
86
+ Echo::EchoResponse.new(message: req.message)
87
+ end
88
+ end
89
+ ```
90
+
91
+ ### Step 4 — Mount in Itsi
92
+
93
+ In your `Itsi.rb` at the project root, add:
94
+
95
+ ```ruby {filename=Itsi.rb}
96
+ require_relative 'echo_service_impl'
97
+
98
+ bind "https://localhost:3000"
99
+ grpc EchoServiceImpl.new,
100
+ nonblocking: false,
101
+ compression: 'gzip' do
102
+ # Nested middleware still works:
103
+ response_headers additions: { 'X-Service' => ['Echo'] }
104
+ end
105
+ ```
106
+ ### Step 5 — Start the server
107
+ ```bash
108
+ itsi serve
109
+ ```
110
+
111
+ ### Step 6 — Test with a gRPC client
112
+
113
+ E.g. using [Evans](https://github.com/ktr0731/evans)
114
+
115
+ ```bash
116
+ evans --host localhost --port 3000 repl
117
+
118
+ ______
119
+ | ____|
120
+ | |__ __ __ __ _ _ __ ___
121
+ | __| \ \ / / / _. | | '_ \ / __|
122
+ | |____ \ V / | (_| | | | | | \__ \
123
+ |______| \_/ \__,_| |_| |_| |___/
124
+
125
+ more expressive universal gRPC client
126
+
127
+
128
+ echo.EchoService@127.0.0.1:3000> call Echo
129
+ message (TYPE_STRING) => Hello
130
+ {
131
+ "message": "Hello"
132
+ }
133
+
134
+ echo.EchoService@127.0.0.1:3000>
135
+ ```
136
+
137
+ ### Step 7 — Try the JSON gateway
138
+
139
+ You can also POST plain JSON (works over HTTP/1.1 or HTTP/2):
140
+ ```bash
141
+ curl \
142
+ -H 'Content-Type: application/json' \
143
+ -H "Content-Type: application/json" \
144
+ -X POST http://localhost:3000/echo.EchoService/Echo \
145
+ -d '{"message":"world"}'
146
+
147
+ {"message":"world"}
148
+
149
+ ```
150
+
151
+ {{% /steps %}}
152
+
153
+
154
+ ## JSON gateway
155
+ Itsi exposes gRPC services via a secondary JSON gateways for use with simple HTTP clients.
156
+ Once mounted, each service‐method is *also* reachable via HTTP/2 and via simple JSON POSTs:
157
+
158
+ ```bash
159
+ # Unary RPC (Echo)
160
+ curl -X POST http://0.0.0.0:3000/EchoService/Echo \
161
+ -H "Content-Type: application/json" \
162
+ -d '{"message":"hello"}'
163
+ # → 200 OK, body: {"message":"hello"}
164
+
165
+ # Server streaming RPC (e.g. "Numbers"): POST an array, receive JSON array:
166
+ curl -X POST http://0.0.0.0:3000/NumberService/Stream \
167
+ -H "Content-Type: application/json" \
168
+ -d '[{"n":1},{"n":2},{"n":3}]'
169
+ # → 200 OK, body: [{"n":1},{"n":2},{"n":3}]
170
+ ```
171
+
172
+ Under the hood, the same framing machinery is used—you just get plain JSON arrays instead of gRPC frames.
@@ -0,0 +1,54 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Grpc < Middleware
5
+ insert_text [
6
+ <<~SNIPPET,
7
+ grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|} do
8
+ ${3:# nested middleware…}
9
+ end
10
+ SNIPPET
11
+
12
+ <<~SNIPPET,
13
+ grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|}
14
+ SNIPPET
15
+ ]
16
+
17
+ detail [
18
+ "gRPC service with middleware (with HTTP/2, compression, reflection and JSON gateway)",
19
+ "gRPC service (with HTTP/2, compression, reflection and JSON gateway)"
20
+ ]
21
+
22
+ schema do
23
+ {
24
+ handlers: Array(Type(Object)) & Required(),
25
+ reflection: Bool().default(true),
26
+ nonblocking: Bool().default(false),
27
+ inner_block: Type(Proc)
28
+ }
29
+ end
30
+
31
+ def initialize(location, *handlers, reflection: true, nonblocking: false, &block)
32
+ super(location, {
33
+ handlers: handlers,
34
+ reflection: reflection,
35
+ nonblocking: nonblocking,
36
+ inner_block: block
37
+ })
38
+ end
39
+
40
+ def build!
41
+ location.grpc_reflection(@params[:handlers]) if @params[:reflection]
42
+ nonblocking = @params[:nonblocking]
43
+ blk = @params[:inner_block]
44
+ @params[:handlers].each do |handler|
45
+ location.location(Regexp.new("#{Regexp.escape(handler.class.service_name)}/(?:#{handler.class.rpc_descs.keys.map(&:to_s).join("|")})")) do
46
+ @middleware[:app] = { preloader: -> { Itsi::Server::GrpcInterface.for(handler) }, request_type: "grpc", nonblocking: nonblocking }
47
+ instance_exec(&blk) if blk
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,124 @@
1
+ ---
2
+ title: Intrusion Protection
3
+ url: /middleware/intrusion_protection
4
+ ---
5
+
6
+ The **Intrusion Protection** middleware detects and automatically bans clients that attempt to access suspicious URLs or send malicious header values. It combines pattern‑based detection (on request paths and header values) with a back‑end ban manager to temporarily block offending IPs.
7
+
8
+ - **URL Patterns**: a list of regexes; any matching request path causes an immediate ban.
9
+ - **Header Patterns**: per‑header regex lists; any matching header value causes a ban.
10
+ - **Ban Duration**: how long (in seconds) to block the client IP.
11
+ - **Store**: in‑memory or Redis‑backed (`store_config`) for both tracking and bans.
12
+ - **Error Response**: customizable (default is `forbidden`).
13
+
14
+ ## Configuration
15
+
16
+ ```ruby {filename=Itsi.rb}
17
+ intrusion_protection \
18
+ banned_url_patterns: [
19
+ "/admin/login", # brute‑force login attempts
20
+ /\.php$/ # any PHP‑extension request
21
+ ],
22
+ banned_header_patterns: {
23
+ "User-Agent" => [
24
+ "sqlmap", # SQL injection scanner
25
+ "curl" # script‑based probing
26
+ ]
27
+ },
28
+ banned_time_seconds: 300, # ban for 5 minutes
29
+ store_config: "in_memory",# or { redis: { connection_url: "redis://…" } }
30
+ error_response: "forbidden"
31
+ ```
32
+
33
+ ### Using `KnownPaths` Helpers
34
+
35
+ Itsi provides a `KnownPaths` module with many pre‑assembled lists of common attack targets taken from [FuzzDB](https://blog.mozilla.org/security/2013/08/16/introducing-fuzzdb/) (e.g. typical login or backup file locations). Each helper returns an `Array<String>` you can pass directly:
36
+
37
+ ```ruby {filename=Itsi.rb}
38
+ # ban all common WordPress plugin endpoints
39
+ intrusion_protection \
40
+ banned_url_patterns: Itsi::Server::KnownPaths.cms_wp_plugins,
41
+ banned_time_seconds: 600
42
+
43
+ # ban both login files and directory‑brute paths
44
+ intrusion_protection \
45
+ banned_url_patterns: (
46
+ Itsi::Server::KnownPaths.login_file_locations_logins +
47
+ Itsi::Server::KnownPaths.filename_dirname_bruteforce_common_web_extensions
48
+ ).uniq,
49
+ banned_time_seconds: 900
50
+ ```
51
+
52
+ Available helper methods live under `Itsi::Server::KnownPaths`—for example:
53
+
54
+ - `login_file_locations_logins`
55
+ - `filename_dirname_bruteforce_test_demo`
56
+ - `cms_wp_plugins`
57
+ - `php_php_common_backdoors`
58
+ - …and many more.
59
+ To see all options, execute
60
+ ```ruby
61
+ Itsi::Server::KnownPaths::ALL
62
+ ```
63
+ in a REPL or see the raw input files [here](https://github.com/wouterken/itsi/tree/main/gems/server/lib/itsi/server/config/known_paths).
64
+
65
+ ### Options
66
+
67
+ - **banned_url_patterns** (Array<String>)
68
+ Regexes applied to the full `path_and_query` of each request. A match → immediate ban+403.
69
+ - **banned_header_patterns** (Hash<String,Array<String>>)
70
+ For each header name, a list of regexes tested against that header’s value. A match → ban+403.
71
+ - **banned_time_seconds** (Integer)
72
+ Duration (in seconds) to keep the client IP banned.
73
+ - **store_config** (`"in_memory"` or `{ redis: { connection_url: String } }`)
74
+ Backend for counters and ban state.
75
+ - **error_response** (String or detailed ErrorResponse)
76
+ Response returned on detection or if IP is already banned (default: `forbidden`).
77
+ - **trusted_proxies** (Hash<String,Hash>)
78
+ Map of trusted proxy IP addresses to their forwarded header configuration.
79
+
80
+ ## How It Works
81
+
82
+ 1. **Initialization**
83
+ - Compile `banned_url_patterns` into a `RegexSet`.
84
+ - Compile each set of header patterns into its own `RegexSet`.
85
+ - Instantiate a `RateLimiter` and `BanManager` (in‑memory or Redis).
86
+
87
+ 2. **Per‑Request**
88
+ - **Check ban status**: if the IP is already banned, return `error_response` immediately.
89
+ - **URL check**: if the request’s `path_and_query` matches any banned URL pattern, ban the IP for `banned_time_seconds` and return `error_response`.
90
+ - **Header check**: for each configured header, if its value matches any banned pattern, ban the IP and return `error_response`.
91
+ - Otherwise, allow the request to proceed.
92
+
93
+ Banned IPs are automatically un‑banned after the specified TTL.
94
+
95
+ ## Trusted Proxies
96
+
97
+ By default, an intrusion protection middleware uses the IP address from the underlying socket (remote_addr). However, if your server is behind a reverse proxy, all requests will appear to come from the proxy’s IP address. This can break IP-based rules or cause rate-limiting to group all users together.
98
+
99
+ To address this, you can declare trusted proxies and instruct the server to extract the original client IP from forwarded headers only if the request came from one of these proxies.
100
+
101
+
102
+ ### Configuring trusted_proxies
103
+
104
+ To trust one or more upstream proxies, provide a trusted_proxies map in the middleware configuration.
105
+ E.g.
106
+ ```ruby {filename=Itsi.rb}
107
+ intrusion_protection \
108
+ banned_url_patterns: [
109
+ "/admin/login", # brute‑force login attempts
110
+ /\.php$/ # any PHP‑extension request
111
+ ],
112
+ banned_header_patterns: {
113
+ "User-Agent" => [
114
+ "sqlmap", # SQL injection scanner
115
+ "curl" # script‑based probing
116
+ ]
117
+ },
118
+ banned_time_seconds: 300, # ban for 5 minutes
119
+ store_config: "in_memory",# or { redis: { connection_url: "redis://…" } }
120
+ error_response: "forbidden",
121
+ trusted_proxies: {
122
+ "192.168.1.1" => { header: { name: "X-Forwarded-For" } }
123
+ }
124
+ ```