itsi 0.1.19 → 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 (645) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Cargo.lock +942 -242
  4. data/LICENSE.txt +698 -0
  5. data/README.md +77 -54
  6. data/Rakefile +9 -5
  7. data/crates/itsi_acme/.gitignore +4 -0
  8. data/crates/itsi_acme/Cargo.toml +86 -0
  9. data/crates/itsi_acme/LICENSE-APACHE +201 -0
  10. data/crates/itsi_acme/LICENSE-MIT +23 -0
  11. data/crates/itsi_acme/README.md +9 -0
  12. data/crates/itsi_acme/examples/high_level.rs +63 -0
  13. data/crates/itsi_acme/examples/high_level_warp.rs +52 -0
  14. data/crates/itsi_acme/examples/low_level.rs +87 -0
  15. data/crates/itsi_acme/examples/low_level_axum.rs +66 -0
  16. data/crates/itsi_acme/src/acceptor.rs +81 -0
  17. data/crates/itsi_acme/src/acme.rs +354 -0
  18. data/crates/itsi_acme/src/axum.rs +86 -0
  19. data/crates/itsi_acme/src/cache.rs +39 -0
  20. data/crates/itsi_acme/src/caches/boxed.rs +80 -0
  21. data/crates/itsi_acme/src/caches/composite.rs +69 -0
  22. data/crates/itsi_acme/src/caches/dir.rs +106 -0
  23. data/crates/itsi_acme/src/caches/mod.rs +11 -0
  24. data/crates/itsi_acme/src/caches/no.rs +78 -0
  25. data/crates/itsi_acme/src/caches/test.rs +136 -0
  26. data/crates/itsi_acme/src/config.rs +172 -0
  27. data/crates/itsi_acme/src/https_helper.rs +69 -0
  28. data/crates/itsi_acme/src/incoming.rs +142 -0
  29. data/crates/itsi_acme/src/jose.rs +161 -0
  30. data/crates/itsi_acme/src/lib.rs +142 -0
  31. data/crates/itsi_acme/src/resolver.rs +59 -0
  32. data/crates/itsi_acme/src/state.rs +424 -0
  33. data/crates/itsi_rb_helpers/src/lib.rs +4 -3
  34. data/crates/itsi_scheduler/Cargo.toml +1 -1
  35. data/crates/itsi_scheduler/src/itsi_scheduler.rs +8 -2
  36. data/crates/itsi_scheduler/src/lib.rs +1 -0
  37. data/crates/itsi_server/Cargo.toml +3 -3
  38. data/crates/itsi_server/src/lib.rs +2 -1
  39. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +20 -3
  40. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +11 -3
  41. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +255 -65
  42. data/crates/itsi_server/src/ruby_types/itsi_server.rs +3 -0
  43. data/crates/itsi_server/src/server/binds/bind.rs +3 -0
  44. data/crates/itsi_server/src/server/binds/listener.rs +44 -32
  45. data/crates/itsi_server/src/server/binds/tls/locked_dir_cache.rs +2 -2
  46. data/crates/itsi_server/src/server/binds/tls.rs +14 -6
  47. data/crates/itsi_server/src/server/middleware_stack/middleware.rs +33 -28
  48. data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +12 -5
  49. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +8 -1
  50. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +9 -1
  51. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +95 -37
  52. data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +11 -2
  53. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +39 -12
  54. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +36 -27
  55. data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  56. data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +12 -3
  57. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +74 -72
  58. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +15 -1
  59. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +11 -8
  60. data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +19 -11
  61. data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +5 -5
  62. data/crates/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +2 -2
  63. data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +31 -2
  64. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +17 -20
  65. data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +19 -8
  66. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +16 -37
  67. data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +22 -12
  68. data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +26 -11
  69. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +3 -3
  70. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +9 -2
  71. data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +14 -4
  72. data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +19 -0
  73. data/crates/itsi_server/src/server/middleware_stack/mod.rs +69 -35
  74. data/crates/itsi_server/src/server/mod.rs +1 -0
  75. data/crates/itsi_server/src/server/redirect_type.rs +26 -0
  76. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +30 -18
  77. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +77 -17
  78. data/crates/itsi_server/src/server/signal.rs +1 -0
  79. data/crates/itsi_server/src/server/size_limited_incoming.rs +6 -0
  80. data/crates/itsi_server/src/server/thread_worker.rs +6 -2
  81. data/crates/itsi_server/src/services/itsi_http_service.rs +20 -2
  82. data/crates/itsi_server/src/services/rate_limiter.rs +15 -4
  83. data/crates/itsi_server/src/services/static_file_server.rs +63 -47
  84. data/crates/itsi_tracing/src/lib.rs +80 -29
  85. data/docker/Dockerfile +12 -0
  86. data/docs/content/_index.md +17 -10
  87. data/docs/content/acknowledgements/_index.md +46 -0
  88. data/docs/content/configuration/_index.md +101 -0
  89. data/docs/content/contact/_index.md +14 -0
  90. data/docs/content/faqs/_index.md +29 -0
  91. data/docs/content/features/_index.md +291 -0
  92. data/docs/content/getting_started/_index.md +73 -0
  93. data/docs/content/getting_started/local_development.md +100 -0
  94. data/docs/content/getting_started/logging.md +23 -0
  95. data/docs/content/getting_started/running_itsi_in_production.md +26 -0
  96. data/docs/content/getting_started/signals.md +38 -0
  97. data/docs/content/itsi-server-100.png +0 -0
  98. data/docs/content/itsi_scheduler/_index.md +106 -0
  99. data/docs/content/itsi_scheduler/itsi-scheduler-100.png +0 -0
  100. data/docs/content/ruby-lsp.png +0 -0
  101. data/docs/content/ruby.svg +948 -0
  102. data/docs/content/utilities/_index.md +13 -0
  103. data/docs/content/utilities/config_file_testing.md +17 -0
  104. data/docs/content/utilities/passfile_generator.md +41 -0
  105. data/docs/content/utilities/route_testing.md +27 -0
  106. data/docs/content/utilities/secrets_management.md +30 -0
  107. data/docs/data/icons.yaml +949 -0
  108. data/docs/hugo.yaml +27 -28
  109. data/fairytale.txt +33 -0
  110. data/gems/scheduler/Cargo.lock +47 -47
  111. data/gems/scheduler/README.md +52 -24
  112. data/gems/scheduler/Rakefile +0 -4
  113. data/gems/scheduler/itsi-scheduler-100.png +0 -0
  114. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  115. data/gems/scheduler/lib/itsi/scheduler.rb +9 -4
  116. data/gems/scheduler/test/test_active_record.rb +12 -7
  117. data/gems/server/Cargo.lock +950 -239
  118. data/gems/server/README.md +2 -0
  119. data/gems/server/Rakefile +0 -4
  120. data/gems/server/exe/itsi +16 -5
  121. data/gems/server/lib/itsi/http_request/response_status_shortcodes.rb +2 -0
  122. data/gems/server/lib/itsi/http_request.rb +40 -9
  123. data/gems/server/lib/itsi/http_response.rb +2 -1
  124. data/gems/server/lib/itsi/passfile.rb +0 -1
  125. data/gems/server/lib/itsi/server/config/config_helpers.rb +105 -0
  126. data/gems/server/lib/itsi/server/config/dsl.rb +44 -411
  127. data/gems/server/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  128. data/gems/server/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  129. data/gems/server/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  130. data/gems/server/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  131. data/gems/server/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  132. data/gems/server/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  133. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  134. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  135. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  136. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  137. data/gems/server/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  138. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  139. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  140. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  141. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  142. data/gems/server/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  143. data/gems/server/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  144. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  145. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  146. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  147. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  148. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  149. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  150. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  151. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  152. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  153. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  154. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  155. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  156. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  157. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  158. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  159. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  160. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  161. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  162. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  163. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  164. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  165. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  166. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  167. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  168. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  169. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  170. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  171. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  172. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  173. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  174. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  175. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  176. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  177. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  178. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  179. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  180. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  181. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  182. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  183. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  184. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  185. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  186. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  187. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  188. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  189. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  190. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  191. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  192. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  193. data/gems/server/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  194. data/gems/server/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  195. data/gems/server/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  196. data/gems/server/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  197. data/gems/server/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  198. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  199. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  200. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  201. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  202. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  203. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  204. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  205. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  206. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  207. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  208. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  209. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  210. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  211. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  212. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  213. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  214. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  215. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  216. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  217. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  218. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  219. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  220. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  221. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  222. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  223. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  224. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  225. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  226. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  227. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  228. data/gems/server/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  229. data/gems/server/lib/itsi/server/config/known_paths.rb +20 -0
  230. data/gems/server/lib/itsi/server/config/middleware/_index.md +56 -0
  231. data/gems/server/lib/itsi/server/config/middleware/allow_list.md +46 -0
  232. data/gems/server/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  233. data/gems/server/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  234. data/gems/server/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  235. data/gems/server/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  236. data/gems/server/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
  237. data/gems/server/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  238. data/gems/server/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  239. data/gems/server/lib/itsi/server/config/middleware/cache_control.md +78 -0
  240. data/gems/server/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  241. data/gems/server/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  242. data/gems/server/lib/itsi/server/config/middleware/compression.md +50 -0
  243. data/gems/server/lib/itsi/server/config/middleware/compression.rb +37 -0
  244. data/gems/server/lib/itsi/server/config/middleware/cors.md +93 -0
  245. data/gems/server/lib/itsi/server/config/middleware/cors.rb +32 -0
  246. data/gems/server/lib/itsi/server/config/middleware/csp.md +37 -0
  247. data/gems/server/lib/itsi/server/config/middleware/csp.rb +44 -0
  248. data/gems/server/lib/itsi/server/config/middleware/deny_list.md +45 -0
  249. data/gems/server/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  250. data/gems/server/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
  251. data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  252. data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  253. data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  254. data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
  255. data/gems/server/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
  256. data/gems/server/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  257. data/gems/server/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
  258. data/gems/server/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  259. data/gems/server/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  260. data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  261. data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
  262. data/gems/server/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  263. data/gems/server/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
  264. data/gems/server/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  265. data/gems/server/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
  266. data/gems/server/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  267. data/gems/server/lib/itsi/server/config/middleware/error_response.md +61 -0
  268. data/gems/server/lib/itsi/server/config/middleware/error_response.rb +36 -0
  269. data/gems/server/lib/itsi/server/config/middleware/etag.md +59 -0
  270. data/gems/server/lib/itsi/server/config/middleware/etag.rb +27 -0
  271. data/gems/server/lib/itsi/server/config/middleware/grpc.md +172 -0
  272. data/gems/server/lib/itsi/server/config/middleware/grpc.rb +54 -0
  273. data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  274. data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  275. data/gems/server/lib/itsi/server/config/middleware/location.md +107 -0
  276. data/gems/server/lib/itsi/server/config/middleware/location.rb +99 -0
  277. data/gems/server/lib/itsi/server/config/middleware/log_requests.md +65 -0
  278. data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  279. data/gems/server/lib/itsi/server/config/middleware/max_body.md +18 -0
  280. data/gems/server/lib/itsi/server/config/middleware/max_body.rb +21 -0
  281. data/gems/server/lib/itsi/server/config/middleware/proxy.md +62 -0
  282. data/gems/server/lib/itsi/server/config/middleware/proxy.rb +41 -0
  283. data/gems/server/lib/itsi/server/config/middleware/rackup_file.md +54 -0
  284. data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
  285. data/gems/server/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  286. data/gems/server/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  287. data/gems/server/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  288. data/gems/server/lib/itsi/server/config/middleware/redirect.md +55 -0
  289. data/gems/server/lib/itsi/server/config/middleware/redirect.rb +25 -0
  290. data/gems/server/lib/itsi/server/config/middleware/request_headers.md +34 -0
  291. data/gems/server/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  292. data/gems/server/lib/itsi/server/config/middleware/response_headers.md +33 -0
  293. data/gems/server/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  294. data/gems/server/lib/itsi/server/config/middleware/run.md +60 -0
  295. data/gems/server/lib/itsi/server/config/middleware/run.rb +43 -0
  296. data/gems/server/lib/itsi/server/config/middleware/static_assets.md +73 -0
  297. data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +87 -0
  298. data/gems/server/lib/itsi/server/config/middleware/static_response.md +44 -0
  299. data/gems/server/lib/itsi/server/config/middleware/static_response.rb +29 -0
  300. data/gems/server/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
  301. data/gems/server/lib/itsi/server/config/middleware/token_source.rb +32 -0
  302. data/gems/server/lib/itsi/server/config/middleware.rb +13 -0
  303. data/gems/server/lib/itsi/server/config/option.rb +14 -0
  304. data/gems/server/lib/itsi/server/config/options/_index.md +37 -0
  305. data/gems/server/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  306. data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
  307. data/gems/server/lib/itsi/server/config/options/bind.md +71 -0
  308. data/gems/server/lib/itsi/server/config/options/bind.rb +26 -0
  309. data/gems/server/lib/itsi/server/config/options/certificates.md +65 -0
  310. data/gems/server/lib/itsi/server/config/options/daemonize.md +14 -0
  311. data/gems/server/lib/itsi/server/config/options/daemonize.rb +19 -0
  312. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  313. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  314. data/gems/server/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  315. data/gems/server/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  316. data/gems/server/lib/itsi/server/config/options/hooks/_index.md +11 -0
  317. data/gems/server/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  318. data/gems/server/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  319. data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  320. data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  321. data/gems/server/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  322. data/gems/server/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  323. data/gems/server/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  324. data/gems/server/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  325. data/gems/server/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  326. data/gems/server/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  327. data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  328. data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  329. data/gems/server/lib/itsi/server/config/options/include.md +20 -0
  330. data/gems/server/lib/itsi/server/config/options/include.rb +36 -0
  331. data/gems/server/lib/itsi/server/config/options/listen_backlog.md +11 -0
  332. data/gems/server/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  333. data/gems/server/lib/itsi/server/config/options/log_format.md +18 -0
  334. data/gems/server/lib/itsi/server/config/options/log_format.rb +19 -0
  335. data/gems/server/lib/itsi/server/config/options/log_level.md +34 -0
  336. data/gems/server/lib/itsi/server/config/options/log_level.rb +20 -0
  337. data/gems/server/lib/itsi/server/config/options/log_target.md +38 -0
  338. data/gems/server/lib/itsi/server/config/options/log_target.rb +19 -0
  339. data/gems/server/lib/itsi/server/config/options/log_target_filters.md +17 -0
  340. data/gems/server/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  341. data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  342. data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  343. data/gems/server/lib/itsi/server/config/options/nodelay.md +16 -0
  344. data/gems/server/lib/itsi/server/config/options/nodelay.rb +19 -0
  345. data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  346. data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  347. data/gems/server/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  348. data/gems/server/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  349. data/gems/server/lib/itsi/server/config/options/preload.md +21 -0
  350. data/gems/server/lib/itsi/server/config/options/preload.rb +18 -0
  351. data/gems/server/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  352. data/gems/server/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  353. data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  354. data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  355. data/gems/server/lib/itsi/server/config/options/request_timeout.md +23 -0
  356. data/gems/server/lib/itsi/server/config/options/request_timeout.rb +19 -0
  357. data/gems/server/lib/itsi/server/config/options/reuse_address.md +16 -0
  358. data/gems/server/lib/itsi/server/config/options/reuse_address.rb +19 -0
  359. data/gems/server/lib/itsi/server/config/options/reuse_port.md +16 -0
  360. data/gems/server/lib/itsi/server/config/options/reuse_port.rb +19 -0
  361. data/gems/server/lib/itsi/server/config/options/scheduler_threads.md +34 -0
  362. data/gems/server/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  363. data/gems/server/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  364. data/gems/server/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  365. data/gems/server/lib/itsi/server/config/options/stream_body.md +32 -0
  366. data/gems/server/lib/itsi/server/config/options/stream_body.rb +18 -0
  367. data/gems/server/lib/itsi/server/config/options/threads.md +44 -0
  368. data/gems/server/lib/itsi/server/config/options/threads.rb +17 -0
  369. data/gems/server/lib/itsi/server/config/options/watch.md +16 -0
  370. data/gems/server/lib/itsi/server/config/options/watch.rb +28 -0
  371. data/gems/server/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  372. data/gems/server/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  373. data/gems/server/lib/itsi/server/config/options/workers.md +42 -0
  374. data/gems/server/lib/itsi/server/config/options/workers.rb +17 -0
  375. data/gems/server/lib/itsi/server/config/typed_struct.rb +242 -0
  376. data/gems/server/lib/itsi/server/config.rb +134 -11
  377. data/gems/server/lib/itsi/server/default_config/Itsi.rb +3 -3
  378. data/gems/server/lib/itsi/server/grpc/grpc_call.rb +1 -1
  379. data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +11 -4
  380. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -3
  381. data/gems/server/lib/itsi/server/route_tester.rb +58 -8
  382. data/gems/server/lib/itsi/server/signal_trap.rb +5 -1
  383. data/gems/server/lib/itsi/server/typed_handlers/param_parser.rb +14 -18
  384. data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +6 -5
  385. data/gems/server/lib/itsi/server/typed_handlers.rb +12 -4
  386. data/gems/server/lib/itsi/server/version.rb +1 -1
  387. data/gems/server/lib/itsi/server.rb +122 -17
  388. data/gems/server/lib/ruby_lsp/itsi/addon.rb +66 -48
  389. data/gems/server/test/helpers/test_helper.rb +130 -11
  390. data/gems/server/test/middleware/allow_list.rb +128 -0
  391. data/gems/server/test/middleware/auth_api_key.rb +141 -0
  392. data/gems/server/test/middleware/auth_basic.rb +91 -0
  393. data/gems/server/test/middleware/auth_jwt.rb +214 -0
  394. data/gems/server/test/middleware/cache_control.rb +82 -0
  395. data/gems/server/test/middleware/cidr_to_regex.rb +46 -0
  396. data/gems/server/test/middleware/compression.rb +89 -0
  397. data/gems/server/test/middleware/cors.rb +113 -0
  398. data/gems/server/test/middleware/csp.rb +62 -0
  399. data/gems/server/test/middleware/deny_list.rb +131 -0
  400. data/gems/server/test/middleware/endpoint.rb +300 -0
  401. data/gems/server/test/middleware/etag.rb +75 -0
  402. data/gems/server/test/middleware/grpc/grpc.rb +158 -0
  403. data/gems/server/test/middleware/grpc/test_service.proto +32 -0
  404. data/gems/server/test/middleware/grpc/test_service_impl.rb +28 -0
  405. data/gems/server/test/middleware/grpc/test_service_pb.rb +18 -0
  406. data/gems/server/test/middleware/grpc/test_service_services_pb.rb +30 -0
  407. data/gems/server/test/middleware/header_interpolation.rb +35 -0
  408. data/gems/server/test/middleware/intrusion_protection.rb +259 -0
  409. data/gems/server/test/middleware/location.rb +220 -0
  410. data/gems/server/test/middleware/max_body.rb +20 -0
  411. data/gems/server/test/middleware/proxy.rb +415 -0
  412. data/gems/server/test/middleware/rate_limit.rb +211 -0
  413. data/gems/server/test/middleware/redirect.rb +85 -0
  414. data/gems/server/test/middleware/request_headers.rb +50 -0
  415. data/gems/server/test/middleware/response_headers.rb +50 -0
  416. data/gems/server/test/middleware/static_assets.rb +374 -0
  417. data/gems/server/test/middleware/static_response.rb +56 -0
  418. data/gems/server/test/middleware/string_rewrite.rb +112 -0
  419. data/gems/server/test/middleware/test_log_requests.rb +17 -0
  420. data/gems/server/test/options/bind.rb +47 -0
  421. data/gems/server/test/options/header_read_timeout.rb +23 -0
  422. data/gems/server/test/options/test_request_timeout.rb +16 -0
  423. data/gems/server/test/options/test_threads.rb +15 -0
  424. data/gems/server/test/options/test_workers.rb +16 -0
  425. data/gems/server/test/{test_itsi_server.rb → rack/test_rack_server.rb} +82 -95
  426. data/grpc_test/Itsi.rb +11 -0
  427. data/grpc_test/echo.proto +14 -0
  428. data/grpc_test/echo_pb.rb +16 -0
  429. data/grpc_test/echo_service_impl.rb +8 -0
  430. data/{sandbox/itsi_file/echo_service_nonitsi → grpc_test}/echo_services_pb.rb +0 -7
  431. data/itsi-scheduler-100.png +0 -0
  432. data/itsi-server-100.png +0 -0
  433. data/lib/itsi/version.rb +1 -1
  434. data/tasks.txt +17 -66
  435. metadata +352 -217
  436. data/crates/_index.md +0 -0
  437. data/crates/itsi_server/src/ruby_types/README.md +0 -21
  438. data/crates/itsi_server/test.md +0 -14
  439. data/docs/Itsi.rb +0 -17
  440. data/docs/content/about.md +0 -6
  441. data/docs/content/docs/_index.md +0 -18
  442. data/docs/content/docs/first-page.md +0 -9
  443. data/docs/content/docs/folder/_index.md +0 -10
  444. data/docs/content/docs/folder/leaf.md +0 -7
  445. data/foo/Itsi.rb +0 -122
  446. data/gems/_index.md +0 -18
  447. data/gems/scheduler/CHANGELOG.md +0 -5
  448. data/gems/scheduler/CODE_OF_CONDUCT.md +0 -139
  449. data/gems/scheduler/LICENSE.txt +0 -21
  450. data/gems/scheduler/_index.md +0 -7
  451. data/gems/server/CHANGELOG.md +0 -10
  452. data/gems/server/CODE_OF_CONDUCT.md +0 -139
  453. data/gems/server/LICENSE.txt +0 -21
  454. data/gems/server/_index.md +0 -6
  455. data/gems/server/lib/itsi/server/default_config/Itsi-rackup.rb +0 -119
  456. data/sandbox/README.md +0 -5
  457. data/sandbox/deploy/main.tf +0 -238
  458. data/sandbox/deploy/outputs.tf +0 -4
  459. data/sandbox/deploy/vars.tf +0 -11
  460. data/sandbox/falcon_benchmark/Gemfile +0 -10
  461. data/sandbox/falcon_benchmark/Gemfile.lock +0 -140
  462. data/sandbox/falcon_benchmark/config.ru +0 -54
  463. data/sandbox/itsi_file/Gemfile +0 -13
  464. data/sandbox/itsi_file/Gemfile.lock +0 -111
  465. data/sandbox/itsi_file/Itsi.rb +0 -474
  466. data/sandbox/itsi_file/call.json +0 -1
  467. data/sandbox/itsi_file/echo_client/Gemfile +0 -10
  468. data/sandbox/itsi_file/echo_client/Gemfile.lock +0 -27
  469. data/sandbox/itsi_file/echo_client/README.md +0 -95
  470. data/sandbox/itsi_file/echo_client/echo_client.rb +0 -164
  471. data/sandbox/itsi_file/echo_client/gen_proto.sh +0 -17
  472. data/sandbox/itsi_file/echo_client/lib/echo_pb.rb +0 -16
  473. data/sandbox/itsi_file/echo_client/lib/echo_services_pb.rb +0 -29
  474. data/sandbox/itsi_file/echo_client/run_client.rb +0 -64
  475. data/sandbox/itsi_file/echo_client/test_compressions.sh +0 -20
  476. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile +0 -10
  477. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile.lock +0 -79
  478. data/sandbox/itsi_file/echo_service_nonitsi/echo.proto +0 -26
  479. data/sandbox/itsi_file/echo_service_nonitsi/echo_pb.rb +0 -16
  480. data/sandbox/itsi_file/echo_service_nonitsi/server.rb +0 -52
  481. data/sandbox/itsi_file/error.html +0 -2
  482. data/sandbox/itsi_file/organisations_controller.rb +0 -20
  483. data/sandbox/itsi_file/public/assets/image.png +0 -0
  484. data/sandbox/itsi_sandbox_async/Gemfile +0 -10
  485. data/sandbox/itsi_sandbox_async/Gemfile.lock +0 -69
  486. data/sandbox/itsi_sandbox_async/config.ru +0 -9
  487. data/sandbox/itsi_sandbox_hanami/.env +0 -2
  488. data/sandbox/itsi_sandbox_hanami/.gitignore +0 -6
  489. data/sandbox/itsi_sandbox_hanami/.rspec +0 -1
  490. data/sandbox/itsi_sandbox_hanami/Gemfile +0 -49
  491. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +0 -440
  492. data/sandbox/itsi_sandbox_hanami/Guardfile +0 -9
  493. data/sandbox/itsi_sandbox_hanami/Procfile.dev +0 -2
  494. data/sandbox/itsi_sandbox_hanami/README.md +0 -1
  495. data/sandbox/itsi_sandbox_hanami/Rakefile +0 -3
  496. data/sandbox/itsi_sandbox_hanami/app/action.rb +0 -12
  497. data/sandbox/itsi_sandbox_hanami/app/actions/.keep +0 -0
  498. data/sandbox/itsi_sandbox_hanami/app/assets/css/app.css +0 -5
  499. data/sandbox/itsi_sandbox_hanami/app/assets/images/favicon.ico +0 -0
  500. data/sandbox/itsi_sandbox_hanami/app/assets/js/app.js +0 -1
  501. data/sandbox/itsi_sandbox_hanami/app/db/relation.rb +0 -10
  502. data/sandbox/itsi_sandbox_hanami/app/db/repo.rb +0 -10
  503. data/sandbox/itsi_sandbox_hanami/app/db/struct.rb +0 -10
  504. data/sandbox/itsi_sandbox_hanami/app/operation.rb +0 -9
  505. data/sandbox/itsi_sandbox_hanami/app/relations/.keep +0 -0
  506. data/sandbox/itsi_sandbox_hanami/app/repos/.keep +0 -0
  507. data/sandbox/itsi_sandbox_hanami/app/structs/.keep +0 -0
  508. data/sandbox/itsi_sandbox_hanami/app/templates/layouts/app.html.erb +0 -14
  509. data/sandbox/itsi_sandbox_hanami/app/view.rb +0 -9
  510. data/sandbox/itsi_sandbox_hanami/app/views/helpers.rb +0 -10
  511. data/sandbox/itsi_sandbox_hanami/bin/dev +0 -8
  512. data/sandbox/itsi_sandbox_hanami/config/app.rb +0 -8
  513. data/sandbox/itsi_sandbox_hanami/config/assets.js +0 -16
  514. data/sandbox/itsi_sandbox_hanami/config/db/migrate/.keep +0 -0
  515. data/sandbox/itsi_sandbox_hanami/config/db/seeds.rb +0 -15
  516. data/sandbox/itsi_sandbox_hanami/config/puma.rb +0 -47
  517. data/sandbox/itsi_sandbox_hanami/config/routes.rb +0 -7
  518. data/sandbox/itsi_sandbox_hanami/config/settings.rb +0 -9
  519. data/sandbox/itsi_sandbox_hanami/config.ru +0 -5
  520. data/sandbox/itsi_sandbox_hanami/db/.keep +0 -0
  521. data/sandbox/itsi_sandbox_hanami/lib/itsi_hanami/types.rb +0 -11
  522. data/sandbox/itsi_sandbox_hanami/lib/tasks/.keep +0 -0
  523. data/sandbox/itsi_sandbox_hanami/package-lock.json +0 -946
  524. data/sandbox/itsi_sandbox_hanami/package.json +0 -8
  525. data/sandbox/itsi_sandbox_hanami/spec/requests/root_spec.rb +0 -11
  526. data/sandbox/itsi_sandbox_hanami/spec/spec_helper.rb +0 -9
  527. data/sandbox/itsi_sandbox_hanami/spec/support/db/cleaning.rb +0 -42
  528. data/sandbox/itsi_sandbox_hanami/spec/support/db.rb +0 -10
  529. data/sandbox/itsi_sandbox_hanami/spec/support/features.rb +0 -5
  530. data/sandbox/itsi_sandbox_hanami/spec/support/operations.rb +0 -8
  531. data/sandbox/itsi_sandbox_hanami/spec/support/requests.rb +0 -13
  532. data/sandbox/itsi_sandbox_hanami/spec/support/rspec.rb +0 -61
  533. data/sandbox/itsi_sandbox_rack/Gemfile +0 -17
  534. data/sandbox/itsi_sandbox_rack/Gemfile.lock +0 -153
  535. data/sandbox/itsi_sandbox_rack/config.ru +0 -5
  536. data/sandbox/itsi_sandbox_rack_lint/Gemfile +0 -7
  537. data/sandbox/itsi_sandbox_rack_lint/Gemfile.lock +0 -27
  538. data/sandbox/itsi_sandbox_rack_lint/config.ru +0 -3
  539. data/sandbox/itsi_sandbox_rails/.dockerignore +0 -48
  540. data/sandbox/itsi_sandbox_rails/.gitattributes +0 -9
  541. data/sandbox/itsi_sandbox_rails/.github/dependabot.yml +0 -12
  542. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +0 -90
  543. data/sandbox/itsi_sandbox_rails/.gitignore +0 -35
  544. data/sandbox/itsi_sandbox_rails/.rubocop.yml +0 -8
  545. data/sandbox/itsi_sandbox_rails/.ruby-version +0 -1
  546. data/sandbox/itsi_sandbox_rails/Dockerfile +0 -69
  547. data/sandbox/itsi_sandbox_rails/Gemfile +0 -66
  548. data/sandbox/itsi_sandbox_rails/Gemfile.lock +0 -429
  549. data/sandbox/itsi_sandbox_rails/README.md +0 -24
  550. data/sandbox/itsi_sandbox_rails/Rakefile +0 -6
  551. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +0 -4
  552. data/sandbox/itsi_sandbox_rails/app/assets/images/.keep +0 -0
  553. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +0 -15
  554. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +0 -4
  555. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +0 -4
  556. data/sandbox/itsi_sandbox_rails/app/controllers/application_controller.rb +0 -4
  557. data/sandbox/itsi_sandbox_rails/app/controllers/concerns/.keep +0 -0
  558. data/sandbox/itsi_sandbox_rails/app/controllers/home_controller.rb +0 -66
  559. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +0 -40
  560. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -29
  561. data/sandbox/itsi_sandbox_rails/app/helpers/application_helper.rb +0 -2
  562. data/sandbox/itsi_sandbox_rails/app/javascript/application.js +0 -3
  563. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/application.js +0 -9
  564. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/hello_controller.js +0 -7
  565. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/index.js +0 -4
  566. data/sandbox/itsi_sandbox_rails/app/jobs/application_job.rb +0 -7
  567. data/sandbox/itsi_sandbox_rails/app/mailers/application_mailer.rb +0 -4
  568. data/sandbox/itsi_sandbox_rails/app/models/application_record.rb +0 -3
  569. data/sandbox/itsi_sandbox_rails/app/models/concerns/.keep +0 -0
  570. data/sandbox/itsi_sandbox_rails/app/models/post.rb +0 -2
  571. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +0 -23
  572. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.html.erb +0 -13
  573. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.text.erb +0 -1
  574. data/sandbox/itsi_sandbox_rails/app/views/pwa/manifest.json.erb +0 -22
  575. data/sandbox/itsi_sandbox_rails/app/views/pwa/service-worker.js +0 -26
  576. data/sandbox/itsi_sandbox_rails/bin/brakeman +0 -7
  577. data/sandbox/itsi_sandbox_rails/bin/bundle +0 -109
  578. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +0 -13
  579. data/sandbox/itsi_sandbox_rails/bin/importmap +0 -4
  580. data/sandbox/itsi_sandbox_rails/bin/rails +0 -4
  581. data/sandbox/itsi_sandbox_rails/bin/rake +0 -4
  582. data/sandbox/itsi_sandbox_rails/bin/rubocop +0 -8
  583. data/sandbox/itsi_sandbox_rails/bin/setup +0 -37
  584. data/sandbox/itsi_sandbox_rails/config/application.rb +0 -27
  585. data/sandbox/itsi_sandbox_rails/config/boot.rb +0 -4
  586. data/sandbox/itsi_sandbox_rails/config/cable.yml +0 -10
  587. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +0 -1
  588. data/sandbox/itsi_sandbox_rails/config/database.yml +0 -30
  589. data/sandbox/itsi_sandbox_rails/config/environment.rb +0 -5
  590. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +0 -82
  591. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +0 -106
  592. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +0 -67
  593. data/sandbox/itsi_sandbox_rails/config/importmap.rb +0 -7
  594. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +0 -12
  595. data/sandbox/itsi_sandbox_rails/config/initializers/content_security_policy.rb +0 -25
  596. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +0 -8
  597. data/sandbox/itsi_sandbox_rails/config/initializers/inflections.rb +0 -16
  598. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +0 -13
  599. data/sandbox/itsi_sandbox_rails/config/locales/en.yml +0 -31
  600. data/sandbox/itsi_sandbox_rails/config/puma.rb +0 -34
  601. data/sandbox/itsi_sandbox_rails/config/routes.rb +0 -23
  602. data/sandbox/itsi_sandbox_rails/config/storage.yml +0 -34
  603. data/sandbox/itsi_sandbox_rails/config.ru +0 -6
  604. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +0 -10
  605. data/sandbox/itsi_sandbox_rails/db/schema.rb +0 -23
  606. data/sandbox/itsi_sandbox_rails/db/seeds.rb +0 -9
  607. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  608. data/sandbox/itsi_sandbox_rails/lib/tasks/.keep +0 -0
  609. data/sandbox/itsi_sandbox_rails/log/.keep +0 -0
  610. data/sandbox/itsi_sandbox_rails/public/404.html +0 -67
  611. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +0 -66
  612. data/sandbox/itsi_sandbox_rails/public/422.html +0 -67
  613. data/sandbox/itsi_sandbox_rails/public/500.html +0 -66
  614. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  615. data/sandbox/itsi_sandbox_rails/public/icon.svg +0 -3
  616. data/sandbox/itsi_sandbox_rails/public/robots.txt +0 -1
  617. data/sandbox/itsi_sandbox_rails/storage/.keep +0 -0
  618. data/sandbox/itsi_sandbox_rails/test/application_system_test_case.rb +0 -5
  619. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +0 -13
  620. data/sandbox/itsi_sandbox_rails/test/controllers/.keep +0 -0
  621. data/sandbox/itsi_sandbox_rails/test/fixtures/files/.keep +0 -0
  622. data/sandbox/itsi_sandbox_rails/test/helpers/.keep +0 -0
  623. data/sandbox/itsi_sandbox_rails/test/integration/.keep +0 -0
  624. data/sandbox/itsi_sandbox_rails/test/mailers/.keep +0 -0
  625. data/sandbox/itsi_sandbox_rails/test/models/.keep +0 -0
  626. data/sandbox/itsi_sandbox_rails/test/system/.keep +0 -0
  627. data/sandbox/itsi_sandbox_rails/test/test_helper.rb +0 -15
  628. data/sandbox/itsi_sandbox_rails/tmp/.keep +0 -0
  629. data/sandbox/itsi_sandbox_rails/tmp/pids/.keep +0 -0
  630. data/sandbox/itsi_sandbox_rails/tmp/storage/.keep +0 -0
  631. data/sandbox/itsi_sandbox_rails/vendor/.keep +0 -0
  632. data/sandbox/itsi_sandbox_rails/vendor/javascript/.keep +0 -0
  633. data/sandbox/itsi_sandbox_roda/Gemfile +0 -5
  634. data/sandbox/itsi_sandbox_roda/Gemfile.lock +0 -37
  635. data/sandbox/itsi_sandbox_roda/config.ru +0 -39
  636. data/sandbox/itsi_sinatra/Gemfile +0 -9
  637. data/sandbox/itsi_sinatra/Gemfile.lock +0 -81
  638. data/sandbox/itsi_sinatra/app.rb +0 -8
  639. data/sandbox/pebble/docker-compose.yml +0 -11
  640. data/sandbox/static_files/.env +0 -1
  641. data/sandbox/static_files/404.html +0 -25
  642. data/sandbox/static_files/_DSC0102.NEF.jpg +0 -0
  643. data/sandbox/static_files/about.html +0 -68
  644. data/sandbox/static_files/tiny.html +0 -1
  645. data/sandbox/static_files/writebook.zip +0 -0
