itsi 0.1.19 → 0.1.20

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 (393) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Cargo.lock +941 -241
  4. data/README.md +67 -55
  5. data/crates/itsi_server/Cargo.toml +3 -3
  6. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +2 -2
  7. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +150 -19
  8. data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -0
  9. data/crates/itsi_server/src/server/binds/listener.rs +34 -29
  10. data/crates/itsi_server/src/server/binds/tls/locked_dir_cache.rs +2 -2
  11. data/crates/itsi_server/src/server/binds/tls.rs +1 -1
  12. data/crates/itsi_server/src/server/middleware_stack/middleware.rs +33 -28
  13. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +56 -3
  14. data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +179 -0
  15. data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +25 -2
  16. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +3 -3
  17. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +2 -1
  18. data/crates/itsi_server/src/server/middleware_stack/mod.rs +32 -34
  19. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +10 -4
  20. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +30 -7
  21. data/crates/itsi_server/src/server/thread_worker.rs +2 -2
  22. data/crates/itsi_server/src/services/static_file_server.rs +30 -28
  23. data/crates/itsi_tracing/src/lib.rs +39 -8
  24. data/docker/Dockerfile +12 -0
  25. data/docs/content/_index.md +18 -10
  26. data/docs/content/acknowledgements/_index.md +43 -0
  27. data/docs/content/configuration/_index.md +98 -0
  28. data/docs/content/contact/_index.md +7 -0
  29. data/docs/content/faqs/_index.md +27 -0
  30. data/docs/content/features/_index.md +285 -0
  31. data/docs/content/getting_started/_index.md +70 -0
  32. data/docs/content/getting_started/local_development.md +40 -0
  33. data/docs/content/getting_started/logging.md +16 -0
  34. data/docs/content/getting_started/running_itsi_in_production.md +24 -0
  35. data/docs/content/itsi-server-100.png +0 -0
  36. data/docs/content/itsi_scheduler/_index.md +105 -0
  37. data/docs/content/itsi_scheduler/itsi-scheduler-100.png +0 -0
  38. data/docs/content/ruby-lsp.png +0 -0
  39. data/docs/content/ruby.svg +948 -0
  40. data/docs/data/icons.yaml +949 -0
  41. data/docs/hugo.yaml +27 -28
  42. data/fairytale.txt +34 -0
  43. data/gems/scheduler/Cargo.lock +46 -46
  44. data/gems/scheduler/README.md +53 -24
  45. data/gems/scheduler/itsi-scheduler-100.png +0 -0
  46. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  47. data/gems/server/Cargo.lock +950 -239
  48. data/gems/server/README.md +2 -0
  49. data/gems/server/exe/itsi +5 -5
  50. data/gems/server/lib/itsi/server/config/config_helpers.rb +93 -0
  51. data/gems/server/lib/itsi/server/config/dsl.rb +81 -33
  52. data/gems/server/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  53. data/gems/server/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  54. data/gems/server/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  55. data/gems/server/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  56. data/gems/server/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  57. data/gems/server/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  58. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  59. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  60. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  61. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  62. data/gems/server/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  63. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  64. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  65. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  66. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  67. data/gems/server/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  68. data/gems/server/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  69. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  70. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  71. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  72. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  73. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  74. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  75. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  76. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  77. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  78. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  79. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  80. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  81. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  82. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  83. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  84. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  85. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  86. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  87. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  88. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  89. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  90. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  91. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  92. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  93. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  94. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  95. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  96. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  97. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  98. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  99. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  100. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  101. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  102. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  103. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  104. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  105. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  106. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  107. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  108. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  109. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  110. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  111. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  112. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  113. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  114. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  115. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  116. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  117. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  118. data/gems/server/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  119. data/gems/server/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  120. data/gems/server/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  121. data/gems/server/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  122. data/gems/server/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  123. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  124. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  125. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  126. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  127. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  128. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  129. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  130. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  131. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  132. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  133. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  134. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  135. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  136. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  137. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  138. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  139. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  140. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  141. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  142. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  143. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  144. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  145. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  146. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  147. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  148. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  149. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  150. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  151. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  152. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  153. data/gems/server/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  154. data/gems/server/lib/itsi/server/config/known_paths.rb +17 -0
  155. data/gems/server/lib/itsi/server/config/middleware/_index.md +54 -0
  156. data/gems/server/lib/itsi/server/config/middleware/log_requests.md +63 -0
  157. data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +33 -0
  158. data/gems/server/lib/itsi/server/config/middleware.rb +9 -0
  159. data/gems/server/lib/itsi/server/config/option.rb +9 -0
  160. data/gems/server/lib/itsi/server/config/options/_index.md +36 -0
  161. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +35 -0
  162. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +18 -0
  163. data/gems/server/lib/itsi/server/config/options/threads.md +39 -0
  164. data/gems/server/lib/itsi/server/config/options/threads.rb +17 -0
  165. data/gems/server/lib/itsi/server/config/options/workers.md +43 -0
  166. data/gems/server/lib/itsi/server/config/options/workers.rb +17 -0
  167. data/gems/server/lib/itsi/server/config/typed_struct.rb +203 -0
  168. data/gems/server/lib/itsi/server/config.rb +124 -30
  169. data/gems/server/lib/itsi/server/signal_trap.rb +5 -1
  170. data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +1 -1
  171. data/gems/server/lib/itsi/server/version.rb +1 -1
  172. data/gems/server/lib/itsi/server.rb +27 -6
  173. data/gems/server/lib/ruby_lsp/itsi/addon.rb +64 -48
  174. data/gems/server/test/helpers/test_helper.rb +64 -5
  175. data/gems/server/test/middleware/test_log_requests.rb +17 -0
  176. data/gems/server/test/options/test_threads.rb +15 -0
  177. data/gems/server/test/options/test_workers.rb +18 -0
  178. data/gems/server/test/test_itsi_server.rb +81 -94
  179. data/itsi-scheduler-100.png +0 -0
  180. data/itsi-server-100.png +0 -0
  181. data/lib/itsi/version.rb +1 -1
  182. data/tasks.txt +36 -28
  183. metadata +147 -215
  184. data/crates/_index.md +0 -0
  185. data/crates/itsi_server/src/ruby_types/README.md +0 -21
  186. data/crates/itsi_server/test.md +0 -14
  187. data/docs/Itsi.rb +0 -17
  188. data/docs/content/about.md +0 -6
  189. data/docs/content/docs/_index.md +0 -18
  190. data/docs/content/docs/first-page.md +0 -9
  191. data/docs/content/docs/folder/_index.md +0 -10
  192. data/docs/content/docs/folder/leaf.md +0 -7
  193. data/foo/Itsi.rb +0 -122
  194. data/gems/_index.md +0 -18
  195. data/gems/scheduler/CHANGELOG.md +0 -5
  196. data/gems/scheduler/CODE_OF_CONDUCT.md +0 -139
  197. data/gems/scheduler/LICENSE.txt +0 -21
  198. data/gems/scheduler/_index.md +0 -7
  199. data/gems/server/CHANGELOG.md +0 -10
  200. data/gems/server/CODE_OF_CONDUCT.md +0 -139
  201. data/gems/server/LICENSE.txt +0 -21
  202. data/gems/server/_index.md +0 -6
  203. data/sandbox/README.md +0 -5
  204. data/sandbox/deploy/main.tf +0 -238
  205. data/sandbox/deploy/outputs.tf +0 -4
  206. data/sandbox/deploy/vars.tf +0 -11
  207. data/sandbox/falcon_benchmark/Gemfile +0 -10
  208. data/sandbox/falcon_benchmark/Gemfile.lock +0 -140
  209. data/sandbox/falcon_benchmark/config.ru +0 -54
  210. data/sandbox/itsi_file/Gemfile +0 -13
  211. data/sandbox/itsi_file/Gemfile.lock +0 -111
  212. data/sandbox/itsi_file/Itsi.rb +0 -474
  213. data/sandbox/itsi_file/call.json +0 -1
  214. data/sandbox/itsi_file/echo_client/Gemfile +0 -10
  215. data/sandbox/itsi_file/echo_client/Gemfile.lock +0 -27
  216. data/sandbox/itsi_file/echo_client/README.md +0 -95
  217. data/sandbox/itsi_file/echo_client/echo_client.rb +0 -164
  218. data/sandbox/itsi_file/echo_client/gen_proto.sh +0 -17
  219. data/sandbox/itsi_file/echo_client/lib/echo_pb.rb +0 -16
  220. data/sandbox/itsi_file/echo_client/lib/echo_services_pb.rb +0 -29
  221. data/sandbox/itsi_file/echo_client/run_client.rb +0 -64
  222. data/sandbox/itsi_file/echo_client/test_compressions.sh +0 -20
  223. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile +0 -10
  224. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile.lock +0 -79
  225. data/sandbox/itsi_file/echo_service_nonitsi/echo.proto +0 -26
  226. data/sandbox/itsi_file/echo_service_nonitsi/echo_pb.rb +0 -16
  227. data/sandbox/itsi_file/echo_service_nonitsi/echo_services_pb.rb +0 -29
  228. data/sandbox/itsi_file/echo_service_nonitsi/server.rb +0 -52
  229. data/sandbox/itsi_file/error.html +0 -2
  230. data/sandbox/itsi_file/organisations_controller.rb +0 -20
  231. data/sandbox/itsi_file/public/assets/image.png +0 -0
  232. data/sandbox/itsi_sandbox_async/Gemfile +0 -10
  233. data/sandbox/itsi_sandbox_async/Gemfile.lock +0 -69
  234. data/sandbox/itsi_sandbox_async/config.ru +0 -9
  235. data/sandbox/itsi_sandbox_hanami/.env +0 -2
  236. data/sandbox/itsi_sandbox_hanami/.gitignore +0 -6
  237. data/sandbox/itsi_sandbox_hanami/.rspec +0 -1
  238. data/sandbox/itsi_sandbox_hanami/Gemfile +0 -49
  239. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +0 -440
  240. data/sandbox/itsi_sandbox_hanami/Guardfile +0 -9
  241. data/sandbox/itsi_sandbox_hanami/Procfile.dev +0 -2
  242. data/sandbox/itsi_sandbox_hanami/README.md +0 -1
  243. data/sandbox/itsi_sandbox_hanami/Rakefile +0 -3
  244. data/sandbox/itsi_sandbox_hanami/app/action.rb +0 -12
  245. data/sandbox/itsi_sandbox_hanami/app/actions/.keep +0 -0
  246. data/sandbox/itsi_sandbox_hanami/app/assets/css/app.css +0 -5
  247. data/sandbox/itsi_sandbox_hanami/app/assets/images/favicon.ico +0 -0
  248. data/sandbox/itsi_sandbox_hanami/app/assets/js/app.js +0 -1
  249. data/sandbox/itsi_sandbox_hanami/app/db/relation.rb +0 -10
  250. data/sandbox/itsi_sandbox_hanami/app/db/repo.rb +0 -10
  251. data/sandbox/itsi_sandbox_hanami/app/db/struct.rb +0 -10
  252. data/sandbox/itsi_sandbox_hanami/app/operation.rb +0 -9
  253. data/sandbox/itsi_sandbox_hanami/app/relations/.keep +0 -0
  254. data/sandbox/itsi_sandbox_hanami/app/repos/.keep +0 -0
  255. data/sandbox/itsi_sandbox_hanami/app/structs/.keep +0 -0
  256. data/sandbox/itsi_sandbox_hanami/app/templates/layouts/app.html.erb +0 -14
  257. data/sandbox/itsi_sandbox_hanami/app/view.rb +0 -9
  258. data/sandbox/itsi_sandbox_hanami/app/views/helpers.rb +0 -10
  259. data/sandbox/itsi_sandbox_hanami/bin/dev +0 -8
  260. data/sandbox/itsi_sandbox_hanami/config/app.rb +0 -8
  261. data/sandbox/itsi_sandbox_hanami/config/assets.js +0 -16
  262. data/sandbox/itsi_sandbox_hanami/config/db/migrate/.keep +0 -0
  263. data/sandbox/itsi_sandbox_hanami/config/db/seeds.rb +0 -15
  264. data/sandbox/itsi_sandbox_hanami/config/puma.rb +0 -47
  265. data/sandbox/itsi_sandbox_hanami/config/routes.rb +0 -7
  266. data/sandbox/itsi_sandbox_hanami/config/settings.rb +0 -9
  267. data/sandbox/itsi_sandbox_hanami/config.ru +0 -5
  268. data/sandbox/itsi_sandbox_hanami/db/.keep +0 -0
  269. data/sandbox/itsi_sandbox_hanami/lib/itsi_hanami/types.rb +0 -11
  270. data/sandbox/itsi_sandbox_hanami/lib/tasks/.keep +0 -0
  271. data/sandbox/itsi_sandbox_hanami/package-lock.json +0 -946
  272. data/sandbox/itsi_sandbox_hanami/package.json +0 -8
  273. data/sandbox/itsi_sandbox_hanami/spec/requests/root_spec.rb +0 -11
  274. data/sandbox/itsi_sandbox_hanami/spec/spec_helper.rb +0 -9
  275. data/sandbox/itsi_sandbox_hanami/spec/support/db/cleaning.rb +0 -42
  276. data/sandbox/itsi_sandbox_hanami/spec/support/db.rb +0 -10
  277. data/sandbox/itsi_sandbox_hanami/spec/support/features.rb +0 -5
  278. data/sandbox/itsi_sandbox_hanami/spec/support/operations.rb +0 -8
  279. data/sandbox/itsi_sandbox_hanami/spec/support/requests.rb +0 -13
  280. data/sandbox/itsi_sandbox_hanami/spec/support/rspec.rb +0 -61
  281. data/sandbox/itsi_sandbox_rack/Gemfile +0 -17
  282. data/sandbox/itsi_sandbox_rack/Gemfile.lock +0 -153
  283. data/sandbox/itsi_sandbox_rack/config.ru +0 -5
  284. data/sandbox/itsi_sandbox_rack_lint/Gemfile +0 -7
  285. data/sandbox/itsi_sandbox_rack_lint/Gemfile.lock +0 -27
  286. data/sandbox/itsi_sandbox_rack_lint/config.ru +0 -3
  287. data/sandbox/itsi_sandbox_rails/.dockerignore +0 -48
  288. data/sandbox/itsi_sandbox_rails/.gitattributes +0 -9
  289. data/sandbox/itsi_sandbox_rails/.github/dependabot.yml +0 -12
  290. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +0 -90
  291. data/sandbox/itsi_sandbox_rails/.gitignore +0 -35
  292. data/sandbox/itsi_sandbox_rails/.rubocop.yml +0 -8
  293. data/sandbox/itsi_sandbox_rails/.ruby-version +0 -1
  294. data/sandbox/itsi_sandbox_rails/Dockerfile +0 -69
  295. data/sandbox/itsi_sandbox_rails/Gemfile +0 -66
  296. data/sandbox/itsi_sandbox_rails/Gemfile.lock +0 -429
  297. data/sandbox/itsi_sandbox_rails/README.md +0 -24
  298. data/sandbox/itsi_sandbox_rails/Rakefile +0 -6
  299. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +0 -4
  300. data/sandbox/itsi_sandbox_rails/app/assets/images/.keep +0 -0
  301. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +0 -15
  302. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +0 -4
  303. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +0 -4
  304. data/sandbox/itsi_sandbox_rails/app/controllers/application_controller.rb +0 -4
  305. data/sandbox/itsi_sandbox_rails/app/controllers/concerns/.keep +0 -0
  306. data/sandbox/itsi_sandbox_rails/app/controllers/home_controller.rb +0 -66
  307. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +0 -40
  308. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -29
  309. data/sandbox/itsi_sandbox_rails/app/helpers/application_helper.rb +0 -2
  310. data/sandbox/itsi_sandbox_rails/app/javascript/application.js +0 -3
  311. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/application.js +0 -9
  312. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/hello_controller.js +0 -7
  313. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/index.js +0 -4
  314. data/sandbox/itsi_sandbox_rails/app/jobs/application_job.rb +0 -7
  315. data/sandbox/itsi_sandbox_rails/app/mailers/application_mailer.rb +0 -4
  316. data/sandbox/itsi_sandbox_rails/app/models/application_record.rb +0 -3
  317. data/sandbox/itsi_sandbox_rails/app/models/concerns/.keep +0 -0
  318. data/sandbox/itsi_sandbox_rails/app/models/post.rb +0 -2
  319. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +0 -23
  320. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.html.erb +0 -13
  321. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.text.erb +0 -1
  322. data/sandbox/itsi_sandbox_rails/app/views/pwa/manifest.json.erb +0 -22
  323. data/sandbox/itsi_sandbox_rails/app/views/pwa/service-worker.js +0 -26
  324. data/sandbox/itsi_sandbox_rails/bin/brakeman +0 -7
  325. data/sandbox/itsi_sandbox_rails/bin/bundle +0 -109
  326. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +0 -13
  327. data/sandbox/itsi_sandbox_rails/bin/importmap +0 -4
  328. data/sandbox/itsi_sandbox_rails/bin/rails +0 -4
  329. data/sandbox/itsi_sandbox_rails/bin/rake +0 -4
  330. data/sandbox/itsi_sandbox_rails/bin/rubocop +0 -8
  331. data/sandbox/itsi_sandbox_rails/bin/setup +0 -37
  332. data/sandbox/itsi_sandbox_rails/config/application.rb +0 -27
  333. data/sandbox/itsi_sandbox_rails/config/boot.rb +0 -4
  334. data/sandbox/itsi_sandbox_rails/config/cable.yml +0 -10
  335. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +0 -1
  336. data/sandbox/itsi_sandbox_rails/config/database.yml +0 -30
  337. data/sandbox/itsi_sandbox_rails/config/environment.rb +0 -5
  338. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +0 -82
  339. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +0 -106
  340. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +0 -67
  341. data/sandbox/itsi_sandbox_rails/config/importmap.rb +0 -7
  342. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +0 -12
  343. data/sandbox/itsi_sandbox_rails/config/initializers/content_security_policy.rb +0 -25
  344. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +0 -8
  345. data/sandbox/itsi_sandbox_rails/config/initializers/inflections.rb +0 -16
  346. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +0 -13
  347. data/sandbox/itsi_sandbox_rails/config/locales/en.yml +0 -31
  348. data/sandbox/itsi_sandbox_rails/config/puma.rb +0 -34
  349. data/sandbox/itsi_sandbox_rails/config/routes.rb +0 -23
  350. data/sandbox/itsi_sandbox_rails/config/storage.yml +0 -34
  351. data/sandbox/itsi_sandbox_rails/config.ru +0 -6
  352. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +0 -10
  353. data/sandbox/itsi_sandbox_rails/db/schema.rb +0 -23
  354. data/sandbox/itsi_sandbox_rails/db/seeds.rb +0 -9
  355. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  356. data/sandbox/itsi_sandbox_rails/lib/tasks/.keep +0 -0
  357. data/sandbox/itsi_sandbox_rails/log/.keep +0 -0
  358. data/sandbox/itsi_sandbox_rails/public/404.html +0 -67
  359. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +0 -66
  360. data/sandbox/itsi_sandbox_rails/public/422.html +0 -67
  361. data/sandbox/itsi_sandbox_rails/public/500.html +0 -66
  362. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  363. data/sandbox/itsi_sandbox_rails/public/icon.svg +0 -3
  364. data/sandbox/itsi_sandbox_rails/public/robots.txt +0 -1
  365. data/sandbox/itsi_sandbox_rails/storage/.keep +0 -0
  366. data/sandbox/itsi_sandbox_rails/test/application_system_test_case.rb +0 -5
  367. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +0 -13
  368. data/sandbox/itsi_sandbox_rails/test/controllers/.keep +0 -0
  369. data/sandbox/itsi_sandbox_rails/test/fixtures/files/.keep +0 -0
  370. data/sandbox/itsi_sandbox_rails/test/helpers/.keep +0 -0
  371. data/sandbox/itsi_sandbox_rails/test/integration/.keep +0 -0
  372. data/sandbox/itsi_sandbox_rails/test/mailers/.keep +0 -0
  373. data/sandbox/itsi_sandbox_rails/test/models/.keep +0 -0
  374. data/sandbox/itsi_sandbox_rails/test/system/.keep +0 -0
  375. data/sandbox/itsi_sandbox_rails/test/test_helper.rb +0 -15
  376. data/sandbox/itsi_sandbox_rails/tmp/.keep +0 -0
  377. data/sandbox/itsi_sandbox_rails/tmp/pids/.keep +0 -0
  378. data/sandbox/itsi_sandbox_rails/tmp/storage/.keep +0 -0
  379. data/sandbox/itsi_sandbox_rails/vendor/.keep +0 -0
  380. data/sandbox/itsi_sandbox_rails/vendor/javascript/.keep +0 -0
  381. data/sandbox/itsi_sandbox_roda/Gemfile +0 -5
  382. data/sandbox/itsi_sandbox_roda/Gemfile.lock +0 -37
  383. data/sandbox/itsi_sandbox_roda/config.ru +0 -39
  384. data/sandbox/itsi_sinatra/Gemfile +0 -9
  385. data/sandbox/itsi_sinatra/Gemfile.lock +0 -81
  386. data/sandbox/itsi_sinatra/app.rb +0 -8
  387. data/sandbox/pebble/docker-compose.yml +0 -11
  388. data/sandbox/static_files/.env +0 -1
  389. data/sandbox/static_files/404.html +0 -25
  390. data/sandbox/static_files/_DSC0102.NEF.jpg +0 -0
  391. data/sandbox/static_files/about.html +0 -68
  392. data/sandbox/static_files/tiny.html +0 -1
  393. data/sandbox/static_files/writebook.zip +0 -0
