itsi 0.1.18 → 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 (394) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Cargo.lock +924 -385
  4. data/README.md +67 -55
  5. data/crates/itsi_server/Cargo.toml +7 -4
  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 +932 -382
  48. data/gems/server/README.md +2 -0
  49. data/gems/server/exe/itsi +5 -5
  50. data/gems/server/lib/itsi/http_request.rb +1 -0
  51. data/gems/server/lib/itsi/server/config/config_helpers.rb +93 -0
  52. data/gems/server/lib/itsi/server/config/dsl.rb +98 -37
  53. data/gems/server/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  54. data/gems/server/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  55. data/gems/server/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  56. data/gems/server/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  57. data/gems/server/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  58. data/gems/server/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  59. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  60. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  61. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  62. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  63. data/gems/server/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  64. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  65. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  66. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  67. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  68. data/gems/server/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  69. data/gems/server/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  70. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  71. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  72. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  73. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  74. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  75. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  76. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  77. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  78. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  79. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  80. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  81. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  82. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  83. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  84. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  85. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  86. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  87. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  88. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  89. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  90. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  91. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  92. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  93. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  94. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  95. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  96. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  97. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  98. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  99. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  100. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  101. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  102. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  103. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  104. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  105. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  106. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  107. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  108. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  109. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  110. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  111. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  112. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  113. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  114. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  115. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  116. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  117. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  118. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  119. data/gems/server/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  120. data/gems/server/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  121. data/gems/server/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  122. data/gems/server/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  123. data/gems/server/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  124. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  125. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  126. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  127. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  128. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  129. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  130. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  131. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  132. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  133. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  134. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  135. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  136. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  137. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  138. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  139. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  140. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  141. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  142. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  143. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  144. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  145. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  146. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  147. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  148. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  149. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  150. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  151. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  152. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  153. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  154. data/gems/server/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  155. data/gems/server/lib/itsi/server/config/known_paths.rb +17 -0
  156. data/gems/server/lib/itsi/server/config/middleware/_index.md +54 -0
  157. data/gems/server/lib/itsi/server/config/middleware/log_requests.md +63 -0
  158. data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +33 -0
  159. data/gems/server/lib/itsi/server/config/middleware.rb +9 -0
  160. data/gems/server/lib/itsi/server/config/option.rb +9 -0
  161. data/gems/server/lib/itsi/server/config/options/_index.md +36 -0
  162. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +35 -0
  163. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +18 -0
  164. data/gems/server/lib/itsi/server/config/options/threads.md +39 -0
  165. data/gems/server/lib/itsi/server/config/options/threads.rb +17 -0
  166. data/gems/server/lib/itsi/server/config/options/workers.md +43 -0
  167. data/gems/server/lib/itsi/server/config/options/workers.rb +17 -0
  168. data/gems/server/lib/itsi/server/config/typed_struct.rb +203 -0
  169. data/gems/server/lib/itsi/server/config.rb +124 -30
  170. data/gems/server/lib/itsi/server/signal_trap.rb +5 -1
  171. data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +1 -1
  172. data/gems/server/lib/itsi/server/version.rb +1 -1
  173. data/gems/server/lib/itsi/server.rb +27 -6
  174. data/gems/server/lib/ruby_lsp/itsi/addon.rb +64 -48
  175. data/gems/server/test/helpers/test_helper.rb +64 -5
  176. data/gems/server/test/middleware/test_log_requests.rb +17 -0
  177. data/gems/server/test/options/test_threads.rb +15 -0
  178. data/gems/server/test/options/test_workers.rb +18 -0
  179. data/gems/server/test/test_itsi_server.rb +81 -94
  180. data/itsi-scheduler-100.png +0 -0
  181. data/itsi-server-100.png +0 -0
  182. data/lib/itsi/version.rb +1 -1
  183. data/tasks.txt +36 -28
  184. metadata +147 -215
  185. data/crates/_index.md +0 -0
  186. data/crates/itsi_server/src/ruby_types/README.md +0 -21
  187. data/crates/itsi_server/test.md +0 -14
  188. data/docs/Itsi.rb +0 -17
  189. data/docs/content/about.md +0 -6
  190. data/docs/content/docs/_index.md +0 -18
  191. data/docs/content/docs/first-page.md +0 -9
  192. data/docs/content/docs/folder/_index.md +0 -10
  193. data/docs/content/docs/folder/leaf.md +0 -7
  194. data/foo/Itsi.rb +0 -122
  195. data/gems/_index.md +0 -18
  196. data/gems/scheduler/CHANGELOG.md +0 -5
  197. data/gems/scheduler/CODE_OF_CONDUCT.md +0 -139
  198. data/gems/scheduler/LICENSE.txt +0 -21
  199. data/gems/scheduler/_index.md +0 -7
  200. data/gems/server/CHANGELOG.md +0 -10
  201. data/gems/server/CODE_OF_CONDUCT.md +0 -139
  202. data/gems/server/LICENSE.txt +0 -21
  203. data/gems/server/_index.md +0 -6
  204. data/sandbox/README.md +0 -5
  205. data/sandbox/deploy/main.tf +0 -238
  206. data/sandbox/deploy/outputs.tf +0 -4
  207. data/sandbox/deploy/vars.tf +0 -11
  208. data/sandbox/falcon_benchmark/Gemfile +0 -10
  209. data/sandbox/falcon_benchmark/Gemfile.lock +0 -140
  210. data/sandbox/falcon_benchmark/config.ru +0 -54
  211. data/sandbox/itsi_file/Gemfile +0 -13
  212. data/sandbox/itsi_file/Gemfile.lock +0 -111
  213. data/sandbox/itsi_file/Itsi.rb +0 -473
  214. data/sandbox/itsi_file/call.json +0 -1
  215. data/sandbox/itsi_file/echo_client/Gemfile +0 -10
  216. data/sandbox/itsi_file/echo_client/Gemfile.lock +0 -27
  217. data/sandbox/itsi_file/echo_client/README.md +0 -95
  218. data/sandbox/itsi_file/echo_client/echo_client.rb +0 -164
  219. data/sandbox/itsi_file/echo_client/gen_proto.sh +0 -17
  220. data/sandbox/itsi_file/echo_client/lib/echo_pb.rb +0 -16
  221. data/sandbox/itsi_file/echo_client/lib/echo_services_pb.rb +0 -29
  222. data/sandbox/itsi_file/echo_client/run_client.rb +0 -64
  223. data/sandbox/itsi_file/echo_client/test_compressions.sh +0 -20
  224. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile +0 -10
  225. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile.lock +0 -79
  226. data/sandbox/itsi_file/echo_service_nonitsi/echo.proto +0 -26
  227. data/sandbox/itsi_file/echo_service_nonitsi/echo_pb.rb +0 -16
  228. data/sandbox/itsi_file/echo_service_nonitsi/echo_services_pb.rb +0 -29
  229. data/sandbox/itsi_file/echo_service_nonitsi/server.rb +0 -52
  230. data/sandbox/itsi_file/error.html +0 -2
  231. data/sandbox/itsi_file/organisations_controller.rb +0 -20
  232. data/sandbox/itsi_file/public/assets/image.png +0 -0
  233. data/sandbox/itsi_sandbox_async/Gemfile +0 -10
  234. data/sandbox/itsi_sandbox_async/Gemfile.lock +0 -69
  235. data/sandbox/itsi_sandbox_async/config.ru +0 -9
  236. data/sandbox/itsi_sandbox_hanami/.env +0 -2
  237. data/sandbox/itsi_sandbox_hanami/.gitignore +0 -6
  238. data/sandbox/itsi_sandbox_hanami/.rspec +0 -1
  239. data/sandbox/itsi_sandbox_hanami/Gemfile +0 -49
  240. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +0 -440
  241. data/sandbox/itsi_sandbox_hanami/Guardfile +0 -9
  242. data/sandbox/itsi_sandbox_hanami/Procfile.dev +0 -2
  243. data/sandbox/itsi_sandbox_hanami/README.md +0 -1
  244. data/sandbox/itsi_sandbox_hanami/Rakefile +0 -3
  245. data/sandbox/itsi_sandbox_hanami/app/action.rb +0 -12
  246. data/sandbox/itsi_sandbox_hanami/app/actions/.keep +0 -0
  247. data/sandbox/itsi_sandbox_hanami/app/assets/css/app.css +0 -5
  248. data/sandbox/itsi_sandbox_hanami/app/assets/images/favicon.ico +0 -0
  249. data/sandbox/itsi_sandbox_hanami/app/assets/js/app.js +0 -1
  250. data/sandbox/itsi_sandbox_hanami/app/db/relation.rb +0 -10
  251. data/sandbox/itsi_sandbox_hanami/app/db/repo.rb +0 -10
  252. data/sandbox/itsi_sandbox_hanami/app/db/struct.rb +0 -10
  253. data/sandbox/itsi_sandbox_hanami/app/operation.rb +0 -9
  254. data/sandbox/itsi_sandbox_hanami/app/relations/.keep +0 -0
  255. data/sandbox/itsi_sandbox_hanami/app/repos/.keep +0 -0
  256. data/sandbox/itsi_sandbox_hanami/app/structs/.keep +0 -0
  257. data/sandbox/itsi_sandbox_hanami/app/templates/layouts/app.html.erb +0 -14
  258. data/sandbox/itsi_sandbox_hanami/app/view.rb +0 -9
  259. data/sandbox/itsi_sandbox_hanami/app/views/helpers.rb +0 -10
  260. data/sandbox/itsi_sandbox_hanami/bin/dev +0 -8
  261. data/sandbox/itsi_sandbox_hanami/config/app.rb +0 -8
  262. data/sandbox/itsi_sandbox_hanami/config/assets.js +0 -16
  263. data/sandbox/itsi_sandbox_hanami/config/db/migrate/.keep +0 -0
  264. data/sandbox/itsi_sandbox_hanami/config/db/seeds.rb +0 -15
  265. data/sandbox/itsi_sandbox_hanami/config/puma.rb +0 -47
  266. data/sandbox/itsi_sandbox_hanami/config/routes.rb +0 -7
  267. data/sandbox/itsi_sandbox_hanami/config/settings.rb +0 -9
  268. data/sandbox/itsi_sandbox_hanami/config.ru +0 -5
  269. data/sandbox/itsi_sandbox_hanami/db/.keep +0 -0
  270. data/sandbox/itsi_sandbox_hanami/lib/itsi_hanami/types.rb +0 -11
  271. data/sandbox/itsi_sandbox_hanami/lib/tasks/.keep +0 -0
  272. data/sandbox/itsi_sandbox_hanami/package-lock.json +0 -946
  273. data/sandbox/itsi_sandbox_hanami/package.json +0 -8
  274. data/sandbox/itsi_sandbox_hanami/spec/requests/root_spec.rb +0 -11
  275. data/sandbox/itsi_sandbox_hanami/spec/spec_helper.rb +0 -9
  276. data/sandbox/itsi_sandbox_hanami/spec/support/db/cleaning.rb +0 -42
  277. data/sandbox/itsi_sandbox_hanami/spec/support/db.rb +0 -10
  278. data/sandbox/itsi_sandbox_hanami/spec/support/features.rb +0 -5
  279. data/sandbox/itsi_sandbox_hanami/spec/support/operations.rb +0 -8
  280. data/sandbox/itsi_sandbox_hanami/spec/support/requests.rb +0 -13
  281. data/sandbox/itsi_sandbox_hanami/spec/support/rspec.rb +0 -61
  282. data/sandbox/itsi_sandbox_rack/Gemfile +0 -17
  283. data/sandbox/itsi_sandbox_rack/Gemfile.lock +0 -153
  284. data/sandbox/itsi_sandbox_rack/config.ru +0 -5
  285. data/sandbox/itsi_sandbox_rack_lint/Gemfile +0 -7
  286. data/sandbox/itsi_sandbox_rack_lint/Gemfile.lock +0 -27
  287. data/sandbox/itsi_sandbox_rack_lint/config.ru +0 -3
  288. data/sandbox/itsi_sandbox_rails/.dockerignore +0 -48
  289. data/sandbox/itsi_sandbox_rails/.gitattributes +0 -9
  290. data/sandbox/itsi_sandbox_rails/.github/dependabot.yml +0 -12
  291. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +0 -90
  292. data/sandbox/itsi_sandbox_rails/.gitignore +0 -35
  293. data/sandbox/itsi_sandbox_rails/.rubocop.yml +0 -8
  294. data/sandbox/itsi_sandbox_rails/.ruby-version +0 -1
  295. data/sandbox/itsi_sandbox_rails/Dockerfile +0 -69
  296. data/sandbox/itsi_sandbox_rails/Gemfile +0 -66
  297. data/sandbox/itsi_sandbox_rails/Gemfile.lock +0 -429
  298. data/sandbox/itsi_sandbox_rails/README.md +0 -24
  299. data/sandbox/itsi_sandbox_rails/Rakefile +0 -6
  300. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +0 -4
  301. data/sandbox/itsi_sandbox_rails/app/assets/images/.keep +0 -0
  302. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +0 -15
  303. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +0 -4
  304. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +0 -4
  305. data/sandbox/itsi_sandbox_rails/app/controllers/application_controller.rb +0 -4
  306. data/sandbox/itsi_sandbox_rails/app/controllers/concerns/.keep +0 -0
  307. data/sandbox/itsi_sandbox_rails/app/controllers/home_controller.rb +0 -66
  308. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +0 -40
  309. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -29
  310. data/sandbox/itsi_sandbox_rails/app/helpers/application_helper.rb +0 -2
  311. data/sandbox/itsi_sandbox_rails/app/javascript/application.js +0 -3
  312. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/application.js +0 -9
  313. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/hello_controller.js +0 -7
  314. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/index.js +0 -4
  315. data/sandbox/itsi_sandbox_rails/app/jobs/application_job.rb +0 -7
  316. data/sandbox/itsi_sandbox_rails/app/mailers/application_mailer.rb +0 -4
  317. data/sandbox/itsi_sandbox_rails/app/models/application_record.rb +0 -3
  318. data/sandbox/itsi_sandbox_rails/app/models/concerns/.keep +0 -0
  319. data/sandbox/itsi_sandbox_rails/app/models/post.rb +0 -2
  320. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +0 -23
  321. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.html.erb +0 -13
  322. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.text.erb +0 -1
  323. data/sandbox/itsi_sandbox_rails/app/views/pwa/manifest.json.erb +0 -22
  324. data/sandbox/itsi_sandbox_rails/app/views/pwa/service-worker.js +0 -26
  325. data/sandbox/itsi_sandbox_rails/bin/brakeman +0 -7
  326. data/sandbox/itsi_sandbox_rails/bin/bundle +0 -109
  327. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +0 -13
  328. data/sandbox/itsi_sandbox_rails/bin/importmap +0 -4
  329. data/sandbox/itsi_sandbox_rails/bin/rails +0 -4
  330. data/sandbox/itsi_sandbox_rails/bin/rake +0 -4
  331. data/sandbox/itsi_sandbox_rails/bin/rubocop +0 -8
  332. data/sandbox/itsi_sandbox_rails/bin/setup +0 -37
  333. data/sandbox/itsi_sandbox_rails/config/application.rb +0 -27
  334. data/sandbox/itsi_sandbox_rails/config/boot.rb +0 -4
  335. data/sandbox/itsi_sandbox_rails/config/cable.yml +0 -10
  336. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +0 -1
  337. data/sandbox/itsi_sandbox_rails/config/database.yml +0 -30
  338. data/sandbox/itsi_sandbox_rails/config/environment.rb +0 -5
  339. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +0 -82
  340. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +0 -106
  341. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +0 -67
  342. data/sandbox/itsi_sandbox_rails/config/importmap.rb +0 -7
  343. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +0 -12
  344. data/sandbox/itsi_sandbox_rails/config/initializers/content_security_policy.rb +0 -25
  345. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +0 -8
  346. data/sandbox/itsi_sandbox_rails/config/initializers/inflections.rb +0 -16
  347. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +0 -13
  348. data/sandbox/itsi_sandbox_rails/config/locales/en.yml +0 -31
  349. data/sandbox/itsi_sandbox_rails/config/puma.rb +0 -34
  350. data/sandbox/itsi_sandbox_rails/config/routes.rb +0 -23
  351. data/sandbox/itsi_sandbox_rails/config/storage.yml +0 -34
  352. data/sandbox/itsi_sandbox_rails/config.ru +0 -6
  353. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +0 -10
  354. data/sandbox/itsi_sandbox_rails/db/schema.rb +0 -23
  355. data/sandbox/itsi_sandbox_rails/db/seeds.rb +0 -9
  356. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  357. data/sandbox/itsi_sandbox_rails/lib/tasks/.keep +0 -0
  358. data/sandbox/itsi_sandbox_rails/log/.keep +0 -0
  359. data/sandbox/itsi_sandbox_rails/public/404.html +0 -67
  360. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +0 -66
  361. data/sandbox/itsi_sandbox_rails/public/422.html +0 -67
  362. data/sandbox/itsi_sandbox_rails/public/500.html +0 -66
  363. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  364. data/sandbox/itsi_sandbox_rails/public/icon.svg +0 -3
  365. data/sandbox/itsi_sandbox_rails/public/robots.txt +0 -1
  366. data/sandbox/itsi_sandbox_rails/storage/.keep +0 -0
  367. data/sandbox/itsi_sandbox_rails/test/application_system_test_case.rb +0 -5
  368. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +0 -13
  369. data/sandbox/itsi_sandbox_rails/test/controllers/.keep +0 -0
  370. data/sandbox/itsi_sandbox_rails/test/fixtures/files/.keep +0 -0
  371. data/sandbox/itsi_sandbox_rails/test/helpers/.keep +0 -0
  372. data/sandbox/itsi_sandbox_rails/test/integration/.keep +0 -0
  373. data/sandbox/itsi_sandbox_rails/test/mailers/.keep +0 -0
  374. data/sandbox/itsi_sandbox_rails/test/models/.keep +0 -0
  375. data/sandbox/itsi_sandbox_rails/test/system/.keep +0 -0
  376. data/sandbox/itsi_sandbox_rails/test/test_helper.rb +0 -15
  377. data/sandbox/itsi_sandbox_rails/tmp/.keep +0 -0
  378. data/sandbox/itsi_sandbox_rails/tmp/pids/.keep +0 -0
  379. data/sandbox/itsi_sandbox_rails/tmp/storage/.keep +0 -0
  380. data/sandbox/itsi_sandbox_rails/vendor/.keep +0 -0
  381. data/sandbox/itsi_sandbox_rails/vendor/javascript/.keep +0 -0
  382. data/sandbox/itsi_sandbox_roda/Gemfile +0 -5
  383. data/sandbox/itsi_sandbox_roda/Gemfile.lock +0 -37
  384. data/sandbox/itsi_sandbox_roda/config.ru +0 -39
  385. data/sandbox/itsi_sinatra/Gemfile +0 -9
  386. data/sandbox/itsi_sinatra/Gemfile.lock +0 -81
  387. data/sandbox/itsi_sinatra/app.rb +0 -8
  388. data/sandbox/pebble/docker-compose.yml +0 -11
  389. data/sandbox/static_files/.env +0 -1
  390. data/sandbox/static_files/404.html +0 -25
  391. data/sandbox/static_files/_DSC0102.NEF.jpg +0 -0
  392. data/sandbox/static_files/about.html +0 -68
  393. data/sandbox/static_files/tiny.html +0 -1
  394. data/sandbox/static_files/writebook.zip +0 -0