@@ -1,86 +1,85 @@
1
- use std::convert::Infallible;
2
-
1
+ use super::{ContentSource, DefaultFormat, ErrorResponse};
2
+ use crate::server::http_message_types::ResponseFormat;
3
3
  use bytes::Bytes;
4
4
  use http_body_util::{combinators::BoxBody, Full};
5
-
6
- use crate::server::http_message_types::ResponseFormat;
7
-
8
- use super::{ContentSource, DefaultFormat, ErrorResponse};
5
+ use std::{convert::Infallible, sync::Arc};
9
6
 
10
7
  impl DefaultFormat {
11
8
  pub fn response_for_code(&self, code: u16) -> ContentSource {
12
9
  match self {
13
10
  DefaultFormat::Plaintext => match code {
14
- 500 => ContentSource::Inline("500 Internal Error".to_owned()),
15
- 404 => ContentSource::Inline("404 Not Found".to_owned()),
16
- 401 => ContentSource::Inline("401 Unauthorized".to_owned()),
17
- 403 => ContentSource::Inline("403 Forbidden".to_owned()),
18
- 413 => ContentSource::Inline("413 Payload Too Large".to_owned()),
19
- 429 => ContentSource::Inline("429 Too Many Requests".to_owned()),
20
- 502 => ContentSource::Inline("502 Bad Gateway".to_owned()),
21
- 503 => ContentSource::Inline("503 Service Unavailable".to_owned()),
22
- 504 => ContentSource::Inline("504 Gateway Timeout".to_owned()),
23
- _ => ContentSource::Inline("Unexpected Error".to_owned()),
11
+ 500 => ContentSource::Static(Arc::new("500 Internal Error".into())),
12
+ 404 => ContentSource::Static(Arc::new("404 Not Found".into())),
13
+ 401 => ContentSource::Static(Arc::new("401 Unauthorized".into())),
14
+ 403 => ContentSource::Static(Arc::new("403 Forbidden".into())),
15
+ 413 => ContentSource::Static(Arc::new("413 Payload Too Large".into())),
16
+ 429 => ContentSource::Static(Arc::new("429 Too Many Requests".into())),
17
+ 502 => ContentSource::Static(Arc::new("502 Bad Gateway".into())),
18
+ 503 => ContentSource::Static(Arc::new("503 Service Unavailable".into())),
19
+ 504 => ContentSource::Static(Arc::new("504 Gateway Timeout".into())),
20
+ _ => ContentSource::Static(Arc::new("Unexpected Error".into())),
24
21
  },
25
22
  DefaultFormat::Html => match code {
26
- 500 => ContentSource::Inline(
27
- include_str!("../../../../default_responses/html/500.html").to_owned(),
28
- ),
29
- 404 => ContentSource::Inline(
30
- include_str!("../../../../default_responses/html/404.html").to_owned(),
31
- ),
32
- 401 => ContentSource::Inline(
33
- include_str!("../../../../default_responses/html/401.html").to_owned(),
34
- ),
35
- 403 => ContentSource::Inline(
36
- include_str!("../../../../default_responses/html/403.html").to_owned(),
37
- ),
38
- 413 => ContentSource::Inline(
39
- include_str!("../../../../default_responses/html/413.html").to_owned(),
40
- ),
41
- 429 => ContentSource::Inline(
42
- include_str!("../../../../default_responses/html/429.html").to_owned(),
43
- ),
44
- 502 => ContentSource::Inline(
45
- include_str!("../../../../default_responses/html/502.html").to_owned(),
46
- ),
47
- 503 => ContentSource::Inline(
48
- include_str!("../../../../default_responses/html/503.html").to_owned(),
49
- ),
50
- 504 => ContentSource::Inline(
51
- include_str!("../../../../default_responses/html/504.html").to_owned(),
52
- ),
53
- _ => ContentSource::Inline("Unexpected Error".to_owned()),
23
+ 500 => ContentSource::Static(Arc::new(
24
+ include_str!("../../../../default_responses/html/500.html").into(),
25
+ )),
26
+ 404 => ContentSource::Static(Arc::new(
27
+ include_str!("../../../../default_responses/html/404.html").into(),
28
+ )),
29
+ 401 => ContentSource::Static(Arc::new(
30
+ include_str!("../../../../default_responses/html/401.html").into(),
31
+ )),
32
+ 403 => ContentSource::Static(Arc::new(
33
+ include_str!("../../../../default_responses/html/403.html").into(),
34
+ )),
35
+ 413 => ContentSource::Static(Arc::new(
36
+ include_str!("../../../../default_responses/html/413.html").into(),
37
+ )),
38
+ 429 => ContentSource::Static(Arc::new(
39
+ include_str!("../../../../default_responses/html/429.html").into(),
40
+ )),
41
+ 502 => ContentSource::Static(Arc::new(
42
+ include_str!("../../../../default_responses/html/502.html").into(),
43
+ )),
44
+ 503 => ContentSource::Static(Arc::new(
45
+ include_str!("../../../../default_responses/html/503.html").into(),
46
+ )),
47
+ 504 => ContentSource::Static(Arc::new(
48
+ include_str!("../../../../default_responses/html/504.html").into(),
49
+ )),
50
+ _ => ContentSource::Static(Arc::new(
51
+ include_str!("../../../../default_responses/html/500.html").into(),
52
+ )),
54
53
  },
55
54
  DefaultFormat::Json => match code {
56
- 500 => ContentSource::Inline(
57
- include_str!("../../../../default_responses/json/500.json").to_owned(),
58
- ),
59
- 404 => ContentSource::Inline(
60
- include_str!("../../../../default_responses/json/404.json").to_owned(),
61
- ),
62
- 401 => ContentSource::Inline(
63
- include_str!("../../../../default_responses/json/401.json").to_owned(),
64
- ),
65
- 403 => ContentSource::Inline(
66
- include_str!("../../../../default_responses/json/403.json").to_owned(),
67
- ),
68
- 413 => ContentSource::Inline(
69
- include_str!("../../../../default_responses/json/413.json").to_owned(),
70
- ),
71
- 429 => ContentSource::Inline(
72
- include_str!("../../../../default_responses/json/429.json").to_owned(),
73
- ),
74
- 502 => ContentSource::Inline(
75
- include_str!("../../../../default_responses/json/502.json").to_owned(),
76
- ),
77
- 503 => ContentSource::Inline(
78
- include_str!("../../../../default_responses/json/503.json").to_owned(),
79
- ),
80
- 504 => ContentSource::Inline(
81
- include_str!("../../../../default_responses/json/504.json").to_owned(),
82
- ),
83
- _ => ContentSource::Inline("Unexpected Error".to_owned()),
55
+ 500 => ContentSource::Static(Arc::new(
56
+ include_str!("../../../../default_responses/json/500.json").into(),
57
+ )),
58
+ 404 => ContentSource::Static(Arc::new(
59
+ include_str!("../../../../default_responses/json/404.json").into(),
60
+ )),
61
+ 401 => ContentSource::Static(Arc::new(
62
+ include_str!("../../../../default_responses/json/401.json").into(),
63
+ )),
64
+ 403 => ContentSource::Static(Arc::new(
65
+ include_str!("../../../../default_responses/json/403.json").into(),
66
+ )),
67
+ 413 => ContentSource::Static(Arc::new(
68
+ include_str!("../../../../default_responses/json/413.json").into(),
69
+ )),
70
+ 429 => ContentSource::Static(Arc::new(
71
+ include_str!("../../../../default_responses/json/429.json").into(),
72
+ )),
73
+ 502 => ContentSource::Static(Arc::new(
74
+ include_str!("../../../../default_responses/json/502.json").into(),
75
+ )),
76
+ 503 => ContentSource::Static(Arc::new(
77
+ include_str!("../../../../default_responses/json/503.json").into(),
78
+ )),
79
+ 504 => ContentSource::Static(Arc::new(
80
+ include_str!("../../../../default_responses/json/504.json").into(),
81
+ )),
82
+ _ => ContentSource::Static(Arc::new("Unexpected Error".into())),
84
83
  },
85
84
  }
86
85
  }
@@ -95,6 +94,9 @@ impl ErrorResponse {
95
94
  };
96
95
  match source {
97
96
  ContentSource::Inline(bytes) => BoxBody::new(Full::new(Bytes::from(bytes))),
97
+ ContentSource::Static(text) => {
98
+ BoxBody::new(Full::new(Bytes::from(String::from(text.as_str()))))
99
+ }
98
100
  ContentSource::File(_) => BoxBody::new(Full::new(Bytes::from("Unexpected error"))),
99
101
  }
100
102
  }
