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,61 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class IntrusionProtection < Middleware
5
+
6
+ require_relative "rate_limit_store"
7
+ require_relative "token_source"
8
+
9
+ insert_text <<~SNIPPET
10
+ intrusion_protection \\
11
+ banned_url_patterns: ${1|KnownPaths.php_php|},
12
+ banned_header_patterns: { "User-Agent" => ${2|%w[sqlmap curl]|} },
13
+ banned_time_seconds: ${3|300,600|},
14
+ store_config: ${4|"in_memory",{redis:{connection_url:"redis://localhost:6379"}}|},
15
+ error_response: ${5|"forbidden",{ code:403\\, plaintext:{inline:"Access Denied"} }|}
16
+ SNIPPET
17
+
18
+
19
+ detail "Detects and automatically bans clients that attempt to access suspicious URLs"
20
+
21
+ schema do
22
+ {
23
+ banned_url_patterns: Array(Type(String)).default([]),
24
+ banned_header_patterns: Hash(Type(String), Array(Type(String))).default({}),
25
+ banned_time_seconds: Type(Float).default(300),
26
+ store_config: (Required() & Or(Enum(["in_memory"]), Type(RateLimitStore))).default("in_memory"),
27
+ error_response: Type(ErrorResponseDef).default("forbidden"),
28
+ combine: Bool().default(true),
29
+ trusted_proxies: (Hash(Type(String), Type(TokenSource)) & Required()).default({})
30
+ }
31
+ end
32
+
33
+ def build!
34
+ @params[:banned_url_patterns] = Array(@params[:banned_url_patterns]).flatten.map do |pattern|
35
+ if pattern.is_a?(Regexp)
36
+ pattern.source
37
+ else
38
+ "#{pattern}$"
39
+ end
40
+ end
41
+
42
+ @params[:banned_header_patterns].transform_values! do |patterns|
43
+ Array(patterns).flatten.map do |pattern|
44
+ if pattern.is_a?(Regexp)
45
+ pattern.source
46
+ else
47
+ pattern
48
+ end
49
+ end
50
+ end
51
+
52
+ if location.middleware[:intrusion_protection]
53
+ location.middleware[:intrusion_protection] = Array(location.middleware[:intrusion_protection]) + [@params]
54
+ else
55
+ location.middleware[:intrusion_protection] = @params
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,107 @@
1
+ ---
2
+ title: Location
3
+ url: /middleware/location
4
+ ---
5
+
6
+ The `location` block is the essential building block of Itsi-powered apps.
7
+ It allows you to selectively apply middleware based on request structure.
8
+ This is similar to a `location` block in NGINX, but with added capabilities—most notably, support for nested location blocks.
9
+ {{< callout type="warn" >}}
10
+ Location blocks are matched in definition order, and only a single location block applies per request.
11
+ This rule is applied recursively: the first top-level match is chosen, then the first matching child, and so on.
12
+ {{</ callout >}}
13
+
14
+ ## Examples
15
+
16
+ ```ruby {filename="Itsi.rb"}
17
+ # Wildcard routes: matches any path beginning with /admin/
18
+ location "/admin/*" do
19
+ auth_basic ...
20
+ end
21
+ ```
22
+
23
+ ```ruby {filename="Itsi.rb"}
24
+ # Nested routes and named captures
25
+ location "/organizations/:organisation_id" do
26
+ location "/users" do
27
+ location "/:user_id([0-9]+)" do
28
+ rate_limiter requests: 10, seconds: 5, ...
29
+ auth_jwt ...
30
+ ...
31
+ end
32
+ end
33
+
34
+ # Shared middleware for multiple exact sub-routes.
35
+ location "/settings", "/options" do
36
+ auth_basic ...
37
+ end
38
+ end
39
+ ```
40
+
41
+ ```ruby {filename="Itsi.rb"}
42
+ # Regex route: matches either 'users' or 'organizations'
43
+ location /(?:users)|(?:organizations)/ do
44
+ intrusion_protection banned_url_patterns: [/wp-admin/]
45
+ ...
46
+ end
47
+ ```
48
+ ```ruby {filename="Itsi.rb"}
49
+ # Match on non-route options.
50
+ # Redirect http requests to https requests
51
+ location protocols: ["http"]
52
+ redirect type: :permanent, to: "https://{host}{path_and_query}"
53
+ end
54
+ ```
55
+
56
+ ## Route Matches
57
+ Routes have several options for matching:
58
+
59
+ {{% details title="Exact Match (e.g. `\"/api/users\"`)" closed="true" %}}
60
+ Matches the complete request path exactly. No prefix matching is performed.
61
+ {{% /details %}}
62
+
63
+
64
+ {{% details title="Wildcard Match (e.g. `\"/api/users/*\"`)" closed="true" %}}
65
+ Fuzzily matches any path that with support for wild-card dynamic segments.
66
+ {{% /details %}}
67
+
68
+ {{% details title="Named Captures (e.g. `\"/api/users/:id\"`)" closed="true" %}}
69
+ Similar to Wildcard match, but captures dynamic segments by name, using `:name` syntax. Matches are delimited by `/`, and captured values are accessible in logs and handlers.
70
+
71
+ You can restrict captures to specific character sets, using embedded regular expressions:
72
+
73
+ ```ruby
74
+ # Matches numeric user IDs
75
+ location "/users/:id([0-9]+)" do
76
+ ...
77
+ end
78
+ ```
79
+ {{% /details %}}
80
+ {{% details title="Regex Match (e.g. `/api\/(users|organizations)/`)" closed="true" %}}
81
+ Full regular expression support for matching complex or variable patterns.
82
+ {{% /details %}}
83
+
84
+ {{% details title="Nested Matches" closed="true" %}}
85
+ Nested blocks allow deeper route matching. Matching proceeds recursively:
86
+ a top-level match is found first, followed by the first matching child block, and so on.
87
+ {{% /details %}}
88
+
89
+
90
+ ## Options
91
+ Location blocks match can also match on several other request attributes:
92
+ * `methods`: An array of HTTP methods to match on. E.g. `%w[GET POST PUT DELETE]`
93
+ * `protocols`: An array of protocols to match on. %w[http https]
94
+ * `hosts`: An array of hosts to match on. E.g. `%w[example.com www.example.com]`
95
+ * `ports`: An array of ports to match on. E.g. `%w[80 443]`
96
+ * `extensions`: An array of file extensions to match on. E.g. `%w[html css js]`
97
+ * `content_types`: An array of content types to match on. E.g. `%w[text/html application/json]`
98
+ * `accepts`: An array of accept headers to match on. E.g. `%w[text/html application/json]`
99
+
100
+ Pass these to the location block using keyword arguments, e.g.
101
+
102
+ ```ruby
103
+ # Redirect all http JSON requests to use https exclusively.
104
+ location protocols: ["http"], content_types: ["application/json"]
105
+ redirect type: :permanent, to: "https://{host}{path_and_query}"
106
+ end
107
+ ```
@@ -0,0 +1,99 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Location < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ location "${1:/}" do
8
+ $2
9
+ end
10
+ SNIPPET
11
+
12
+ detail "Group middleware by route and/or route options"
13
+
14
+ schema do
15
+ {
16
+ routes: Array(Or(Type(String), Type(Regexp))),
17
+ methods: Array(Type(String)),
18
+ protocols: Array(Type(String)),
19
+ schemes: Array(Type(String)),
20
+ hosts: Array(Type(String)),
21
+ ports: Array(Type(String)),
22
+ extensions: Array(Type(String)),
23
+ content_types: Array(Type(String)),
24
+ accepts: Array(Type(String)),
25
+ block: Type(Proc)
26
+ }
27
+ end
28
+
29
+ attr_accessor :location, :routes, :block, :protocols, :hosts, :ports,
30
+ :extensions, :content_types, :accepts, :block
31
+
32
+ def initialize(location,
33
+ *routes,
34
+ methods: [],
35
+ protocols: [],
36
+ schemes: [],
37
+ hosts: [],
38
+ ports: [],
39
+ extensions: [],
40
+ content_types: [],
41
+ accepts: [],
42
+ &block
43
+ )
44
+
45
+ @location = location
46
+ params = self.schema.new({
47
+ routes: routes,
48
+ methods: methods,
49
+ protocols: protocols,
50
+ schemes: schemes,
51
+ hosts: hosts,
52
+ ports: ports,
53
+ extensions: extensions,
54
+ content_types: content_types,
55
+ accepts: accepts,
56
+ block: block
57
+ }).to_h
58
+ @routes = params[:routes].empty? ? ["*"] : params[:routes]
59
+ @methods = params[:methods]
60
+ @protocols = params[:protocols] | params[:schemes]
61
+ @hosts = params[:hosts]
62
+ @ports = params[:ports]
63
+ @extensions = params[:extensions]
64
+ @content_types = params[:content_types]
65
+ @accepts = params[:accepts]
66
+ @block = block
67
+ end
68
+
69
+ def http_methods
70
+ @methods
71
+ end
72
+
73
+ def build!
74
+ build_child = lambda {
75
+ location.children << DSL.new(
76
+ location,
77
+ routes: routes,
78
+ methods: Array(http_methods) | location.http_methods,
79
+ protocols: Array(protocols) | location.protocols,
80
+ hosts: Array(hosts) | location.hosts,
81
+ ports: Array(ports) | location.ports,
82
+ extensions: Array(extensions) | location.extensions,
83
+ content_types: Array(content_types) | location.content_types,
84
+ accepts: Array(accepts) | location.accepts,
85
+ controller: location.controller,
86
+ &block
87
+ )
88
+ }
89
+ if location.parent.nil?
90
+ location.options[:middleware_loaders] << build_child
91
+ else
92
+ build_child[]
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,65 @@
1
+ ---
2
+ title: Request Logs
3
+ url: /middleware/log_requests
4
+ ---
5
+
6
+ The request logging middleware allows you to define customized log statements to occur before and/or after each request is processed.
7
+
8
+ You can provide a log level and format string to be written before and after each request.
9
+
10
+
11
+ ```ruby {filename=Itsi.rb}
12
+ log_requests \
13
+ before: {
14
+ level: "INFO",
15
+ format: "[{request_id}] {method} {path_and_query} - {addr} "
16
+ },
17
+ after: {
18
+ level: "INFO",
19
+ format: "[{request_id}] └─ {status} in {response_time}"
20
+ }
21
+ ```
22
+
23
+
24
+ The log statement can populated with several different placeholders.
25
+ Available values are:
26
+
27
+ ### `before` Format String
28
+ * `request_id` - (A short, unique hexadecimal request identifier)
29
+ * `request_id_full` - (A full 128-bit unique request identifier)
30
+ * `method` - The HTTP method
31
+ * `path` - The HTTP Path
32
+ * `addr` - The client's IP address
33
+ * `host` - The request host
34
+ * `path_and_query` - The path and query combined
35
+ * `query` - The request query string
36
+ * `port` - The bound port
37
+ * `start_time` - The request start time
38
+ * `<Header-Name>`: Any existing request header. For example `{Accept}` or `{Cookie}` will be replaced with its current value.
39
+
40
+
41
+ ### `after` Format String
42
+ * `request_id` - (A short, unique hexadecimal request identifier)
43
+ * `request_id_full` - (A full 128-bit unique request identifier)
44
+ * `status` - The HTTP status code
45
+ * `addr` - The client's IP address
46
+ * `response_time` - The response time in milliseconds
47
+ * `<Header-Name>`: Any existing response header. For example `{Content-Type}` or `{Set-Cookie}` will be replaced with its current value.
48
+
49
+
50
+ ### Path Attributes
51
+ In addition to this, any capture groups referenced by container location blocks
52
+ are also made available, to be interpolated into the log statement. E.g.:
53
+
54
+ ```ruby {filename=Itsi.rb}
55
+
56
+ location "/users/:user_id" do # 1. If we capture user_id here.
57
+
58
+ log_requests before: {
59
+ level: "INFO",
60
+ format: "[{request_id}] User: {user_id}" # 2. Then we can log the user_id here.
61
+ }
62
+
63
+ end
64
+
65
+ ```
@@ -0,0 +1,31 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class LogRequests < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ log_requests \\
8
+ before: { level: ${1|"INFO","WARN","ERROR","DEBUG"|} format: ${2|"[{request_id}] {method} {path_and_query} - {addr} "|} },
9
+ after: { level: ${3|"INFO","WARN","ERROR","DEBUG"|}, format: ${4|"[{request_id}] └─ {status} in {response_time}"|} }
10
+ SNIPPET
11
+
12
+ detail "Enable logging before or after requests"
13
+
14
+ LogRequestConfig = TypedStruct.new do
15
+ {
16
+ level: (Required() & Enum(%w[INFO WARN ERROR DEBUG])).default("INFO"),
17
+ format: Type(String)
18
+ }
19
+ end
20
+
21
+ schema do
22
+ {
23
+ before: Type(LogRequestConfig),
24
+ after: Type(LogRequestConfig)
25
+ }
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: Max Body
3
+ url: /options/max_body
4
+ ---
5
+
6
+ Limits the maximum request body size in bytes. This helps prevent excessively large payloads, which can cause resource exhaustion or denial-of-service issues.
7
+
8
+ ### Default
9
+
10
+ ```ruby {filename=Itsi.rb}
11
+ max_body 10 * 1024 ** 2 # 10 MiB
12
+ ```
13
+
14
+ ### Example
15
+
16
+ ```ruby {filename=Itsi.rb}
17
+ max_body 5 * 1024 ** 2 # 5 MiB
18
+ ```
@@ -0,0 +1,21 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class MaxBody < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ max_body limit_bytes: ${1: 10 * 1024 ** 2} # Maximum body size in bytes
8
+ SNIPPET
9
+
10
+ detail "Limit request body size."
11
+
12
+ schema do
13
+ {
14
+ limit_bytes: (Type(Integer) & Required()).default(10 * 1024 ** 2) # Default 10 MiB
15
+ }
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,62 @@
1
+ ---
2
+ title: Reverse Proxy
3
+ url: /middleware/proxy
4
+ ---
5
+
6
+ The Reverse Proxy middleware enables reverse proxying by forwarding incoming HTTP requests to one of several backend servers. It supports streaming requests and responses, uses a dynamic URL rewriting mechanism to compute the target URL, supports multiple backend selection strategies, and can override or add headers before forwarding requests.
7
+
8
+ ## Proxy Configuration
9
+
10
+ ```ruby
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, \
19
+ error_response: "bad_gateway"
20
+ ```
21
+ ## Options
22
+ | **Option** | **Description** |
23
+ |-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
24
+ | `to` | The target URL. It supports dynamic URL rewriting using placeholders like `{path}` and `{query}`. If no backends are given, it will perform DNS resolution to determine the appropriate backend to route to. This parameter also determines the SNI hostname and Host header (unless overridden). |
25
+ | `backends` (Optional) | An array of Socket addresses. E.g. `["127.0.0.1:3001", "127.0.0.1:3002"]`. If provided, all requests will be routed to one of these backends based on the selected `backend_priority` algorithm. **Note:** The proxy uses persistent connections, so repeated testing from the same client will typically be satisfied by the same backend. |
26
+ | `backend_priority` (Optional) | The strategy for selecting a backend server. Options include `round_robin`, `ordered`, and `random`. Defaults to `round_robin`. |
27
+ | `headers` (Optional) | A hash of headers to be overridden or added before forwarding requests. To clear a header, set the value to `nil`. |
28
+ | `verify_ssl` (Optional) | A boolean indicating whether to verify SSL certificates. Defaults to `true`. |
29
+ | `timeout` (Optional) | The timeout in seconds for the proxy request. Failures to respond in time will result in a 504 timeout error. Defaults to `30` seconds. |
30
+ | `tls_sni` (Optional) | A boolean indicating whether to use TLS SNI. Defaults to `true`. |
31
+ | `error_response` (Optional) | The error response to be returned when the proxy fails. Users can either use a built-in error response or provide a custom one. See [Error Responses](/middleware/error_response) for more details on how to structure this. Defaults to the built-in `502 Bad Gateway` response. |
32
+
33
+ ## How It Works
34
+
35
+ 1. **URL Rewriting**
36
+ The `to` parameter is a dynamic template that applies the [String Rewrite](/middleware/string_rewrite) mechanism. For instance, placeholders such as `{path}` and `{query}` are replaced with parts from the incoming request.
37
+ *Example*:
38
+ - For a request to `/resource?id=5`, a template of
39
+ ```ruby
40
+ "http://backend.example.com/api{path}{query}"
41
+ ```
42
+ produces:
43
+ ```
44
+ http://backend.example.com/api/resource?id=5
45
+ ```
46
+
47
+ 2. **Backend Selection**
48
+ The `backends` array lists available backend server addresses (formatted as `"IP:port"`). The `backend_priority` setting controls how a backend is chosen:
49
+ - **round_robin**: Cycles sequentially through the list.
50
+ - **ordered**: Always selects the first backend.
51
+ - **random**: Chooses a backend at random.
52
+ Note - The proxy uses persistent connections, so repeated testing from the same client will typically be satisfied by the same backend.
53
+
54
+ 3. **Header Overrides**
55
+ The `headers` option lets you specify extra or overriding headers. Each header value may be a literal or a string rewrite. For example, overriding `"X-Forwarded-For"` to carry the client’s IP is done by:
56
+ ```ruby
57
+ { "X-Forwarded-For" => { rewrite: "{addr}" } }
58
+ ```
59
+
60
+ 4. **Request Forwarding and Error Handling**
61
+ Depending on whether the request method is idempotent, the middleware buffers the request body to allow retries, or streams it directly. If the target URL is invalid or a backend error occurs (e.g. timeout or connection error), a configurable error response is returned.
62
+ See [Error Responses](/middleware/error_response) for more details on how to customize errors.
@@ -0,0 +1,41 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Proxy < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ proxy \\
8
+ to: "${1:http://backend.example.com/api{path}{query}}", \\
9
+ backends: [${2:"127.0.0.1:3001", "127.0.0.1:3002"}], \\
10
+ backend_priority: ${3|"round_robin","ordered","random"|}, \\
11
+ headers: { ${4| "X-Forwarded-For" => { rewrite: "{addr}" },|} }, \\
12
+ verify_ssl: ${5|true,false|}, \\
13
+ timeout: ${6|30,60|}, \\
14
+ tls_sni: ${7|true,false|}, \\
15
+ error_response: ${8|"bad_gateway", "service_unavailable", { code: 503\\, default_format: "html"\\, html: { inline: "<h1>Service Unavailable</h1>" } }|}
16
+ SNIPPET
17
+
18
+ detail "Forwards incoming requests to a backend server using dynamic URL rewriting. Supports various backend selection strategies and header overriding."
19
+
20
+ schema do
21
+ {
22
+ to: Type(String) & Required(),
23
+ backends: Array(Type(String)),
24
+ backend_priority: Enum(["round_robin", "ordered", "random"]).default("round_robin"),
25
+ headers: Hash(Type(String), Type(String)).default({}),
26
+ verify_ssl: Bool().default(true),
27
+ tls_sni: Bool().default(true),
28
+ timeout: Type(Integer).default(30),
29
+ error_response: Type(ErrorResponseDef).default("bad_gateway"),
30
+ }
31
+ end
32
+
33
+ def build!
34
+ require 'uri'
35
+ @params[:backends]||= URI.extract(@params[:to]).map(&URI.method(:parse)).map{|u| "#{u.scheme}://#{u.host}:#{u.port}" }
36
+ super
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: Rackup File
3
+ url: /middleware/rackup_file
4
+ ---
5
+
6
+ You can use the `rackup_file` middleware to mount a rack application defined in a Rackup file (typically `config.ru`)
7
+
8
+ The alternative way to mount a rack application is to use the [`run`](/middleware/run) middleware to define a Rack app inline.
9
+
10
+ You can mount several rack applications to run simultaneously within a single Itsi application, using different location blocks.
11
+ Depending on *where* you mount the app, the application will receive different values for `PATH_INFO`, `SCRIPT_NAME`.
12
+
13
+
14
+ {{< callout >}}
15
+ If no `Itsi.rb` file is defined, Itsi will attempt to run the app defined at `./config.ru` by default, just like other Rack servers. You can also use `-r` or `--rackup_file` flags to specify a different file.
16
+ {{< /callout >}}
17
+
18
+
19
+ ## Configuration
20
+
21
+ ### Simple inline Rackup file.
22
+ ```ruby {filename=Itsi.rb}
23
+ rackup_file "config.ru"
24
+ ```
25
+
26
+
27
+ ### Rack app mounted at a subpath
28
+ ```ruby {filename=Itsi.rb}
29
+ require 'rack'
30
+ location "/subpath/*" do
31
+ rackup_file "config.ru"
32
+ end
33
+
34
+ rackup_file "config.ru"
35
+
36
+ ```
37
+
38
+ ```bash
39
+ # SCRIPT_NAME is "/subpath", path_info is "/child_path"
40
+ $ curl http://0.0.0.0:3000/subpath/child_path
41
+
42
+ # SCRIPT_NAME is "", path_info is "/root/child_path"
43
+ $ curl http://0.0.0.0:3000/root/child_path
44
+ :/root/child_path
45
+ ```
46
+
47
+ ### Options
48
+ * `nonblocking` (default false). Determines whether requests sent to this Rack application should be run on non-blocking threads. Only applies if running in hybrid (non-blocking and blocking thread pool) mode. Otherwise this is a no-op and will run in whatever mode is set globally.
49
+ * `sendfile` (default true). Determines whether Itsi should respect the `X-Sendfile` header set by the Rack application and use the `sendfile` function to efficiently send files. (Despite the name, this does not use the OS-level `sendfile` system call). Note. Itsi enforces the restriction that the referenced file must be within a child directory of the application root.
50
+
51
+ e.g.
52
+ ```ruby {filename=Itsi.rb}
53
+ rackup_file "config.ru", nonblocking: true, sendfile: false
54
+ ```
@@ -0,0 +1,44 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class RackupFile < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ rackup_file \\
8
+ "config.ru",
9
+ nonblocking: ${2|true,false|},
10
+ sendfile: ${3|true,false|}
11
+
12
+ SNIPPET
13
+
14
+ detail "Define an inline Rack Application"
15
+
16
+ schema do
17
+ {
18
+ nonblocking: Bool().default(false),
19
+ sendfile: Bool().default(true)
20
+ }
21
+ end
22
+
23
+ def initialize(location, app, **params)
24
+ super(location, params)
25
+ raise "Rackup file must be a string" unless app.is_a?(String)
26
+ @app = Itsi::Server::RackInterface.for(app)
27
+ end
28
+
29
+ def build!
30
+ app_args = {
31
+ preloader: -> { @app},
32
+ sendfile: @params[:sendfile],
33
+ nonblocking: @params[:nonblocking],
34
+ base_path: "^(?<base_path>#{location.paths_from_parent.gsub(/\.\*\)$/, ')')}).*$"
35
+ }
36
+ location.middleware[:app] = app_args
37
+ location.location("*") do
38
+ @middleware[:app] = app_args
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end