@@ -3,7 +3,9 @@
3
3
  module Itsi
4
4
  class Server
5
5
  module Config
6
+ require_relative "config/typed_struct"
6
7
  require_relative "config/dsl"
8
+ require_relative "config/known_paths"
7
9
  require_relative "default_app/default_app"
8
10
 
9
11
  ITSI_DEFAULT_CONFIG_FILE = "Itsi.rb"
@@ -33,7 +35,7 @@ module Itsi
33
35
  # 3. Default values.
34
36
  def self.build_config(args, config_file_path, builder_proc = nil)
35
37
  args.transform_keys!(&:to_sym)
36
- itsifile_config = \
38
+ itsifile_config, errors = \
37
39
  if builder_proc
38
40
  DSL.evaluate(&builder_proc)
39
41
  elsif args[:static]
@@ -87,33 +89,77 @@ module Itsi
87
89
  Bundler.require(preload)
88
90
  end
89
91
 
90
- {
91
- workers: args.fetch(:workers) { itsifile_config.fetch(:workers, 1) },
92
- worker_memory_limit: args.fetch(:worker_memory_limit) { itsifile_config.fetch(:worker_memory_limit, nil) },
93
- silence: args.fetch(:silence) { itsifile_config.fetch(:silence, false) },
94
- shutdown_timeout: args.fetch(:shutdown_timeout) { itsifile_config.fetch(:shutdown_timeout, 5) },
95
- hooks: itsifile_config.fetch(:hooks, nil),
96
- preload: !!preload,
97
- request_timeout: itsifile_config.fetch(:request_timeout, nil),
98
- notify_watchers: itsifile_config.fetch(:notify_watchers, nil),
99
- threads: args.fetch(:threads) { itsifile_config.fetch(:threads, 1) },
100
- scheduler_threads: args.fetch(:scheduler_threads) { itsifile_config.fetch(:scheduler_threads, nil) },
101
- streamable_body: args.fetch(:streamable_body) { itsifile_config.fetch(:streamable_body, false) },
102
- multithreaded_reactor: args.fetch(:multithreaded_reactor) do
103
- itsifile_config.fetch(:multithreaded_reactor, nil)
104
- end,
105
- pin_worker_cores: args.fetch(:pin_worker_cores) { itsifile_config.fetch(:pin_worker_cores, true) },
106
- scheduler_class: args.fetch(:scheduler_class) { itsifile_config.fetch(:scheduler_class, nil) },
107
- oob_gc_responses_threshold: args.fetch(:oob_gc_responses_threshold) do
108
- itsifile_config.fetch(:oob_gc_responses_threshold, nil)
109
- end,
110
- log_level: args.fetch(:log_level) { itsifile_config.fetch(:log_level, nil) },
111
- log_format: args.fetch(:log_format) { itsifile_config.fetch(:log_format, nil) },
112
- log_target: args.fetch(:log_target) { itsifile_config.fetch(:log_target, nil) },
113
- binds: args.fetch(:binds) { itsifile_config.fetch(:binds, ["http://0.0.0.0:3000"]) },
114
- middleware_loader: middleware_loader,
115
- listeners: args.fetch(:listeners) { nil }
116
- }.transform_keys(&:to_s)
92
+ [
93
+ {
94
+ workers: args.fetch(:workers) { itsifile_config.fetch(:workers, 1) },
95
+ worker_memory_limit: args.fetch(:worker_memory_limit) { itsifile_config.fetch(:worker_memory_limit, nil) },
96
+ silence: args.fetch(:silence) { itsifile_config.fetch(:silence, false) },
97
+ shutdown_timeout: args.fetch(:shutdown_timeout) { itsifile_config.fetch(:shutdown_timeout, 5) },
98
+ hooks: itsifile_config.fetch(:hooks, nil),
99
+ preload: !!preload,
100
+ request_timeout: itsifile_config.fetch(:request_timeout, nil),
101
+ header_read_timeout: args.fetch(:header_read_timeout) { itsifile_config.fetch(:header_read_timeout, nil) },
102
+ notify_watchers: itsifile_config.fetch(:notify_watchers, nil),
103
+ threads: args.fetch(:threads) { itsifile_config.fetch(:threads, 1) },
104
+ scheduler_threads: args.fetch(:scheduler_threads) { itsifile_config.fetch(:scheduler_threads, nil) },
105
+ streamable_body: args.fetch(:streamable_body) { itsifile_config.fetch(:streamable_body, false) },
106
+ multithreaded_reactor: args.fetch(:multithreaded_reactor) do
107
+ itsifile_config.fetch(:multithreaded_reactor, nil)
108
+ end,
109
+ pin_worker_cores: args.fetch(:pin_worker_cores) { itsifile_config.fetch(:pin_worker_cores, true) },
110
+ scheduler_class: args.fetch(:scheduler_class) { itsifile_config.fetch(:scheduler_class, nil) },
111
+ oob_gc_responses_threshold: args.fetch(:oob_gc_responses_threshold) do
112
+ itsifile_config.fetch(:oob_gc_responses_threshold, nil)
113
+ end,
114
+ log_level: args.fetch(:log_level) { itsifile_config.fetch(:log_level, nil) },
115
+ log_format: args.fetch(:log_format) { itsifile_config.fetch(:log_format, nil) },
116
+ log_target: args.fetch(:log_target) { itsifile_config.fetch(:log_target, nil) },
117
+ log_target_filters: args.fetch(:log_target_filters) { itsifile_config.fetch(:log_target_filters, nil) },
118
+ binds: args.fetch(:binds) { itsifile_config.fetch(:binds, ["http://0.0.0.0:3000"]) },
119
+ middleware_loader: middleware_loader,
120
+ listeners: args.fetch(:listeners) { nil },
121
+ reuse_address: itsifile_config.fetch(:reuse_address, true),
122
+ reuse_port: itsifile_config.fetch(:reuse_port, true),
123
+ listen_backlog: itsifile_config.fetch(:listen_backlog, 1024 ),
124
+ nodelay: itsifile_config.fetch(:nodelay, true),
125
+ recv_buffer_size: itsifile_config.fetch(:recv_buffer_size, 262_144)
126
+ }.transform_keys(&:to_s),
127
+
128
+ errors.flat_map do |(error, message)|
129
+ location = message[/(.*?)\:in/,1]
130
+ file, lineno = location.split(":")
131
+ lineno = lineno.to_i
132
+ err_message = error.kind_of?(NoMethodError) ? error.detailed_message : error.message
133
+ file_lines = IO.readlines(file)
134
+ info_lines = if error.kind_of?(SyntaxError)
135
+ []
136
+ else
137
+ ([lineno-2, 0].max...[file_lines.length, lineno.succ.succ].min).map do |currline|
138
+ [
139
+ " #{currline.succ.to_s.rjust(3)} | #{file_lines[currline].strip}",
140
+ if currline == lineno-1
141
+ " | ^^^ "
142
+ end
143
+ ].compact
144
+ end.flatten
145
+ end
146
+ [
147
+ err_message,
148
+ " --> #{File.expand_path(file)}:#{lineno}",
149
+ *info_lines
150
+ ]
151
+ end
152
+ ]
153
+ end
154
+
155
+ def self.test!(cli_params)
156
+ _, errors = build_config(cli_params, Itsi::Server::Config.config_file_path(cli_params[:config_file]))
157
+ if errors.any?
158
+ Itsi.log_error("Config file is invalid")
159
+ puts errors
160
+ else
161
+ Itsi.log_info("Config file is valid")
162
+ end
117
163
  end