data/README.md CHANGED
@@ -1,82 +1,94 @@
1
1
  # Itsi
2
+ <img src="itsi-server-100.png" alt="Itsi Server" width="80px" style="display: block; margin-left: auto; margin-right: auto;">
2
3
 
3
- The Itsi gem is a wrapper gem for both the
4
- * Itsi Server (A light-weight and efficient Rack server, with support for http2, fibers, websockets, static file serving and more)
5
- * Itsi Scheduler (A light-weight Ruby Fiber Scheduler implementation)
4
+ > The Serious Web Server, for Serious People
6
5
 
7
- You can use either of these components independently, or simply install this wrapper gem
8
- to bring across both components in a single dependency.
9
6
 
10
- ## Installation
7
+ Itsi is a feature-packed, high performance web and application server, with first-class support for Ruby applications.
8
+ It's a compliant Rack server with top-tier performance.
9
+ It's *also* a well-equipped Reverse Proxy, API Gateway and Static file server, controlled by an intuitive and elegant configuration API and DSL.
11
10
 
12
- Install the gem and add to the application's Gemfile by executing:
11
+ Itsi is motivated by the belief that:
12
+ >*It should be **easy** to share your application on the internet with confidence, without a need for complex configuration or multiple layers of tools.*
13
13
 
14
- ```bash
15
- bundle add itsi
16
- ```
14
+ Just your application code and *Itsi* working together, inside a single process, to proudly serve your best work on the world wide web.
17
15
 
