itsi-server 0.2.22-aarch64-linux

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 (451) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +8 -0
  3. data/Cargo.lock +4452 -0
  4. data/Cargo.toml +11 -0
  5. data/Rakefile +57 -0
  6. data/exe/itsi +193 -0
  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.lock +368 -0
  30. data/ext/itsi_error/Cargo.toml +12 -0
  31. data/ext/itsi_error/src/lib.rs +140 -0
  32. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  33. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  34. data/ext/itsi_rb_helpers/Cargo.lock +355 -0
  35. data/ext/itsi_rb_helpers/Cargo.toml +11 -0
  36. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  37. data/ext/itsi_rb_helpers/src/lib.rs +232 -0
  38. data/ext/itsi_scheduler/Cargo.toml +24 -0
  39. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  40. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  41. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  42. data/ext/itsi_scheduler/src/itsi_scheduler.rs +320 -0
  43. data/ext/itsi_scheduler/src/lib.rs +39 -0
  44. data/ext/itsi_server/Cargo.lock +2956 -0
  45. data/ext/itsi_server/Cargo.toml +94 -0
  46. data/ext/itsi_server/extconf.rb +11 -0
  47. data/ext/itsi_server/src/default_responses/html/401.html +68 -0
  48. data/ext/itsi_server/src/default_responses/html/403.html +68 -0
  49. data/ext/itsi_server/src/default_responses/html/404.html +68 -0
  50. data/ext/itsi_server/src/default_responses/html/413.html +71 -0
  51. data/ext/itsi_server/src/default_responses/html/429.html +68 -0
  52. data/ext/itsi_server/src/default_responses/html/500.html +71 -0
  53. data/ext/itsi_server/src/default_responses/html/502.html +71 -0
  54. data/ext/itsi_server/src/default_responses/html/503.html +68 -0
  55. data/ext/itsi_server/src/default_responses/html/504.html +69 -0
  56. data/ext/itsi_server/src/default_responses/html/index.html +238 -0
  57. data/ext/itsi_server/src/default_responses/json/401.json +6 -0
  58. data/ext/itsi_server/src/default_responses/json/403.json +6 -0
  59. data/ext/itsi_server/src/default_responses/json/404.json +6 -0
  60. data/ext/itsi_server/src/default_responses/json/413.json +6 -0
  61. data/ext/itsi_server/src/default_responses/json/429.json +6 -0
  62. data/ext/itsi_server/src/default_responses/json/500.json +6 -0
  63. data/ext/itsi_server/src/default_responses/json/502.json +6 -0
  64. data/ext/itsi_server/src/default_responses/json/503.json +6 -0
  65. data/ext/itsi_server/src/default_responses/json/504.json +6 -0
  66. data/ext/itsi_server/src/default_responses/mod.rs +14 -0
  67. data/ext/itsi_server/src/env.rs +43 -0
  68. data/ext/itsi_server/src/lib.rs +154 -0
  69. data/ext/itsi_server/src/prelude.rs +2 -0
  70. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +116 -0
  71. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +149 -0
  72. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +346 -0
  73. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +265 -0
  74. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +399 -0
  75. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +447 -0
  76. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +545 -0
  77. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +650 -0
  78. data/ext/itsi_server/src/ruby_types/itsi_server.rs +102 -0
  79. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  80. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  81. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  82. data/ext/itsi_server/src/server/binds/listener.rs +485 -0
  83. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  84. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  85. data/ext/itsi_server/src/server/binds/tls.rs +278 -0
  86. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  87. data/ext/itsi_server/src/server/frame_stream.rs +143 -0
  88. data/ext/itsi_server/src/server/http_message_types.rs +230 -0
  89. data/ext/itsi_server/src/server/io_stream.rs +128 -0
  90. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  91. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  92. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
  93. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  94. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +93 -0
  95. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  96. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  97. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +329 -0
  98. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +300 -0
  99. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  100. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  101. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +188 -0
  102. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +168 -0
  103. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +183 -0
  104. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  105. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
  106. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +133 -0
  107. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  108. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +122 -0
  109. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +407 -0
  110. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +155 -0
  111. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +54 -0
  112. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  113. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +138 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +269 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +62 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +218 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  119. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  120. data/ext/itsi_server/src/server/mod.rs +14 -0
  121. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  122. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  123. data/ext/itsi_server/src/server/request_job.rs +11 -0
  124. data/ext/itsi_server/src/server/serve_strategy/acceptor.rs +100 -0
  125. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +411 -0
  126. data/ext/itsi_server/src/server/serve_strategy/mod.rs +31 -0
  127. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +449 -0
  128. data/ext/itsi_server/src/server/signal.rs +129 -0
  129. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  130. data/ext/itsi_server/src/server/thread_worker.rs +504 -0
  131. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  132. data/ext/itsi_server/src/services/itsi_http_service.rs +270 -0
  133. data/ext/itsi_server/src/services/mime_types.rs +2896 -0
  134. data/ext/itsi_server/src/services/mod.rs +6 -0
  135. data/ext/itsi_server/src/services/password_hasher.rs +89 -0
  136. data/ext/itsi_server/src/services/rate_limiter.rs +609 -0
  137. data/ext/itsi_server/src/services/static_file_server.rs +1400 -0
  138. data/ext/itsi_tracing/Cargo.lock +274 -0
  139. data/ext/itsi_tracing/Cargo.toml +17 -0
  140. data/ext/itsi_tracing/src/lib.rs +370 -0
  141. data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
  142. data/lib/itsi/http_request.rb +228 -0
  143. data/lib/itsi/http_response.rb +49 -0
  144. data/lib/itsi/passfile.rb +108 -0
  145. data/lib/itsi/rack_env_pool.rb +49 -0
  146. data/lib/itsi/server/3.1/itsi_server.so +0 -0
  147. data/lib/itsi/server/3.2/itsi_server.so +0 -0
  148. data/lib/itsi/server/3.3/itsi_server.so +0 -0
  149. data/lib/itsi/server/3.4/itsi_server.so +0 -0
  150. data/lib/itsi/server/4.0/itsi_server.so +0 -0
  151. data/lib/itsi/server/config/config_helpers.rb +116 -0
  152. data/lib/itsi/server/config/dsl.rb +208 -0
  153. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  154. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  155. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  156. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  157. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  158. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  159. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  160. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  161. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  162. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  163. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  164. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  165. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  166. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  167. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  168. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  169. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  170. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  171. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  172. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  173. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  174. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  175. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  176. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  177. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  178. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  179. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  180. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  181. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  182. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  183. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  184. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  185. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  186. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  187. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  188. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  189. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  190. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  191. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  192. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  193. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  194. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  212. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  213. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  214. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  215. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  216. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  217. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  218. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  219. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  220. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  221. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  222. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  223. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  224. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  225. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  226. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  227. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  228. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  229. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  230. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  231. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  232. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  233. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  234. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  235. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  236. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  237. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  238. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  239. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  240. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  241. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  242. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  254. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  255. data/lib/itsi/server/config/known_paths.rb +24 -0
  256. data/lib/itsi/server/config/middleware/_index.md +56 -0
  257. data/lib/itsi/server/config/middleware/allow_list.md +46 -0
  258. data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  259. data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  260. data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  261. data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  262. data/lib/itsi/server/config/middleware/auth_basic.rb +46 -0
  263. data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  264. data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  265. data/lib/itsi/server/config/middleware/cache_control.md +78 -0
  266. data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  267. data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  268. data/lib/itsi/server/config/middleware/compression.md +50 -0
  269. data/lib/itsi/server/config/middleware/compression.rb +37 -0
  270. data/lib/itsi/server/config/middleware/cors.md +93 -0
  271. data/lib/itsi/server/config/middleware/cors.rb +32 -0
  272. data/lib/itsi/server/config/middleware/csp.md +37 -0
  273. data/lib/itsi/server/config/middleware/csp.rb +44 -0
  274. data/lib/itsi/server/config/middleware/deny_list.md +45 -0
  275. data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  276. data/lib/itsi/server/config/middleware/endpoint/_index.md +160 -0
  277. data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  278. data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  279. data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  280. data/lib/itsi/server/config/middleware/endpoint/delete.rb +43 -0
  281. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +106 -0
  282. data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  283. data/lib/itsi/server/config/middleware/endpoint/get.rb +43 -0
  284. data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  285. data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  286. data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  287. data/lib/itsi/server/config/middleware/endpoint/patch.rb +43 -0
  288. data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  289. data/lib/itsi/server/config/middleware/endpoint/post.rb +43 -0
  290. data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  291. data/lib/itsi/server/config/middleware/endpoint/put.rb +43 -0
  292. data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  293. data/lib/itsi/server/config/middleware/error_response.md +74 -0
  294. data/lib/itsi/server/config/middleware/error_response.rb +36 -0
  295. data/lib/itsi/server/config/middleware/etag.md +55 -0
  296. data/lib/itsi/server/config/middleware/etag.rb +25 -0
  297. data/lib/itsi/server/config/middleware/grpc.md +170 -0
  298. data/lib/itsi/server/config/middleware/grpc.rb +54 -0
  299. data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  300. data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  301. data/lib/itsi/server/config/middleware/location.md +107 -0
  302. data/lib/itsi/server/config/middleware/location.rb +103 -0
  303. data/lib/itsi/server/config/middleware/log_requests.md +67 -0
  304. data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  305. data/lib/itsi/server/config/middleware/max_body.md +18 -0
  306. data/lib/itsi/server/config/middleware/max_body.rb +21 -0
  307. data/lib/itsi/server/config/middleware/proxy.md +62 -0
  308. data/lib/itsi/server/config/middleware/proxy.rb +42 -0
  309. data/lib/itsi/server/config/middleware/rackup_file.md +72 -0
  310. data/lib/itsi/server/config/middleware/rackup_file.rb +43 -0
  311. data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  312. data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  313. data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  314. data/lib/itsi/server/config/middleware/redirect.md +55 -0
  315. data/lib/itsi/server/config/middleware/redirect.rb +25 -0
  316. data/lib/itsi/server/config/middleware/request_headers.md +34 -0
  317. data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  318. data/lib/itsi/server/config/middleware/response_headers.md +33 -0
  319. data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  320. data/lib/itsi/server/config/middleware/run.md +79 -0
  321. data/lib/itsi/server/config/middleware/run.rb +45 -0
  322. data/lib/itsi/server/config/middleware/static_assets.md +113 -0
  323. data/lib/itsi/server/config/middleware/static_assets.rb +99 -0
  324. data/lib/itsi/server/config/middleware/static_response.md +44 -0
  325. data/lib/itsi/server/config/middleware/static_response.rb +30 -0
  326. data/lib/itsi/server/config/middleware/string_rewrite.md +81 -0
  327. data/lib/itsi/server/config/middleware/token_source.rb +32 -0
  328. data/lib/itsi/server/config/middleware.rb +13 -0
  329. data/lib/itsi/server/config/option.rb +13 -0
  330. data/lib/itsi/server/config/options/_index.md +41 -0
  331. data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  332. data/lib/itsi/server/config/options/auto_reload_config.rb +46 -0
  333. data/lib/itsi/server/config/options/bind.md +71 -0
  334. data/lib/itsi/server/config/options/bind.rb +26 -0
  335. data/lib/itsi/server/config/options/certificates.md +65 -0
  336. data/lib/itsi/server/config/options/daemonize.md +14 -0
  337. data/lib/itsi/server/config/options/daemonize.rb +19 -0
  338. data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  339. data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  340. data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  341. data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  342. data/lib/itsi/server/config/options/hooks/_index.md +11 -0
  343. data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  344. data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  345. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  346. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  347. data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  348. data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  349. data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  350. data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  351. data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  352. data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  353. data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  354. data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  355. data/lib/itsi/server/config/options/include.md +21 -0
  356. data/lib/itsi/server/config/options/include.rb +41 -0
  357. data/lib/itsi/server/config/options/listen_backlog.md +11 -0
  358. data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  359. data/lib/itsi/server/config/options/log_format.md +18 -0
  360. data/lib/itsi/server/config/options/log_format.rb +19 -0
  361. data/lib/itsi/server/config/options/log_level.md +34 -0
  362. data/lib/itsi/server/config/options/log_level.rb +20 -0
  363. data/lib/itsi/server/config/options/log_target.md +38 -0
  364. data/lib/itsi/server/config/options/log_target.rb +19 -0
  365. data/lib/itsi/server/config/options/log_target_filters.md +17 -0
  366. data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  367. data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  368. data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  369. data/lib/itsi/server/config/options/nodelay.md +16 -0
  370. data/lib/itsi/server/config/options/nodelay.rb +19 -0
  371. data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  372. data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  373. data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  374. data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  375. data/lib/itsi/server/config/options/pipeline_flush.md +16 -0
  376. data/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
  377. data/lib/itsi/server/config/options/preload.md +21 -0
  378. data/lib/itsi/server/config/options/preload.rb +18 -0
  379. data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  380. data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  381. data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  382. data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  383. data/lib/itsi/server/config/options/request_timeout.md +23 -0
  384. data/lib/itsi/server/config/options/request_timeout.rb +19 -0
  385. data/lib/itsi/server/config/options/reuse_address.md +18 -0
  386. data/lib/itsi/server/config/options/reuse_address.rb +19 -0
  387. data/lib/itsi/server/config/options/reuse_port.md +18 -0
  388. data/lib/itsi/server/config/options/reuse_port.rb +17 -0
  389. data/lib/itsi/server/config/options/ruby_thread_request_backlog_size.md +18 -0
  390. data/lib/itsi/server/config/options/ruby_thread_request_backlog_size.rb +19 -0
  391. data/lib/itsi/server/config/options/scheduler_threads.md +41 -0
  392. data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  393. data/lib/itsi/server/config/options/send_buffer_size.md +15 -0
  394. data/lib/itsi/server/config/options/send_buffer_size.rb +19 -0
  395. data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  396. data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  397. data/lib/itsi/server/config/options/stream_body.md +32 -0
  398. data/lib/itsi/server/config/options/stream_body.rb +18 -0
  399. data/lib/itsi/server/config/options/threads.md +44 -0
  400. data/lib/itsi/server/config/options/threads.rb +17 -0
  401. data/lib/itsi/server/config/options/watch.md +16 -0
  402. data/lib/itsi/server/config/options/watch.rb +28 -0
  403. data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  404. data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  405. data/lib/itsi/server/config/options/workers.md +42 -0
  406. data/lib/itsi/server/config/options/workers.rb +17 -0
  407. data/lib/itsi/server/config/options/writev.md +25 -0
  408. data/lib/itsi/server/config/options/writev.rb +19 -0
  409. data/lib/itsi/server/config/typed_struct.rb +239 -0
  410. data/lib/itsi/server/config.rb +321 -0
  411. data/lib/itsi/server/default_app/default_app.rb +34 -0
  412. data/lib/itsi/server/default_app/index.html +115 -0
  413. data/lib/itsi/server/default_config/Itsi.rb +108 -0
  414. data/lib/itsi/server/grpc/grpc_call.rb +247 -0
  415. data/lib/itsi/server/grpc/grpc_interface.rb +106 -0
  416. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  417. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  418. data/lib/itsi/server/native_extension.rb +34 -0
  419. data/lib/itsi/server/rack/handler/itsi.rb +29 -0
  420. data/lib/itsi/server/rack_interface.rb +109 -0
  421. data/lib/itsi/server/route_tester.rb +159 -0
  422. data/lib/itsi/server/scheduler_interface.rb +23 -0
  423. data/lib/itsi/server/scheduler_mode.rb +10 -0
  424. data/lib/itsi/server/signal_trap.rb +33 -0
  425. data/lib/itsi/server/typed_handlers/param_parser.rb +221 -0
  426. data/lib/itsi/server/typed_handlers/source_parser.rb +58 -0
  427. data/lib/itsi/server/typed_handlers.rb +25 -0
  428. data/lib/itsi/server/version.rb +7 -0
  429. data/lib/itsi/server.rb +288 -0
  430. data/lib/itsi/standard_headers.rb +86 -0
  431. data/lib/ruby_lsp/itsi/addon.rb +128 -0
  432. data/lib/shell_completions/completions.rb +26 -0
  433. data/vendor/rb-sys-build/.cargo-ok +1 -0
  434. data/vendor/rb-sys-build/.cargo_vcs_info.json +6 -0
  435. data/vendor/rb-sys-build/Cargo.lock +294 -0
  436. data/vendor/rb-sys-build/Cargo.toml +71 -0
  437. data/vendor/rb-sys-build/Cargo.toml.orig +32 -0
  438. data/vendor/rb-sys-build/LICENSE-APACHE +190 -0
  439. data/vendor/rb-sys-build/LICENSE-MIT +21 -0
  440. data/vendor/rb-sys-build/src/bindings/sanitizer.rs +185 -0
  441. data/vendor/rb-sys-build/src/bindings/stable_api.rs +247 -0
  442. data/vendor/rb-sys-build/src/bindings/wrapper.h +71 -0
  443. data/vendor/rb-sys-build/src/bindings.rs +280 -0
  444. data/vendor/rb-sys-build/src/cc.rs +421 -0
  445. data/vendor/rb-sys-build/src/lib.rs +12 -0
  446. data/vendor/rb-sys-build/src/rb_config/flags.rs +101 -0
  447. data/vendor/rb-sys-build/src/rb_config/library.rs +132 -0
  448. data/vendor/rb-sys-build/src/rb_config/search_path.rs +57 -0
  449. data/vendor/rb-sys-build/src/rb_config.rs +906 -0
  450. data/vendor/rb-sys-build/src/utils.rs +53 -0
  451. metadata +569 -0