118
164
 
119
165
  # Reloads the entire process
@@ -156,10 +202,58 @@ module Itsi
156
202
  return
157
203
  end
158
204
 
159
- puts "Writing default configuration..."
205
+ default_config = IO.read("#{__dir__}/default_config/Itsi.rb")
206
+
207
+ if File.exist?("./config.ru")
208
+ default_config << <<~RUBY
209
+ # You can mount several Ruby apps as either
210
+ # 1. rackup files
211
+ # 2. inline rack apps
212
+ # 3. inline Ruby endpoints
213
+ #
214
+ # 1. rackup_file
215
+ rackup_file "./config.ru"
216
+ #
217
+ # 2. inline rack app
218
+ # require 'rack'
219
+ # run(Rack::Builder.app do
220
+ # use Rack::CommonLogger
221
+ # run ->(env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
222
+ # end)
223
+ #
224
+ # 3. Endpoints
225
+ # endpoint "/" do |req|
226
+ # req.ok "Hello from Itsi"
227
+ # end
228
+ RUBY
229
+ else
230
+ default_config << <<~RUBY
231
+ # You can mount several Ruby apps as either
232
+ # 1. rackup files
233
+ # 2. inline rack apps
234
+ # 3. inline Ruby endpoints
235
+ #
236
+ # 1. rackup_file
237
+ # Use `rackup_file` to specify the Rack app file name.
238
+ #
239
+ # 2. inline rack app
240
+ # require 'rack'
241
+ # run(Rack::Builder.app do
242
+ # use Rack::CommonLogger
243
+ # run ->(env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
244
+ # end)
245
+ #
246
+ # 3. Endpoint
247
+ endpoint "/" do |req|
248
+ req.ok "Hello from Itsi"
249
+ end
250
+ RUBY
251
+ end
252
+
160
253
  File.open(ITSI_DEFAULT_CONFIG_FILE, "w") do |file|