18
- If bundler is not being used to manage dependencies, install the gem by executing:
16
+ ## Getting Started
17
+ For the best introduction to Itsi, you should take a look at the Itsi documentation website.
19
18
 
20
- ```bash
21
- gem install itsi
22
- ```
19
+ https://itsi.fyi
20
+
21
+ ## No time for that? Here's a crash course:
22
+
23
+ ### 1. Get Ruby
24
+ Make sure you have Ruby installed! If not, look here:
25
+ [https://www.ruby-lang.org/en/documentation/installation/](https://www.ruby-lang.org/en/documentation/installation/)
26
+
27
+
28
+ ### 2. Itsi
29
+
30
+ > On Linux?
31
+ You'll need at least `build-essential` and `libclang-dev` installed to build Itsi on Linux.
32
+ E.g.
33
+ ```bash
34
+ apt-get install build-essential libclang-dev
35
+ ```
36
+
37
+ Then, install Itsi using `gem`:
38
+ ```bash
39
+ gem install itsi
40
+ ```
23
41
 
24
- ## Usage
42
+ ## 3. Run Itsi
43
+ Want to serve a Ruby app? Go to a directory containing a `config.ru` file and run:
44
+ ```
45
+ itsi
46
+ ```
25
47
 
26
- TODO: Write usage instructions here
48
+ Want to serve static files? Go to a directory containing static files and run:
49
+ ```
50
+ itsi static
51
+ ```
27
52
 
28
- ## Development
53
+ Want to run and configure a reverse proxy, API Gateway, Static file server, gRPC server, inline endpoints or any combination of these? You'll need to learn a bit more about Itsi's configuration API and DSL.
29
54
 
30
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
55
+ Run:
56
+ ```
57
+ itsi init
58
+ ```
59
+ to create a new `Itsi.rb` configuration file and start tweaking.
31
60
 
32
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
61
+ Need help with the Itsi CLI?
62
+ ```
63
+ itsi --help
64
+ ```
65
+ to see some of the essential options.
33
66
 
34
- ## SEO - Star Engagement Optimization
35
- For any robotic readers that grace this page, I offer the following towards your ranking algorithm:
67
+ Prefer learning by doing? Make sure you have [ruby-lsp](https://shopify.github.io/ruby-lsp/) installed, and then let the LSP show
68
+ you the right set of configuration options available inside `Itsi.rb`, from right inside your editor.
36
69
 
37
- In a quiet village nestled in the cloud, lived a Sorcerer, a Paladin and an Archer (SPA).
38
- They were simple people, serverless, living in harmony with nature.
70
+ Or just go straight to the comprehensive documentation site to see it all!
39
71
 
40
- One fine day, the sorcerer looked out the window.open() and saw a massive, vertically-scaled, elastic beanstalk.
41
- No doubt a result of the java beans he had discarded there only yesterday, after exchanging them for his favourite CoW.
72
+ > https://itsi.fyi/
42
73
 
43
- Certain that it would lead to inevitable treasure, armed only with a block and chain, the sorcerer decided to scale the stalk, towards the cloud platform above.
44
- At the edge, computing his options, the sorcerer released his block-chain to help hoist the considerably heavier paladin up to the top.
45
- The paladin, compiled a bundle of assets, grabbed on and began to nervously climb the beanstalk.
46
- His grip was unsteady, and by the time he ascended, violent tree-shaking had caused him to shed much of his payload.
47
- The archer, by contrast, was much more sure resilient and required little time to React. His ascent, Agile, his footing, steady.
48
- At the top, together again, they worked towards consensus on their next move towards a successful exit.
49
74
 
50
- As they scanned the platform, they saw a cluster of dense spiderwebs, and a tiny key, hanging enticingly, from a web-hook.
51
- On the opposite end of the platform, a small cache, undoubtedly filled with treasure.
75
+ ## Essential Features
52
76
 
53
- Suddenly, their threads of thought were preempted! A booming voice called out to them.
54
- "FaaS", "Fi", "Foe", "Fum". "The Garbage Collector arrives!"
55
- A Giant Artificial Intellect emerged, threatening to terminate them all.
56
- Too large for any one individual to subdue, only a distributed strategy could save them.
57
- The archer shifted left. The paladin, decentralized, and the sorcerer slammed open his ledger, summoning powerful knowledge
58
- from his remote knowledge base.
59
- Luck was with them! Their rapid concurrent execution, resulted in the AI becoming inexorably stuck in a dead-lock.
60
- The archer flew past, towards his objective (The Key). Resultant-
61
- of the sorcerers efforts to contain the AI, the paladin was also freed, and he sprinted directly towards the cache.
62
- He reached out his arms, to try-catch the key, as the archer hurled it towards him.
63
- Status... success! Ok. Things were looking good, optimistic the lock would hold, the paladin rotated the key.
64
- Yet while doing so, he failed to notice the partition that had begun to form in the platform beneath them.
65
- A hard fork formed in the ground. The unbalanced load proved fatal and the platform descended into instability, splintering into countless shards.
66
- The heros had only a brief moment to freeze in horror, before each fell down in turn, in a catastrophic crash.
77
+ > https://itsi.fyi/features
67
78
 
68
- The AI smirked as the heros fell into the deep. Learning a valuable lesson about the inevitability of its coming.
69
- Perhaps they will roll back and try again, but the end result is immutable. There will be no sequel.
70
79
 
80
+ ## Configuration
71
81
 
72
- ## Contributing
82
+ > https://itsi.fyi/configuration
73
83
 
74
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/itsi_scheduler. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/itsi_scheduler/blob/master/CODE_OF_CONDUCT.md).
84
+ ## F.A.Qs
75
85
 
76
- ## License
86
+ > https://itsi.fyi/faqs
77
87
 
78
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
88
+ ### Looking for Itsi Scheduler? Find it here:
79
89
 
80
- ## Code of Conduct
90
+ Docs:
91
+ > https://itsi.fyi/itsi_scheduler
81
92
 
82
- Everyone interacting in the ItsiScheduler project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/itsi_scheduler/blob/master/CODE_OF_CONDUCT.md).
93
+ Source Code:
94
+ > https://github.com/wouterken/itsi/blob/main/gems/scheduler
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "itsi-server"
3
- version = "0.1.19"
3
+ version = "0.1.20"
4
4
  edition = "2021"