@@ -5,6 +5,8 @@ use http_body_util::{combinators::BoxBody, Full};
5
5
  use serde::{Deserialize, Deserializer};
6
6
  use std::convert::Infallible;
7
7
  use std::path::PathBuf;
8
+ use std::sync::Arc;
9
+ use tracing::warn;
8
10
 
9
11
  use crate::server::http_message_types::{HttpResponse, ResponseFormat};
10
12
  use crate::services::static_file_server::ROOT_STATIC_FILE_SERVER;
@@ -16,6 +18,9 @@ pub enum ContentSource {
16
18
  Inline(String),
17
19
  #[serde(rename(deserialize = "file"))]
18
20
  File(PathBuf),
21
+ #[serde(rename(deserialize = "static"))]
22
+ #[serde(skip_deserializing)]
23
+ Static(Arc<String>),
19
24
  }
20
25
 
21
26
  #[derive(Debug, Clone, Deserialize, Default)]
@@ -90,7 +95,13 @@ impl From<ErrorResponseDef> for ErrorResponse {
90
95
  "bad_gateway" => ErrorResponse::bad_gateway(),
91
96
  "service_unavailable" => ErrorResponse::service_unavailable(),
92
97
  "gateway_timeout" => ErrorResponse::gateway_timeout(),
93
- _ => panic!("Unknown error response name: {}", name),
98
+ _ => {
99
+ warn!(
100
+ "Unknown error response name: {}. Using internal server error.",
101
+ name
102
+ );
103
+ ErrorResponse::internal_server_error()
104
+ }
94
105
  },