161
- file.write(IO.read("#{__dir__}/default_config/Itsi.rb"))
254
+ file.write(default_config)
162
255
  end
256
+
163
257
  end
164
258
  end
165
259
  end
@@ -10,13 +10,17 @@ module Itsi
10
10
  INTERCEPTED_SIGNALS = ["INT"].freeze
11
11
 
12
12
  def trap(signal, *args, &block)
13
- unless INTERCEPTED_SIGNALS.include?(signal.to_s) && block.nil? && Itsi::Server.running?
13
+ unless INTERCEPTED_SIGNALS.include?(signal.to_s) && block.nil? && server_running?
14
14
  return super(signal, *args, &block)
15
15
  end
16
16
 
17
17
  Itsi::Server.reset_signal_handlers
18
18
  nil
19
19
  end
20
+
21
+ def server_running?
22
+ Itsi::Server.respond_to?(:running) && Itsi::Server.running?
23
+ end
20
24
  end
21
25
  end
22
26
 
@@ -10,7 +10,7 @@ module Itsi
10
10
 
11
11
  proc_line = source_location.last - 1
12
12
  first_line = source_lines[proc_line]
13
- binding.b
13
+
14
14
  until first_line =~ /(?:lambda|proc|->|def|.*?do\s*\|)/ || proc_line.zero?