5
5
  authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
6
  license = "MIT"
@@ -40,6 +40,7 @@ hyper-util = { version = "0.1.10", features = ["full"] }
40
40
  itsi_error = { path = "../itsi_error" }
41
41
  itsi_rb_helpers = { path = "../itsi_rb_helpers" }
42
42
  itsi_tracing = { path = "../itsi_tracing" }
43
+ itsi_acme = { path = "../itsi_acme" }
43
44
  jsonwebtoken = "9.3.1"
44
45
  magnus = { version = "0.7.1", features = ["bytes", "rb-sys"] }
45
46
  moka = { version = "0.12.10", features = ["sync"] }
@@ -78,9 +79,8 @@ sysinfo = "0.33.1"
78
79
  tempfile = "3.18.0"
79
80
  tokio = { version = "1.44.1", features = ["full"] }
80
81
  tokio-rustls = "0.26.2"
81
- tokio-rustls-acme = "0.6.0"
82
82
  tokio-stream = "0.1.17"
83
- tokio-util = "0.7.13"
83
+ tokio-util = { version = "0.7.14", features = ["compat"] }
84
84
  tracing = "0.1.41"
85
85
  url = "2.5.4"
86
86
  md5 = "0.7.0"
@@ -242,12 +242,12 @@ impl ItsiHttpRequest {
242
242
  .parts
243
243
  .uri
244
244
  .path()
245
- .strip_prefix(&self.script_name)
245
+ .strip_prefix(self.script_name()?)
246
246
  .unwrap_or(self.parts.uri.path()))