@@ -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
+ ```
@@ -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 schemes: ["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 schemes: ["http"], content_types: ["application/json"]
105
+ redirect type: :permanent, to: "https://{host}{path_and_query}"
106
+ end
107
+ ```
@@ -0,0 +1,103 @@
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
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].map { |s| s.is_a?(Regexp) ? s : s.to_s }
60
+ @protocols = (params[:protocols] | params[:schemes]).map { |s| s.is_a?(Regexp) ? s : s.to_s }
61
+ @hosts = params[:hosts].map { |s| s.is_a?(Regexp) ? s : s.to_s }
62
+ @ports = params[:ports].map { |s| s.is_a?(Regexp) ? s : s.to_s }
63
+ @extensions = params[:extensions].map { |s| s.is_a?(Regexp) ? s : s.to_s }
64
+ @content_types = params[:content_types].map { |s| s.is_a?(Regexp) ? s : s.to_s }
65
+ @accepts = params[:accepts].map { |s| s.is_a?(Regexp) ? s : s.to_s }
66
+ @block = block
67
+ end
68
+
69
+ def http_methods
70
+ @methods
71
+ end
72
+
73
+ def intersect(a, b)
74
+ return b if a.empty?
75
+ return a if b.empty?
76
+ a & b
77
+ end
78
+
79
+ def build!
80
+ build_child = lambda {
81
+ child = DSL.new(
82
+ location,
83
+ routes: routes,
84
+ methods: intersect(http_methods, location.http_methods),
85
+ protocols: intersect(protocols, location.protocols),
86
+ hosts: intersect(hosts, location.hosts),
87
+ ports: intersect(ports, location.ports),
88
+ extensions: intersect(extensions, location.extensions),
89
+ content_types: intersect(content_types, location.content_types),
90
+ accepts: intersect(accepts, location.accepts),
91
+ controller: location.controller,
92
+ &block
93
+ )
94
+ child.options[:nested_locations].each(&:call)
95
+ location.children << child
96
+ }
97
+ location.options[:nested_locations] << build_child
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,67 @@
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, using [String Rewrite](/middleware/string_rewrite) functionality.
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
+ See [String Rewrite](/middleware/string_rewrite) for more advanced string manipulation options.
50
+
51
+
52
+ ### Path Attributes
53
+ In addition to this, any capture groups referenced by container location blocks
54
+ are also made available, to be interpolated into the log statement. E.g.:
55
+
56
+ ```ruby {filename=Itsi.rb}
57
+
58
+ location "/users/:user_id" do # 1. If we capture user_id here.
59
+
60
+ log_requests before: {
61
+ level: "INFO",
62
+ format: "[{request_id}] User: {user_id}" # 2. Then we can log the user_id here.
63
+ }
64
+
65
+ end
66
+
67
+ ```
@@ -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" => "{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" => "{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,42 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Proxy < Middleware
5
+ insert_text <<~SNIPPET
6
+ proxy \\
7
+ to: "${1:http://backend.example.com{path_and_query}",
8
+ backends: [${2:"127.0.0.1:3001", "127.0.0.1:3002"}],
9
+ backend_priority: ${3|"round_robin","ordered","random"|},
10
+ headers: { ${4| "X-Forwarded-For" => "{addr}"|} },
11
+ verify_ssl: ${5|true,false|},
12
+ timeout: ${6|30,60|},
13
+ tls_sni: ${7|true,false|},
14
+ error_response: ${8|"bad_gateway", "service_unavailable", { code: 503\\, default_format: "html"\\, html: { inline: "<h1>Service Unavailable</h1>" } }|}
15
+ SNIPPET
16
+
17
+ detail "Forwards incoming requests to a backend server using dynamic URL rewriting. Supports various backend selection strategies and header overriding."
18
+
19
+ schema do
20
+ {
21
+ to: Type(String) & Required(),
22
+ backends: Array(Type(String)),
23
+ backend_priority: Enum(%w[round_robin ordered random]).default("round_robin"),
24
+ headers: Hash(Type(String), Type(String)).default({}),
25
+ verify_ssl: Bool().default(true),
26
+ tls_sni: Bool().default(true),
27
+ timeout: Type(Integer).default(30),
28
+ error_response: Type(ErrorResponseDef).default("bad_gateway")
29
+ }
30
+ end
31
+
32
+ def build!
33
+ require "uri"
34
+ @params[:backends] ||= URI.extract(@params[:to]).map(&URI.method(:parse)).map do |u|
35
+ "#{u.scheme}://#{u.host}:#{u.port}"
36
+ end
37
+ super
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end