15
15
  proc_line -= 1
16
16
  first_line = source_lines[proc_line]
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Itsi
4
4
  class Server
5
- VERSION = "0.1.18"
5
+ VERSION = "0.1.20"
6
6
  end
7
7
  end
@@ -38,14 +38,22 @@ module Itsi
38
38
  server = new(cli_params, itsi_file, blk)
39
39
  previous_handler = Signal.trap(:INT, :DEFAULT)
40
40
  run = lambda do
41
- write_pid
42
41
  @running = server
42
+
43
+ if cli_params[:daemonize]
44
+ Itsi.log_info("Itsi is running in the background. Writing pid to #{Itsi::Server::Config.pid_file_path}")
45
+ Itsi.log_info("To stop Itsi, run 'itsi stop' from this directory.")
46
+ Process.daemon(true, false)
47
+ end
48
+ write_pid
49
+
43
50
  server.start
44
- @running = false
51
+ @running = nil
45
52
  Signal.trap(:INT, previous_handler)
46
53
  server
47
54
  end
48
55
  background ? Thread.new(&run) : run[]
56
+ rescue
49
57
  end
50
58
 
51
59
  def static(cli_params)
@@ -55,6 +63,15 @@ module Itsi
55
63
  def stop
56
64
  return unless pid = get_pid