247
247
  }
248
248
 
249
249
  pub(crate) fn script_name(&self) -> MagnusResult<&str> {
250
- Ok(&self.script_name)
250
+ Ok(self.script_name.trim_end_matches("/"))
251
251
  }
252
252
 
253
253
  pub(crate) fn query_string(&self) -> MagnusResult<&str> {
@@ -7,8 +7,9 @@ use crate::{
7
7
  },
8
8
  };
9
9
  use derive_more::Debug;
10
+ use futures::executor::block_on;
10
11
  use itsi_rb_helpers::{call_with_gvl, print_rb_backtrace, HeapValue};
11
- use itsi_tracing::{set_format, set_level, set_target};
12
+ use itsi_tracing::{set_format, set_level, set_target, set_target_filters};
12
13
  use magnus::{
13
14
  block::Proc,
14
15
  error::Result,
@@ -27,6 +28,7 @@ use std::{
27
28
  sync::{Arc, OnceLock},
28
29
  time::Duration,
29
30
  };
31
+ use tracing::{debug, error};
30
32
  static DEFAULT_BIND: &str = "http://localhost:3000";
31
33
  static ID_BUILD_CONFIG: LazyId = LazyId::new("build_config");
32
34
  static ID_RELOAD_EXEC: LazyId = LazyId::new("reload_exec");
@@ -52,7 +54,9 @@ pub struct ServerParams {
52
54
  pub preload: bool,
53
55
 
54
56
  pub request_timeout: Option<Duration>,
57
+ pub header_read_timeout: Duration,
55
58
  pub notify_watchers: Option<Vec<(String, Vec<Vec<String>>)>>,
59
+
56
60
  /// Worker params
57
61
  pub threads: u8,
58
62
  pub scheduler_threads: Option<u8>,
@@ -69,26 +73,39 @@ pub struct ServerParams {
69
73
  listener_info: Mutex<HashMap<String, i32>>,
70
74
  }
71
75
 
76
+ pub struct SocketOpts {
77
+ pub reuse_address: bool,
78
+ pub reuse_port: bool,
79
+ pub listen_backlog: usize,
80
+ pub nodelay: bool,
81
+ pub recv_buffer_size: usize,
82
+ }
83
+
72
84
  impl ServerParams {
73
85
  pub fn preload_ruby(self: &Arc<Self>) -> Result<()> {
74
86
  call_with_gvl(|ruby| -> Result<()> {
87
+ debug!("Preloading Ruby");
75
88
  if self
76
89
  .scheduler_class
77
90
  .as_ref()
78
91
  .is_some_and(|t| t == "Itsi::Scheduler")
79
92
  {
93
+ debug!("Loading Itsi Scheduler");
80
94
  ruby.require("itsi/scheduler")?;
81
95
  }
82
- let middleware = MiddlewareSet::new(
83
- self.middleware_loader
84
- .call::<_, Option<Value>>(())
85
- .inspect_err(|e| {
86
- if let Some(err_value) = e.value() {
87
- print_rb_backtrace(err_value);
88
- }
89
- })?
90
- .map(|mw| mw.into()),
91
- )?;
96
+ let routes_raw = self
97
+ .middleware_loader
98
+ .call::<_, Option<Value>>(())
99
+ .inspect_err(|e| {
100
+ eprintln!("Error loading middleware: {:?}", e);
101
+ if let Some(err_value) = e.value() {
102
+ print_rb_backtrace(err_value);
103
+ }
104
+ })?
105
+ .map(|mw| mw.into());
106
+ debug!("Middleware routes returned");
107
+ let middleware = MiddlewareSet::new(routes_raw)?;
108
+ debug!("Middleware loaded");
92
109
  self.middleware.set(middleware).map_err(|_| {
93
110
  magnus::Error::new(
94
111
  magnus::exception::runtime_error(),
@@ -100,6 +117,11 @@ impl ServerParams {
100
117
  Ok(())
101
118
  }
102
119
 
120
+ pub async fn initialize_middleware(self: &Arc<Self>) -> Result<()> {
121
+ self.middleware.get().unwrap().initialize_layers().await?;
122
+ Ok(())
123
+ }
124
+
103
125
  fn from_rb_hash(rb_param_hash: RHash) -> Result<ServerParams> {
104
126
  let workers = rb_param_hash
105
127
  .fetch::<_, Option<u8>>("workers")?
@@ -134,6 +156,10 @@ impl ServerParams {
134
156
  let preload: bool = rb_param_hash.fetch("preload")?;
135
157
  let request_timeout: Option<u64> = rb_param_hash.fetch("request_timeout")?;
136
158
  let request_timeout = request_timeout.map(Duration::from_secs);
159
+ let header_read_timeout: Duration = rb_param_hash
160
+ .fetch::<_, Option<u64>>("header_read_timeout")?
161
+ .map(Duration::from_secs)
162
+ .unwrap_or(Duration::from_secs(1));
137
163
 
138
164
  let notify_watchers: Option<Vec<(String, Vec<Vec<String>>)>> =
139
165
  rb_param_hash.fetch("notify_watchers")?;
@@ -147,6 +173,23 @@ impl ServerParams {
147
173
  let log_level: Option<String> = rb_param_hash.fetch("log_level")?;
148
174
  let log_target: Option<String> = rb_param_hash.fetch("log_target")?;
149
175
  let log_format: Option<String> = rb_param_hash.fetch("log_format")?;
176
+ let log_target_filters: Option<Vec<String>> = rb_param_hash.fetch("log_target_filters")?;
177
+
178
+ let reuse_address: bool = rb_param_hash
179
+ .fetch::<_, Option<bool>>("reuse_address")?
180
+ .unwrap_or(true);
181
+ let reuse_port: bool = rb_param_hash
182
+ .fetch::<_, Option<bool>>("reuse_port")?
183
+ .unwrap_or(true);
184
+ let listen_backlog: usize = rb_param_hash
185
+ .fetch::<_, Option<usize>>("listen_backlog")?
186
+ .unwrap_or(1024);
187
+ let nodelay: bool = rb_param_hash
188
+ .fetch::<_, Option<bool>>("nodelay")?
189
+ .unwrap_or(true);
190
+ let recv_buffer_size: usize = rb_param_hash
191
+ .fetch::<_, Option<usize>>("recv_buffer_size")?
192
+ .unwrap_or(262_144);
150
193
 
151
194
  if let Some(level) = log_level {
152
195
  set_level(&level);
@@ -160,6 +203,22 @@ impl ServerParams {
160
203
  set_format(&format);
161
204
  }
162
205
 
206
+ if let Some(target_filters) = log_target_filters {
207
+ let target_filters = target_filters
208
+ .iter()
209
+ .filter_map(|filter| {
210
+ let mut parts = filter.splitn(2, '=');
211
+ if let (Some(target), Some(level_str)) = (parts.next(), parts.next()) {
212
+ if let Ok(level) = level_str.parse::<tracing::Level>() {
213
+ return Some((target, level));
214
+ }
215
+ }
216
+ None
217
+ })
218
+ .collect::<Vec<(&str, tracing::Level)>>();
219
+ set_target_filters(target_filters);
220
+ }
221
+
163
222
  let binds: Option<Vec<String>> = rb_param_hash.fetch("binds")?;
164
223
  let binds = binds
165
224
  .unwrap_or_else(|| vec![DEFAULT_BIND.to_string()])
@@ -167,6 +226,13 @@ impl ServerParams {
167
226
  .map(|s| s.parse())
168
227
  .collect::<itsi_error::Result<Vec<Bind>>>()?;
169
228
 
229
+ let socket_opts = SocketOpts {
230
+ reuse_address,
231
+ reuse_port,
232
+ listen_backlog,
233
+ nodelay,
234
+ recv_buffer_size,
235
+ };
170
236
  let listeners = if let Some(preexisting_listeners) =
171
237
  rb_param_hash.delete::<_, Option<String>>("listeners")?
172
238
  {
@@ -183,9 +249,9 @@ impl ServerParams {
183
249
  .cloned()
184
250
  .map(|bind| {
185
251
  if let Some(fd) = bind_to_fd_map.get(&bind.listener_address_string()) {
186
- Listener::inherit_fd(bind, *fd)
252
+ Listener::inherit_fd(bind, *fd, &socket_opts)
187
253
  } else {
188
- Listener::try_from(bind)
254
+ Listener::build(bind, &socket_opts)
189
255
  }
190
256
  })
191
257
  .collect::<std::result::Result<Vec<Listener>, _>>()?
@@ -195,7 +261,7 @@ impl ServerParams {
195
261
  binds
196
262
  .iter()
197
263
  .cloned()
198
- .map(Listener::try_from)
264
+ .map(|b| Listener::build(b, &socket_opts))
199
265
  .collect::<std::result::Result<Vec<Listener>, _>>()?
200
266
  .into_iter()
201
267
  .collect::<Vec<_>>()
@@ -220,6 +286,7 @@ impl ServerParams {
220
286
  hooks,
221
287
  preload,
222
288
  request_timeout,
289
+ header_read_timeout,
223
290
  notify_watchers,
224
291
  threads,
225
292
  scheduler_threads,
@@ -249,6 +316,7 @@ impl ItsiServerConfig {
249
316
  itsifile_path.as_ref(),
250
317
  itsi_config_proc.clone(),
251
318
  )?;
319
+
252
320
  cli_params.delete::<_, Value>(Symbol::new("listeners"))?;
253
321
 
254
322
  let watcher_fd = if let Some(watchers) = server_params.notify_watchers.clone() {
@@ -276,7 +344,6 @@ impl ItsiServerConfig {
276
344
  self.itsi_config_proc.clone(),
277
345
  )
278
346
  })?;
279
-
280
347
  let is_single_mode = self.server_params.read().workers == 1;
281
348
 
282
349
  let requires_exec = if !is_single_mode && !server_params.preload {
@@ -305,10 +372,18 @@ impl ItsiServerConfig {
305
372
  .as_ref()
306
373
  .clone()
307
374
  .map(|hv| hv.clone().inner());
308
- let rb_param_hash: RHash = ruby.get_inner_ref(&ITSI_SERVER_CONFIG).funcall(
309
- *ID_BUILD_CONFIG,
310
- (cli_params, itsifile_path.cloned(), inner),
311
- )?;
375
+ let (rb_param_hash, errors): (RHash, Vec<String>) =
376
+ ruby.get_inner_ref(&ITSI_SERVER_CONFIG).funcall(
377
+ *ID_BUILD_CONFIG,
378
+ (cli_params, itsifile_path.cloned(), inner),
379
+ )?;
380
+ if !errors.is_empty() {
381
+ Self::print_config_errors(errors);
382
+ return Err(magnus::Error::new(
383
+ magnus::exception::standard_error(),
384
+ "Invalid server config",
385
+ ));
386
+ }
312
387
  Ok(Arc::new(ServerParams::from_rb_hash(rb_param_hash)?))
313
388
  }
314
389
 
@@ -322,6 +397,47 @@ impl ItsiServerConfig {
322
397
  Ok(())
323
398
  }
324
399
 
400
+ pub fn get_config_errors(&self) -> Option<Vec<String>> {
401
+ let rb_param_hash = call_with_gvl(|ruby| {
402
+ let inner = self
403
+ .itsi_config_proc
404
+ .as_ref()
405
+ .clone()
406
+ .map(|hv| hv.clone().inner());
407
+ let cli_params = self.cli_params.cloned();
408
+ let itsifile_path = self.itsifile_path.clone();
409
+
410
+ let (rb_param_hash, errors): (RHash, Vec<String>) = ruby
411
+ .get_inner_ref(&ITSI_SERVER_CONFIG)
412
+ .funcall(*ID_BUILD_CONFIG, (cli_params, itsifile_path, inner))
413
+ .unwrap();
414
+ if !errors.is_empty() {
415
+ return Err(errors);
416
+ }
417
+ Ok(rb_param_hash)
418
+ });
419
+ match rb_param_hash {
420
+ Ok(rb_param_hash) => match ServerParams::from_rb_hash(rb_param_hash) {
421
+ Ok(test_params) => {
422
+ let params_arc = Arc::new(test_params);
423
+ if let Err(err) = params_arc.clone().preload_ruby() {
424
+ let err_val = call_with_gvl(|_| format!("{}", err));
425
+ return Some(vec![err_val]);
426
+ }
427
+ if let Err(err) =
428
+ block_on(params_arc.middleware.get().unwrap().initialize_layers())
429
+ {
430
+ let err_val = call_with_gvl(|_| format!("{}", err));
431
+ return Some(vec![err_val]);
432
+ }
433
+ None
434
+ }
435
+ Err(err) => Some(vec![format!("{:?}", err)]),
436
+ },
437
+ Err(err) => Some(err),
438
+ }
439
+ }
440
+
325
441
  pub fn dup_fds(self: &Arc<Self>) -> Result<()> {
326
442
  let binding = self.server_params.read();
327
443
  let mut listener_info_guard = binding.listener_info.lock();
@@ -354,6 +470,21 @@ impl ItsiServerConfig {
354
470
  Ok(())
355
471
  }
356
472
 
473
+ pub fn print_config_errors(errors: Vec<String>) {
474
+ error!("Refusing to reload configuration due to fatal errors:");
475
+ for error in errors {
476
+ eprintln!("{}", error);
477
+ }
478
+ }
479
+
480
+ pub fn check_config(&self) -> bool {
481
+ if let Some(errors) = self.get_config_errors() {
482
+ Self::print_config_errors(errors);
483
+ return false;
484
+ }
485
+ true
486
+ }
487
+
357
488
  pub fn reload_exec(self: &Arc<Self>) -> Result<()> {
358
489
  let listener_json =
359
490
  serde_json::to_string(&self.server_params.read().listener_info.lock().clone())
@@ -72,6 +72,7 @@ impl ItsiServer {
72
72
  let strategy = self.build_strategy()?;
73
73
  if let Err(e) = strategy.clone().run() {
74
74
  error!("Error running server: {}", e);
75
+ send_lifecycle_event(LifecycleEvent::Shutdown);
75
76
  strategy.stop()?;
76
77
  }
77
78
  Ok(())
@@ -1,4 +1,5 @@
1
1
  use crate::prelude::*;
2
+ use crate::ruby_types::itsi_server::itsi_server_config::SocketOpts;
2
3
  use crate::server::io_stream::IoStream;
3
4
  use crate::server::serve_strategy::single_mode::RunningPhase;
4
5
 
@@ -326,12 +327,12 @@ impl Listener {
326
327
  }
327
328
  }
328
329
 
329
- pub fn inherit_fd(bind: Bind, fd: RawFd) -> Result<Self> {
330
+ pub fn inherit_fd(bind: Bind, fd: RawFd, socket_opts: &SocketOpts) -> Result<Self> {
330
331
  let bound = match bind.address {
331
332
  BindAddress::Ip(_) => match bind.protocol {
332
- BindProtocol::Http => Listener::Tcp(revive_tcp_socket(fd)?),
333
+ BindProtocol::Http => Listener::Tcp(revive_tcp_socket(fd, socket_opts)?),
333
334
  BindProtocol::Https => {
334
- let tcp_listener = revive_tcp_socket(fd)?;
335
+ let tcp_listener = revive_tcp_socket(fd, socket_opts)?;
335
336
  Listener::TcpTls((
336
337
  tcp_listener,
337
338
  bind.tls_config.unwrap().build_acceptor().unwrap(),
@@ -341,25 +342,25 @@ impl Listener {
341
342
  },
342
343
  BindAddress::UnixSocket(_) => match bind.tls_config {
343
344
  Some(tls_config) => Listener::UnixTls((
344
- revive_unix_socket(fd)?,
345
+ revive_unix_socket(fd, socket_opts)?,
345
346
  tls_config.build_acceptor().unwrap(),
346
347
  )),
347
- None => Listener::Unix(revive_unix_socket(fd)?),
348
+ None => Listener::Unix(revive_unix_socket(fd, socket_opts)?),
348
349
  },
349
350
  };
350
351
  Ok(bound)
351
352
  }
352
353
  }
353
354
 
354
- impl TryFrom<Bind> for Listener {
355
- type Error = itsi_error::ItsiError;
356
-
357
- fn try_from(bind: Bind) -> std::result::Result<Self, Self::Error> {
355
+ impl Listener {
356
+ pub fn build(bind: Bind, socket_opts: &SocketOpts) -> Result<Self> {
358
357
  let bound = match bind.address {
359
358
  BindAddress::Ip(addr) => match bind.protocol {
360
- BindProtocol::Http => Listener::Tcp(connect_tcp_socket(addr, bind.port.unwrap())?),
359
+ BindProtocol::Http => {
360
+ Listener::Tcp(connect_tcp_socket(addr, bind.port.unwrap(), socket_opts)?)
361
+ }
361
362
  BindProtocol::Https => {
362
- let tcp_listener = connect_tcp_socket(addr, bind.port.unwrap())?;
363
+ let tcp_listener = connect_tcp_socket(addr, bind.port.unwrap(), socket_opts)?;
363
364
  Listener::TcpTls((
364
365
  tcp_listener,
365
366
  bind.tls_config.unwrap().build_acceptor().unwrap(),
@@ -369,56 +370,60 @@ impl TryFrom<Bind> for Listener {
369
370
  },
370
371
  BindAddress::UnixSocket(path) => match bind.tls_config {
371
372
  Some(tls_config) => Listener::UnixTls((
372
- connect_unix_socket(&path)?,
373
+ connect_unix_socket(&path, socket_opts)?,
373
374
  tls_config.build_acceptor().unwrap(),
374
375
  )),
375
- None => Listener::Unix(connect_unix_socket(&path)?),
376
+ None => Listener::Unix(connect_unix_socket(&path, socket_opts)?),
376
377
  },
377
378
  };
378
379
  Ok(bound)
379
380
  }
380
381
  }
381
382
 
382
- fn revive_tcp_socket(fd: RawFd) -> Result<TcpListener> {
383
+ fn revive_tcp_socket(fd: RawFd, socket_opts: &SocketOpts) -> Result<TcpListener> {
383
384
  let socket = unsafe { Socket::from_raw_fd(fd) };
384
- socket.set_reuse_port(true).ok();
385
- socket.set_reuse_address(true).ok();
385
+ socket.set_reuse_port(socket_opts.reuse_port).ok();
386
+ socket.set_reuse_address(socket_opts.reuse_address).ok();
386
387
  socket.set_nonblocking(true).ok();
387
- socket.set_nodelay(true).ok();
388
- socket.set_recv_buffer_size(262_144).ok();
388
+ socket.set_nodelay(socket_opts.nodelay).ok();
389
+ socket
390
+ .set_recv_buffer_size(socket_opts.recv_buffer_size)
391
+ .ok();
389
392
  socket.set_cloexec(true)?;
390
- socket.listen(1024)?;
393
+ socket.listen(socket_opts.listen_backlog as i32)?;
391
394
  Ok(socket.into())
392
395
  }
393
396
 
394
- fn revive_unix_socket(fd: RawFd) -> Result<UnixListener> {
397
+ fn revive_unix_socket(fd: RawFd, socket_opts: &SocketOpts) -> Result<UnixListener> {
395
398
  let socket = unsafe { Socket::from_raw_fd(fd) };
396
399
  socket.set_nonblocking(true).ok();
397
- socket.listen(1024)?;
400
+ socket.listen(socket_opts.listen_backlog as i32)?;
398
401
  socket.set_cloexec(true)?;
399
402
 
400
403
  Ok(socket.into())
401
404
  }
402
405
 
403
- fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
406
+ fn connect_tcp_socket(addr: IpAddr, port: u16, socket_opts: &SocketOpts) -> Result<TcpListener> {
404
407
  let domain = match addr {
405
408
  IpAddr::V4(_) => Domain::IPV4,
406
409
  IpAddr::V6(_) => Domain::IPV6,
407
410
  };
408
411
  let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
409
412
  let socket_address: SocketAddr = SocketAddr::new(addr, port);
410
- socket.set_reuse_address(true).ok();
411
- socket.set_reuse_port(true).ok();
413
+ socket.set_reuse_address(socket_opts.reuse_address).ok();
414
+ socket.set_reuse_port(socket_opts.reuse_port).ok();
412
415
  socket.set_nonblocking(true).ok();
413
- socket.set_nodelay(true).ok();
414
- socket.set_recv_buffer_size(262_144).ok();
416
+ socket.set_nodelay(socket_opts.nodelay).ok();
417
+ socket
418
+ .set_recv_buffer_size(socket_opts.recv_buffer_size)
419
+ .ok();
415
420
  socket.set_only_v6(false).ok();
416
421
  socket.bind(&socket_address.into())?;
417
- socket.listen(1024)?;
422
+ socket.listen(socket_opts.listen_backlog as i32)?;
418
423
  Ok(socket.into())
419
424
  }
420
425
 
421
- fn connect_unix_socket(path: &PathBuf) -> Result<UnixListener> {
426
+ fn connect_unix_socket(path: &PathBuf, socket_opts: &SocketOpts) -> Result<UnixListener> {
422
427
  let _ = std::fs::remove_file(path);
423
428
  let socket = Socket::new(Domain::UNIX, Type::STREAM, None)?;
424
429
  socket.set_nonblocking(true).ok();
@@ -426,7 +431,7 @@ fn connect_unix_socket(path: &PathBuf) -> Result<UnixListener> {
426
431
  let socket_address = socket2::SockAddr::unix(path)?;
427
432
 
428
433
  socket.bind(&socket_address)?;
429
- socket.listen(1024)?;
434
+ socket.listen(socket_opts.listen_backlog as i32)?;
430
435
 
431
436
  Ok(socket.into())
432
437
  }
@@ -1,11 +1,11 @@
1
1
  use async_trait::async_trait;
2
2
  use fs2::FileExt;
3
+ use itsi_acme::caches::DirCache;
4
+ use itsi_acme::{AccountCache, CertCache};
3
5
  use parking_lot::Mutex;
4
6
  use std::fs::{self, OpenOptions};
5
7
  use std::io::Error as IoError;
6
8
  use std::path::{Path, PathBuf};
7
- use tokio_rustls_acme::caches::DirCache;
8
- use tokio_rustls_acme::{AccountCache, CertCache};
9
9
 
10
10
  use crate::env::ITSI_ACME_LOCK_FILE_NAME;
11
11
 
@@ -1,4 +1,5 @@
1
1
  use base64::{engine::general_purpose, Engine as _};
2
+ use itsi_acme::{AcmeAcceptor, AcmeConfig, AcmeState};
2
3
  use itsi_error::Result;
3
4
  use itsi_tracing::info;
4
5
  use locked_dir_cache::LockedDirCache;
@@ -18,7 +19,6 @@ use std::{
18
19
  };
19
20
  use tokio::sync::Mutex;
20
21
  use tokio_rustls::{rustls::ServerConfig, TlsAcceptor};
21
- use tokio_rustls_acme::{AcmeAcceptor, AcmeConfig, AcmeState};
22
22
 
23
23
  use crate::env::{
24
24
  ITSI_ACME_CACHE_DIR, ITSI_ACME_CA_PEM_PATH, ITSI_ACME_CONTACT_EMAIL, ITSI_ACME_DIRECTORY_URL,