95
106
  }
96
107
  }
@@ -139,6 +150,9 @@ impl ErrorResponse {
139
150
  Some(ContentSource::Inline(text)) => {
140
151
  return BoxBody::new(Full::new(Bytes::from(text.clone())));
141
152
  }
153
+ Some(ContentSource::Static(text)) => {
154
+ return BoxBody::new(Full::new(Bytes::from(String::from(text.as_str()))));
155
+ }
142
156
  Some(ContentSource::File(path)) => {
143
157
  // Convert the PathBuf to a &str (assumes valid UTF-8).
144
158
  if let Some(path_str) = path.to_str() {
@@ -15,6 +15,7 @@ use hyper::body::Body;
15
15
  use magnus::error::Result;
16
16
  use serde::Deserialize;
17
17
  use sha2::{Digest, Sha256};
18
+ use tracing::debug;
18
19
 
19
20
  #[derive(Debug, Clone, Copy, Deserialize, Default)]
20
21
  pub enum ETagType {
@@ -60,6 +61,7 @@ impl MiddlewareLayer for ETag {
60
61
  // Store if-none-match header in context if present for later use in after hook
61
62
  if self.handle_if_none_match {
62
63
  if let Some(if_none_match) = req.headers().get(header::IF_NONE_MATCH) {
64
+ debug!(target: "middleware::etag", "Received If-None-Match header: {:?}", if_none_match);
63
65
  if let Ok(etag_value) = if_none_match.to_str() {
64
66
  context.set_if_none_match(Some(etag_value.to_string()));
65
67
  }
@@ -77,33 +79,35 @@ impl MiddlewareLayer for ETag {
77
79
  | StatusCode::NON_AUTHORITATIVE_INFORMATION
78
80
  | StatusCode::NO_CONTENT
79
81
  | StatusCode::PARTIAL_CONTENT => {}
80
- _ => return resp,
82
+ _ => {
83
+ debug!(target: "middleware::etag", "Skipping ETag middleware for ineligible response");
84
+ return resp;
85
+ }
81
86
  }
82
87
 
83
- // Skip if already has an ETag
84
88
  if resp.headers().contains_key(header::ETAG) {
89
+ debug!(target: "middleware::etag", "Forwarding response with existing ETag");
85
90
  return resp;
86
91
  }
87
92
 
88
- // Skip if Cache-Control: no-store is present
89
93
  if let Some(cache_control) = resp.headers().get(header::CACHE_CONTROL) {
90
94
  if let Ok(cache_control_str) = cache_control.to_str() {
91
95
  if cache_control_str.contains("no-store") {
96
+ debug!(target: "middleware::etag", "Skipping ETag for no-store response");
92
97
  return resp;
93
98
  }
94
99
  }
95
100
  }
96
101
 
97
- // Check if body is a stream or fixed size using size_hint (similar to compression.rs)
98
102
  let body_size = resp.size_hint().exact();
99
103
 
100
- // Skip streaming bodies
101
104
  if body_size.is_none() {
105
+ debug!(target: "middleware::etag", "Skipping ETag for streaming response");
102
106
  return resp;
103
107
  }
104
108
 
105
- // Skip if body is too small
106
109
  if body_size.unwrap_or(0) < self.min_body_size as u64 {
110
+ debug!(target: "middleware::etag", "Skipping ETag for small response");
107
111
  return resp;
108
112
  }
109
113
 
@@ -142,6 +146,7 @@ impl MiddlewareLayer for ETag {
142
146
  ETagType::Weak => format!("W/\"{}\"", computed_etag),
143
147
  };
144
148
 
149
+ debug!(target: "middleware::etag", "Computed ETag for response {}", formatted_etag);
145
150
  if let Ok(value) = HeaderValue::from_str(&formatted_etag) {
146
151
  parts.headers.insert(header::ETAG, value);
147
152
  }
@@ -150,7 +155,6 @@ impl MiddlewareLayer for ETag {
150
155
  formatted_etag
151
156
  };
152
157
 
153
- // Handle 304 Not Modified if we have an If-None-Match header and it matches
154
158
  if self.handle_if_none_match {
155
159
  if let Some(if_none_match) = context.get_if_none_match() {
156
160
  if if_none_match == etag_value || if_none_match == "*" {
@@ -176,7 +180,6 @@ impl MiddlewareLayer for ETag {
176
180
  }
177
181
  }
178
182
 
179
- // Recreate response with the original body and the ETag header
180
183
  Response::from_parts(parts, body)
181
184
  }
182
185
  }
@@ -4,6 +4,7 @@ use crate::services::rate_limiter::{
4
4
  get_ban_manager, get_rate_limiter, BanManager, RateLimiter, RateLimiterConfig,
5
5
  };
6
6
 
7
+ use super::token_source::TokenSource;
7
8
  use super::{ErrorResponse, FromValue, MiddlewareLayer};
8
9
 
9
10
  use async_trait::async_trait;
@@ -28,12 +29,13 @@ pub struct IntrusionProtection {
28
29
  pub banned_header_pattern_matchers: OnceLock<HashMap<String, RegexSet>>,
29
30
  #[serde(default)]
30
31
  pub banned_header_patterns: HashMap<String, Vec<String>>,
31
- pub banned_time_seconds: u64,
32
+ pub banned_time_seconds: f64,
32
33
  #[serde(skip_deserializing)]
33
34
  pub rate_limiter: OnceLock<Arc<dyn RateLimiter>>,
34
35
  #[serde(skip_deserializing)]
35
36
  pub ban_manager: OnceLock<BanManager>,
36
37
  pub store_config: RateLimiterConfig,
38
+ pub trusted_proxies: HashMap<String, TokenSource>,
37
39
  #[serde(default = "forbidden_error_response")]
38
40
  pub error_response: ErrorResponse,
39
41
  }
@@ -49,6 +51,7 @@ impl MiddlewareLayer for IntrusionProtection {
49
51
  if !self.banned_url_patterns.is_empty() {
50
52
  match RegexSet::new(&self.banned_url_patterns) {
51
53
  Ok(regex_set) => {
54
+ debug!(target: "middleware::intrusion_protection", "Compiled URL regex patterns: {} items.", regex_set.len());
52
55
  let _ = self.banned_url_pattern_matcher.set(regex_set);
53
56
  }
54
57
  Err(e) => {
@@ -64,6 +67,7 @@ impl MiddlewareLayer for IntrusionProtection {
64
67
  if !patterns.is_empty() {
65
68
  match RegexSet::new(patterns) {
66
69
  Ok(regex_set) => {
70
+ debug!(target: "middleware::intrusion_protection", "Compiled header regex patterns for {}: {} items.", header_name, regex_set.len());
67
71
  header_matchers.insert(header_name.clone(), regex_set);
68
72
  }
69
73
  Err(e) => {
@@ -81,12 +85,14 @@ impl MiddlewareLayer for IntrusionProtection {
81
85
  // Initialize rate limiter (used for tracking bans)
82
86
  // This will automatically fall back to in-memory if Redis fails
83
87
  if let Ok(limiter) = get_rate_limiter(&self.store_config).await {
88
+ debug!(target: "middleware::intrusion_protection", "Initialized rate limiter.");
84
89
  let _ = self.rate_limiter.set(limiter);
85
90
  }
86
91
 
87
92
  // Initialize ban manager
88
93
  // This will automatically fall back to in-memory if Redis fails
89
94
  if let Ok(manager) = get_ban_manager(&self.store_config).await {
95
+ debug!(target: "middleware::intrusion_protection", "Initialized ban manager.");
90
96
  let _ = self.ban_manager.set(manager);
91
97
  }
92
98
 
@@ -99,12 +105,18 @@ impl MiddlewareLayer for IntrusionProtection {
99
105
  context: &mut HttpRequestContext,
100
106
  ) -> Result<Either<HttpRequest, HttpResponse>> {
101
107
  // Get client IP address from context's service
102
- let client_ip = &context.addr;
108
+ let client_ip = if self.trusted_proxies.contains_key(&context.addr) {
109
+ let source = self.trusted_proxies.get(&context.addr).unwrap();
110
+ source.extract_token(&req).unwrap_or(&context.addr)
111
+ } else {
112
+ &context.addr
113
+ };
103
114
 
104
115
  // Check if the IP is already banned
105
116
  if let Some(ban_manager) = self.ban_manager.get() {
106
117
  match ban_manager.is_banned(client_ip).await {
107
118
  Ok(Some(_)) => {
119
+ debug!(target: "middleware::intrusion_protection", "IP {} is banned.", client_ip);
108
120
  return Ok(Either::Right(
109
121
  self.error_response
110
122
  .to_http_response(req.accept().into())
@@ -115,9 +127,7 @@ impl MiddlewareLayer for IntrusionProtection {
115
127
  error!("Error checking IP ban status: {:?}", e);
116
128
  // Continue processing - fail open
117
129
  }
118
- _ => {
119
- // Not banned, continue with intrusion checks
120
- }
130
+ _ => {}
121
131
  }
122
132
  } else {
123
133
  warn!("No ban manager available for intrusion protection");
@@ -128,12 +138,13 @@ impl MiddlewareLayer for IntrusionProtection {
128
138
  let path = req.uri().path_and_query().map(|p| p.as_str()).unwrap_or("");
129
139
 
130
140
  if url_matcher.is_match(path) {
141
+ debug!(target: "middleware::intrusion_protection", "Banned URL pattern detected: {}", path);
131
142
  if let Some(ban_manager) = self.ban_manager.get() {
132
143
  match ban_manager
133
144
  .ban_ip(
134
145
  client_ip,
135
146
  &format!("Banned URL pattern detected: {}", path),
136
- Duration::from_secs(self.banned_time_seconds),
147
+ Duration::from_secs_f64(self.banned_time_seconds),
137
148
  )
138
149
  .await
139
150
  {
@@ -156,10 +167,7 @@ impl MiddlewareLayer for IntrusionProtection {
156
167
  for (header_name, pattern_set) in header_matchers {
157
168
  if let Some(header_value) = req.header(header_name) {
158
169
  if pattern_set.is_match(header_value) {
159
- info!(
160
- "Intrusion detected: Header pattern match for {} in header {}",
161
- header_value, header_name
162
- );
170
+ debug!(target: "middleware::intrusion_protection", "Banned header pattern detected: {} in {}", header_value, header_name);
163
171
 
164
172
  // Ban the IP address if possible
165
173
  if let Some(ban_manager) = self.ban_manager.get() {
@@ -170,7 +178,7 @@ impl MiddlewareLayer for IntrusionProtection {
170
178
  "Banned header pattern detected: {} in {}",
171
179
  header_value, header_name
172
180
  ),
173
- Duration::from_secs(self.banned_time_seconds),
181
+ Duration::from_secs_f64(self.banned_time_seconds),
174
182
  )
175
183
  .await
176
184
  {
@@ -42,11 +42,11 @@ pub enum LogMiddlewareLevel {
42
42
  impl LogMiddlewareLevel {
43
43
  pub fn log(&self, message: String) {
44
44
  match self {
45
- LogMiddlewareLevel::Trace => trace!(message),
46
- LogMiddlewareLevel::Debug => debug!(message),
47
- LogMiddlewareLevel::Info => info!(message),
48
- LogMiddlewareLevel::Warn => warn!(message),
49
- LogMiddlewareLevel::Error => error!(message),
45
+ LogMiddlewareLevel::Trace => trace!(target: "middleware::log_requests", message),
46
+ LogMiddlewareLevel::Debug => debug!(target: "middleware::log_requests", message),
47
+ LogMiddlewareLevel::Info => info!(target: "middleware::log_requests", message),
48
+ LogMiddlewareLevel::Warn => warn!(target: "middleware::log_requests", message),
49
+ LogMiddlewareLevel::Error => error!(target: "middleware::log_requests", message),
50
50
  }
51
51
  }
52
52
  }
@@ -13,7 +13,7 @@ use std::sync::atomic::Ordering;
13
13
 
14
14
  #[derive(Debug, Clone, Deserialize)]
15
15
  pub struct MaxBody {
16
- pub max_size: usize,
16
+ pub limit_bytes: usize,
17
17
  #[serde(default = "payload_too_large_error_response")]
18
18
  pub error_response: ErrorResponse,
19
19
  }
@@ -29,7 +29,7 @@ impl MiddlewareLayer for MaxBody {
29
29
  req: HttpRequest,
30
30
  context: &mut HttpRequestContext,
31
31
  ) -> Result<Either<HttpRequest, HttpResponse>> {
32
- req.body().limit.store(self.max_size, Ordering::Relaxed);
32
+ req.body().limit.store(self.limit_bytes, Ordering::Relaxed);
33
33
  context.set_response_format(req.accept().into());
34
34
  Ok(Either::Left(req))
35
35
  }
@@ -5,6 +5,7 @@ mod auth_jwt;
5
5
  mod cache_control;
6
6
  mod compression;
7
7
  mod cors;
8
+ mod csp;
8
9
  mod deny_list;
9
10
  mod error_response;
10
11
  mod etag;
@@ -23,6 +24,9 @@ mod static_response;
23
24
  mod string_rewrite;
24
25
  mod token_source;
25
26
 
27
+ use std::sync::Arc;
28
+ use std::sync::LazyLock;
29
+
26
30
  pub use allow_list::AllowList;
27
31
  use async_trait::async_trait;
28
32
  pub use auth_api_key::AuthAPIKey;
@@ -32,6 +36,7 @@ pub use cache_control::CacheControl;
32
36
  pub use compression::Compression;
33
37
  pub use compression::CompressionAlgorithm;
34
38
  pub use cors::Cors;
39
+ pub use csp::Csp;
35
40
  pub use deny_list::DenyList;
36
41
  use either::Either;
37
42
  pub use error_response::ErrorResponse;
@@ -39,6 +44,7 @@ pub use etag::ETag;
39
44
  pub use intrusion_protection::IntrusionProtection;
40
45
  pub use log_requests::LogRequests;
41
46
  use magnus::error::Result;
47
+ use magnus::rb_sys::AsRawValue;
42
48
  use magnus::Value;
43
49
  pub use max_body::MaxBody;
44
50
  pub use proxy::Proxy;
@@ -51,17 +57,40 @@ use serde::Deserialize;
51
57
  use serde_magnus::deserialize;
52
58
  pub use static_assets::StaticAssets;
53
59
  pub use static_response::StaticResponse;
60
+ pub use string_rewrite::StringRewrite;
54
61
 
55
62
  use crate::server::http_message_types::HttpRequest;
56
63
  use crate::server::http_message_types::HttpResponse;
57
64
  use crate::services::itsi_http_service::HttpRequestContext;
58
65
 
66
+ use std::collections::HashMap;
67
+ use std::sync::Mutex;
68
+ static CACHE: LazyLock<Mutex<HashMap<u64, Arc<dyn std::any::Any + Send + Sync>>>> =
69
+ LazyLock::new(|| Mutex::new(HashMap::new()));
70
+
71
+ pub fn clear_value_cache() {
72
+ let mut cache = CACHE.lock().unwrap();
73
+ cache.clear();
74
+ }
75
+
59
76
  pub trait FromValue: Sized + Send + Sync + 'static {
60
- fn from_value(value: Value) -> Result<Self>
77
+ fn from_value(value: Value) -> Result<Arc<Self>>
61
78
  where
62
79
  Self: Deserialize<'static>,
63
80
  {
64
- deserialize(value)
81
+ let raw = value.as_raw();
82
+
83
+ let mut cache = CACHE.lock().unwrap();
84
+
85
+ if let Some(cached) = cache.get(&raw) {
86
+ if let Some(deserialized) = cached.downcast_ref::<Arc<Self>>() {
87
+ return Ok(deserialized.clone());
88
+ }
89
+ }
90
+
91
+ let deserialized: Arc<Self> = Arc::new(deserialize(value)?);
92
+ cache.insert(raw, deserialized.clone());
93
+ Ok(deserialized)
65
94
  }
66
95
  }
67
96
 
@@ -33,13 +33,14 @@ use reqwest::{
33
33
  Body, Client, Url,
34
34
  };
35
35
  use serde::Deserialize;
36
+ use tracing::{debug, info};
36
37
 
37
38
  #[derive(Debug, Clone, Deserialize)]
38
39
  pub struct Proxy {
39
40
  pub to: StringRewrite,
40
41
  pub backends: Vec<String>,
41
42
  pub backend_priority: BackendPriority,
42
- pub headers: HashMap<String, Option<ProxiedHeader>>,
43
+ pub headers: HashMap<String, Option<StringRewrite>>,
43
44
  pub verify_ssl: bool,
44
45
  pub timeout: u64,
45
46
  pub tls_sni: bool,
@@ -63,23 +64,6 @@ pub enum BackendPriority {
63
64
  Random,
64
65
  }
65
66
 
66
- #[derive(Debug, Clone, Deserialize)]
67
- pub enum ProxiedHeader {
68
- #[serde(rename(deserialize = "value"))]
69
- String(String),
70
- #[serde(rename(deserialize = "rewrite"))]
71
- StringRewrite(StringRewrite),
72
- }
73
-
74
- impl ProxiedHeader {
75
- pub fn to_string(&self, req: &HttpRequest, context: &HttpRequestContext) -> String {
76
- match self {
77
- ProxiedHeader::String(value) => value.clone(),
78
- ProxiedHeader::StringRewrite(rewrite) => rewrite.rewrite_request(req, context),
79
- }
80
- }
81
- }
82
-
83
67
  #[derive(Debug, Clone)]
84
68
  pub struct Resolver {
85
69
  backends: Arc<Vec<SocketAddr>>,
@@ -164,7 +148,7 @@ impl Proxy {
164
148
  for (name, header_opt) in self.headers.iter() {
165
149
  if let Some(header_value) = header_opt {
166
150
  // Compute the header value using the full HttpRequest.
167
- let value_str = header_value.to_string(req, context);
151
+ let value_str = header_value.rewrite_request(req, context);
168
152
  if let Ok(header_val) = http::HeaderValue::from_str(&value_str) {
169
153
  if let Ok(header_name) = name.parse::<http::header::HeaderName>() {
170
154
  headers.insert(header_name, header_val);
@@ -201,6 +185,7 @@ impl Proxy {
201
185
 
202
186
  // Add a Host header if not overridden.
203
187
  if !overriding_headers.contains_key("host") && !host_str.is_empty() {
188
+ debug!("Adding Host header: {}", host_str);
204
189
  builder = builder.header("Host", host_str);
205
190
  }
206
191
 
@@ -231,6 +216,7 @@ impl Proxy {
231
216
  Err(e) => {
232
217
  // Retry for connectivity-related errors.
233
218
  if e.is_connect() {
219
+ debug!(target: "middleware::proxy", "Connection error, retrying");
234
220
  last_err = Some(e);
235
221
  if attempt + 1 < max_attempts {
236
222
  continue;
@@ -278,6 +264,7 @@ impl MiddlewareLayer for Proxy {
278
264
  }
279
265
  })
280
266
  .collect::<Vec<_>>();
267
+ debug!(target: "middleware::proxy", "backends: {:?}", backends);
281
268
 
282
269
  self.client
283
270
  .set(
@@ -314,14 +301,20 @@ impl MiddlewareLayer for Proxy {
314
301
  context: &mut HttpRequestContext,
315
302
  ) -> Result<Either<HttpRequest, HttpResponse>> {
316
303
  let url = self.to.rewrite_request(&req, context);
304
+
317
305
  let accept: ResponseFormat = req.accept().into();
318
306
  let error_response = self.error_response.to_http_response(accept.clone()).await;
319
307
 
320
308
  let destination = match Url::parse(&url) {
321
309
  Ok(dest) => dest,
322
- Err(_) => return Ok(Either::Right(error_response)),
310
+ Err(_) => {
311
+ debug!(target: "middleware::proxy", "Failed to parse URL: {}", url);
312
+ return Ok(Either::Right(error_response));
313
+ }
323
314
  };
324
315
 
316
+ debug!(target: "middleware::proxy", "Proxying to: {:?}", destination);
317
+
325
318
  // Clone the headers before consuming the request.
326
319
  let req_headers = req.headers().clone();
327
320
  let host_str = destination.host_str().unwrap_or_else(|| {
@@ -331,6 +324,7 @@ impl MiddlewareLayer for Proxy {
331
324
  .unwrap_or("")
332
325
  });
333
326
 
327
+ info!("Extracted host str is {}", host_str);
334
328
  let req_info = RequestInfo {
335
329
  method: req.method().clone(),
336
330
  headers: req_headers.clone(),
@@ -373,6 +367,8 @@ impl MiddlewareLayer for Proxy {
373
367
 
374
368
  let response = match reqwest_response_result {
375
369
  Ok(response) => {
370
+ debug!(target: "middleware::proxy", "Response {} received", response.status());
371
+
376
372
  let status = response.status();
377
373
  let mut builder = Response::builder().status(status);
378
374
  for (hn, hv) in response.headers() {
@@ -387,6 +383,7 @@ impl MiddlewareLayer for Proxy {
387
383
  response.unwrap_or(error_response)
388
384
  }
389
385
  Err(e) => {
386
+ debug!(target: "middleware::proxy", "Error {:?} received", e);
390
387
  if let Some(inner) = e.source() {
391
388
  if inner.downcast_ref::<MaxBodySizeReached>().is_some() {
392
389
  let mut max_body_response = Response::new(BoxBody::new(Empty::new()));