57
65
  Process.kill(:INT, pid)
66
+ i = 0
67
+ while i < 10
68
+ sleep 0.25
69
+ unless get_pid(false)
70
+ puts "Itsi stopped"
71
+ break
72
+ end
73
+ i += 1
74
+ end
58
75
  end
59
76
 
60
77
  def stop_background_thread
@@ -66,19 +83,23 @@ module Itsi
66
83
  File.write(Itsi::Server::Config.pid_file_path, Process.pid)
67
84
  end
68
85
 
69
- def get_pid
86
+ def get_pid(warn=true)
70
87
  pid = File.read(Itsi::Server::Config.pid_file_path).to_i
71
88
  if Process.kill(0, pid)
72
89
  pid
73
90
  else
74
- puts "No server running"
91
+ warn ? puts("No server running") : nil
75
92
  nil
76
93
  end
77
94
  rescue StandardError
78
- puts "No server running"
95
+ warn ? puts("No server running") : nil
79
96
  nil
80
97
  end
81
98
 
99
+ def test
100
+ Itsi::Server::Config.test!(cli_params = {})
101
+ end
102
+
82
103
  def init
83
104
  Config.write_default
84
105
  end
@@ -134,7 +155,7 @@ module Itsi
134
155
 
135
156
  def status
136
157
  return unless pid = get_pid
137
-
158
+ Itsi.log_info("Itsi running on #{pid}")
138
159
  Process.kill(:USR2, pid)
139
160
  end
140
161
 
@@ -1,10 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "ruby_lsp/addon"
4
- puts "Here we go"
4
+ require "itsi/server"
5
+
5
6
  module RubyLsp
6
7
  module Itsi
7
8
  class Addon < ::RubyLsp::Addon
9
+ def activate(global_state, message_queue)
10
+ @message_queue = message_queue
11
+ end
12
+
13
+ def deactivate; end
8
14
 
9
15
  def name
10
16
  "Ruby LSP Itsi"
@@ -14,6 +20,7 @@ module RubyLsp
14
20
  "0.1.0"
15
21
  end
16
22
 
23
+
17
24
  def create_completion_listener(response_builder, node_context, dispatcher, uri)
18
25
  return unless uri.to_s.end_with?("Itsi.rb")
19
26
  @in_itsi_file = true
@@ -21,8 +28,7 @@ module RubyLsp
21
28
  end
22
29
 
23
30
  def create_hover_listener(response_builder, node_context, dispatcher)
24
- hl = dispatcher.listeners[:on_call_node_enter].find{|c| c.kind_of?(RubyLsp::Listeners::Hover)}
25
-
31
+ hl = dispatcher.listeners[:on_call_node_enter].find { |c| c.is_a?(RubyLsp::Listeners::Hover) }
26
32
  return unless hl.instance_variable_get("@path").to_s.end_with?("Itsi.rb")
27
33
  HoverListener.new(response_builder, node_context, dispatcher)
28
34
  end
@@ -34,29 +40,21 @@ module RubyLsp
34
40
  @node_context = node_context
35
41
  @dispatcher = dispatcher
36
42
 
37
- # Register for call nodes (you could also use other events if more appropriate)
43
+ @options_by_name = ::Itsi::Server::Config::Option.subclasses.group_by(&:option_name).map{|k,v| [k,v.first]}.to_h
44
+ @middlewares_by_name = ::Itsi::Server::Config::Middleware.subclasses.group_by(&:middleware_name).map{|k,v| [k,v.first]}.to_h
45
+ # Register for call nodes for hover events
38
46
  dispatcher.register(self, :on_call_node_enter)
39
47
  end
40
48
 
41
49
  def on_call_node_enter(node)
42
- # Check if this is the call for foo_bar; you might add additional logic if needed.
43
- case node.message
44
- when "log_level"
45
- # Push a simple hover response.
46
- @response_builder.push(
47
- "Method **log_level**: A method that takes a single parameter `a`.",
48
- category: :documentation
49
- )
50
- when "shutdown_timeout"
51
- # Push a simple hover response.
50
+ if (matched_class = @options_by_name[node.message.to_sym])
52
51
  @response_builder.push(
53
- "Method **shutdown_timeout**: Number of seconds to wait for a graceful shutdown before forcefully shutting down.",
52
+ matched_class.documentation,
54
53
  category: :documentation
55
54
  )
56
- when "log"
57
- # Push a simple hover response.
55
+ elsif (matched_class = @middlewares_by_name[node.message.to_sym])
58
56
  @response_builder.push(
59
- "Method **log**: A method that takes a single parameter `a`.",
57
+ matched_class.documentation,
60
58
  category: :documentation
61
59
  )
62
60
  end
@@ -70,42 +68,60 @@ module RubyLsp
70
68
  @uri = uri
71
69
  @dispatcher = dispatcher
72
70
 
73
- # Register for call nodes to handle method completions
71
+ # Register for method call completions
74
72
  dispatcher.register(self, :on_call_node_enter)
73
+ # Also register for completion item resolution requests
74
+ dispatcher.register(self, :completion_item_resolve)
75
75
  end
76
76
 
77
77
  def on_call_node_enter(node)
78
- # Only handle method calls that are being typed (no arguments yet)
78
+ # Only handle method calls that are being typed (i.e. no arguments yet)
79
79
  return unless node.arguments.nil?
80
- puts "Adding log level completion"
81
- # Add our completion item
82
- @response_builder << Interface::CompletionItem.new(
83
- label: "log_level",
84
- kind: Constant::CompletionItemKind::METHOD,
85
- detail: "log_level a ",
86
- documentation: "A method that takes a single parameter 'a'",
87
- insert_text: "log_level ${1|:info,:debug,:warn,:error|}",
88
- insert_text_format: Constant::InsertTextFormat::SNIPPET,
89
- )
90
-
91
- @response_builder << Interface::CompletionItem.new(
92
- label: "bind",
93
- kind: Constant::CompletionItemKind::METHOD,
94
- detail: "Bind to an interface",
95
- documentation: "A method that takes a single parameter 'a'",
96
- insert_text: "bind ${1|'https://0.0.0.0','http://0.0.0.0','http://0.0.0.0:3000','https://0.0.0.0:3000','http://127.0.0.1','https://127.0.0.1'|}",
97
- insert_text_format: Constant::InsertTextFormat::SNIPPET,
98
- )
99
-
100
- @response_builder << Interface::CompletionItem.new(
101
- label: "log_format",
102
- kind: Constant::CompletionItemKind::METHOD,
103
- detail: "log_format",
104
- documentation: "A method that takes a single parameter 'a'",
105
- insert_text: "log_format ${1|:plain,:json,:auto|}",
106
- insert_text_format: Constant::InsertTextFormat::SNIPPET,
107
- )
80
+
81
+ ::Itsi::Server::Config::Option.subclasses.each do |option|
82
+ completion_item = Interface::CompletionItem.new(
83
+ label: option.option_name,
84
+ kind: Constant::CompletionItemKind::METHOD,
85
+ label_details: Interface::CompletionItemLabelDetails.new(
86
+ detail: option.detail,
87
+ description: option.documentation
88
+ ),
89
+ documentation: Interface::MarkupContent.new(
90
+ kind: Constant::MarkupKind::MARKDOWN,
91
+ value: option.documentation
92
+ ),
93
+ insert_text: option.insert_text,
94
+ insert_text_format: Constant::InsertTextFormat::SNIPPET,
95
+ data: {
96
+ delegateCompletion: true
97
+ }
98
+ )
99
+ @response_builder << completion_item
100
+ end
101
+
102
+ ::Itsi::Server::Config::Middleware.subclasses.each do |middleware|
103
+ completion_item = Interface::CompletionItem.new(
104
+ label: middleware.middleware_name,
105
+ kind: Constant::CompletionItemKind::METHOD,
106
+ label_details: Interface::CompletionItemLabelDetails.new(
107
+ detail: middleware.detail,
108
+ description: middleware.documentation
109
+ ),
110
+ documentation: Interface::MarkupContent.new(
111
+ kind: Constant::MarkupKind::MARKDOWN,
112
+ value: middleware.documentation
113
+ ),
114
+ insert_text: middleware.insert_text,
115
+ insert_text_format: Constant::InsertTextFormat::SNIPPET,
116
+ data: {
117
+ delegateCompletion: true
118
+ }
119
+ )
120
+ @response_builder << completion_item
121
+ end
108
122
  end
123
+
124
+
109
125
  end
110
126
  end
111
127
  end
@@ -4,6 +4,10 @@ ENV["ITSI_LOG"] = "off"
4
4
  require "minitest/reporters"
5
5
  require "itsi/server"
6
6
  require "itsi/scheduler"
7
+ require "socket"
8
+ require "net/http"
9
+ require "minitest/autorun"
10
+
7
11
 
8
12
  Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
9
13
 
@@ -14,18 +18,73 @@ def free_bind(protocol)
14
18
  "#{protocol}://0.0.0.0:#{port}"
15
19
  end
16
20
 
17
- def run_app(app, protocol: "http", bind: free_bind(protocol), scheduler_class: nil)
18
- Itsi::Server.start_in_background_thread do
21
+ def server(app: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, &blk)
22
+ itsi_rb ||= lambda do
19
23
  # Inline Itsi.rb
20
24
  bind bind
21
25
  workers 1
22
26
  threads 1
23
- fiber_scheduler scheduler_class
24
27
  log_level :warn
25
- run app
28
+ run app if app
26
29
  end
27
30
 
28
- yield URI(bind)
31
+ cli_params = {}
32
+ cli_params[:binds] = [bind] if bind
33
+
34
+ Itsi::Server.start_in_background_thread(cli_params, &itsi_rb)
35
+ uri = URI(bind)
36
+ RequestContext.new(uri, self).instance_exec(uri, &blk)
37
+ rescue StandardError => e
38
+ puts e
39
+ puts e.message
40
+ puts e.backtrace.join("\n")
29
41
  ensure
30
42
  Itsi::Server.stop_background_thread
31
43
  end
44
+
45
+ class RequestContext
46
+ def initialize(uri, binding)
47
+ @uri = uri
48
+ @binding = binding
49
+ end
50
+
51
+ def method_missing(method_name, *args, &block)
52
+ @binding.send(method_name, *args, &block)
53
+ end
54
+
55
+ def post(path, data)
56
+ Net::HTTP.post(@uri+path, data)
57
+ end
58
+
59
+ def get(path)
60
+ Net::HTTP.get(@uri+path)
61
+ end
62
+
63
+ def get_resp(path)
64
+ Net::HTTP.get_response(@uri+path)
65
+ end
66
+
67
+ def head(path)
68
+ Net::HTTP.start(@uri.host, @uri.port) {|http|
69
+ http.head(path)
70
+ }
71
+ end
72
+
73
+ def options(path)
74
+ Net::HTTP.start(@uri.host, @uri.port) {|http|
75
+ http.options(path)
76
+ }
77
+ end
78
+
79
+ def put(path, data)
80
+ Net::HTTP.put(@uri+path, data)
81
+ end
82
+
83
+ def delete(path)
84
+ Net::HTTP.delete(@uri+path)
85
+ end
86
+
87
+ def patch(path, data)
88
+ Net::HTTP.patch(@uri+path, data)
89
+ end
90
+ end
@@ -0,0 +1,17 @@
1
+ require_relative "../helpers/test_helper"
2
+
3
+ class TestLogRequests < Minitest::Test
4
+
5
+ def test_it_supports_logging_before_requests
6
+
7
+ end
8
+
9
+ def test_it_supports_logging_after_requests
10
+
11
+ end
12
+
13
+ def test_it_supports_configuring_log_level
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,15 @@
1
+ require_relative "../helpers/test_helper"
2
+
3
+ class TestThreads < Minitest::Test
4
+
5
+ def test_it_can_run_multiple_threads
6
+ thread_count = 4
7
+ server(
8
+ itsi_rb: lambda do
9
+ threads thread_count
10
+ get("/foo"){|r| r.ok Thread.current.object_id}
11
+ end) do
12
+ assert_equal thread_count, 30.times.map { |i| get("/foo") }.uniq.size
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "../helpers/test_helper"
2
+
3
+ class TestWorkers < Minitest::Test
4
+
5
+ def test_it_can_run_multiple_workers
6
+ worker_count = 4
7
+
8
+ server(
9
+ itsi_rb: lambda do
10
+
11
+ workers worker_count
12
+ get("/foo"){|r| r.ok Process.pid}
13
+
14
+ end) do
15
+ assert_equal worker_count, 30.times.map { |i| get("/foo") }.uniq.size
16
+ end
17
+ end
18
+ end