itsi 0.1.19 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (645) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/Cargo.lock +942 -242
  4. data/LICENSE.txt +698 -0
  5. data/README.md +77 -54
  6. data/Rakefile +9 -5
  7. data/crates/itsi_acme/.gitignore +4 -0
  8. data/crates/itsi_acme/Cargo.toml +86 -0
  9. data/crates/itsi_acme/LICENSE-APACHE +201 -0
  10. data/crates/itsi_acme/LICENSE-MIT +23 -0
  11. data/crates/itsi_acme/README.md +9 -0
  12. data/crates/itsi_acme/examples/high_level.rs +63 -0
  13. data/crates/itsi_acme/examples/high_level_warp.rs +52 -0
  14. data/crates/itsi_acme/examples/low_level.rs +87 -0
  15. data/crates/itsi_acme/examples/low_level_axum.rs +66 -0
  16. data/crates/itsi_acme/src/acceptor.rs +81 -0
  17. data/crates/itsi_acme/src/acme.rs +354 -0
  18. data/crates/itsi_acme/src/axum.rs +86 -0
  19. data/crates/itsi_acme/src/cache.rs +39 -0
  20. data/crates/itsi_acme/src/caches/boxed.rs +80 -0
  21. data/crates/itsi_acme/src/caches/composite.rs +69 -0
  22. data/crates/itsi_acme/src/caches/dir.rs +106 -0
  23. data/crates/itsi_acme/src/caches/mod.rs +11 -0
  24. data/crates/itsi_acme/src/caches/no.rs +78 -0
  25. data/crates/itsi_acme/src/caches/test.rs +136 -0
  26. data/crates/itsi_acme/src/config.rs +172 -0
  27. data/crates/itsi_acme/src/https_helper.rs +69 -0
  28. data/crates/itsi_acme/src/incoming.rs +142 -0
  29. data/crates/itsi_acme/src/jose.rs +161 -0
  30. data/crates/itsi_acme/src/lib.rs +142 -0
  31. data/crates/itsi_acme/src/resolver.rs +59 -0
  32. data/crates/itsi_acme/src/state.rs +424 -0
  33. data/crates/itsi_rb_helpers/src/lib.rs +4 -3
  34. data/crates/itsi_scheduler/Cargo.toml +1 -1
  35. data/crates/itsi_scheduler/src/itsi_scheduler.rs +8 -2
  36. data/crates/itsi_scheduler/src/lib.rs +1 -0
  37. data/crates/itsi_server/Cargo.toml +3 -3
  38. data/crates/itsi_server/src/lib.rs +2 -1
  39. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +20 -3
  40. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +11 -3
  41. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +255 -65
  42. data/crates/itsi_server/src/ruby_types/itsi_server.rs +3 -0
  43. data/crates/itsi_server/src/server/binds/bind.rs +3 -0
  44. data/crates/itsi_server/src/server/binds/listener.rs +44 -32
  45. data/crates/itsi_server/src/server/binds/tls/locked_dir_cache.rs +2 -2
  46. data/crates/itsi_server/src/server/binds/tls.rs +14 -6
  47. data/crates/itsi_server/src/server/middleware_stack/middleware.rs +33 -28
  48. data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +12 -5
  49. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +8 -1
  50. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +9 -1
  51. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +95 -37
  52. data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +11 -2
  53. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +39 -12
  54. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +36 -27
  55. data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  56. data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +12 -3
  57. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +74 -72
  58. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +15 -1
  59. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +11 -8
  60. data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +19 -11
  61. data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +5 -5
  62. data/crates/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +2 -2
  63. data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +31 -2
  64. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +17 -20
  65. data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +19 -8
  66. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +16 -37
  67. data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +22 -12
  68. data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +26 -11
  69. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +3 -3
  70. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +9 -2
  71. data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +14 -4
  72. data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +19 -0
  73. data/crates/itsi_server/src/server/middleware_stack/mod.rs +69 -35
  74. data/crates/itsi_server/src/server/mod.rs +1 -0
  75. data/crates/itsi_server/src/server/redirect_type.rs +26 -0
  76. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +30 -18
  77. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +77 -17
  78. data/crates/itsi_server/src/server/signal.rs +1 -0
  79. data/crates/itsi_server/src/server/size_limited_incoming.rs +6 -0
  80. data/crates/itsi_server/src/server/thread_worker.rs +6 -2
  81. data/crates/itsi_server/src/services/itsi_http_service.rs +20 -2
  82. data/crates/itsi_server/src/services/rate_limiter.rs +15 -4
  83. data/crates/itsi_server/src/services/static_file_server.rs +63 -47
  84. data/crates/itsi_tracing/src/lib.rs +80 -29
  85. data/docker/Dockerfile +12 -0
  86. data/docs/content/_index.md +17 -10
  87. data/docs/content/acknowledgements/_index.md +46 -0
  88. data/docs/content/configuration/_index.md +101 -0
  89. data/docs/content/contact/_index.md +14 -0
  90. data/docs/content/faqs/_index.md +29 -0
  91. data/docs/content/features/_index.md +291 -0
  92. data/docs/content/getting_started/_index.md +73 -0
  93. data/docs/content/getting_started/local_development.md +100 -0
  94. data/docs/content/getting_started/logging.md +23 -0
  95. data/docs/content/getting_started/running_itsi_in_production.md +26 -0
  96. data/docs/content/getting_started/signals.md +38 -0
  97. data/docs/content/itsi-server-100.png +0 -0
  98. data/docs/content/itsi_scheduler/_index.md +106 -0
  99. data/docs/content/itsi_scheduler/itsi-scheduler-100.png +0 -0
  100. data/docs/content/ruby-lsp.png +0 -0
  101. data/docs/content/ruby.svg +948 -0
  102. data/docs/content/utilities/_index.md +13 -0
  103. data/docs/content/utilities/config_file_testing.md +17 -0
  104. data/docs/content/utilities/passfile_generator.md +41 -0
  105. data/docs/content/utilities/route_testing.md +27 -0
  106. data/docs/content/utilities/secrets_management.md +30 -0
  107. data/docs/data/icons.yaml +949 -0
  108. data/docs/hugo.yaml +27 -28
  109. data/fairytale.txt +33 -0
  110. data/gems/scheduler/Cargo.lock +47 -47
  111. data/gems/scheduler/README.md +52 -24
  112. data/gems/scheduler/Rakefile +0 -4
  113. data/gems/scheduler/itsi-scheduler-100.png +0 -0
  114. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  115. data/gems/scheduler/lib/itsi/scheduler.rb +9 -4
  116. data/gems/scheduler/test/test_active_record.rb +12 -7
  117. data/gems/server/Cargo.lock +950 -239
  118. data/gems/server/README.md +2 -0
  119. data/gems/server/Rakefile +0 -4
  120. data/gems/server/exe/itsi +16 -5
  121. data/gems/server/lib/itsi/http_request/response_status_shortcodes.rb +2 -0
  122. data/gems/server/lib/itsi/http_request.rb +40 -9
  123. data/gems/server/lib/itsi/http_response.rb +2 -1
  124. data/gems/server/lib/itsi/passfile.rb +0 -1
  125. data/gems/server/lib/itsi/server/config/config_helpers.rb +105 -0
  126. data/gems/server/lib/itsi/server/config/dsl.rb +44 -411
  127. data/gems/server/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  128. data/gems/server/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  129. data/gems/server/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  130. data/gems/server/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  131. data/gems/server/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  132. data/gems/server/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  133. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  134. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  135. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  136. data/gems/server/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  137. data/gems/server/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  138. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  139. data/gems/server/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  140. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  141. data/gems/server/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  142. data/gems/server/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  143. data/gems/server/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  144. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  145. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  146. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  147. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  148. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  149. data/gems/server/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  150. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  151. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  152. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  153. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  154. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  155. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  156. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  157. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  158. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  159. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  160. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  161. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  162. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  163. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  164. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  165. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  166. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  167. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  168. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  169. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  170. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  171. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  172. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  173. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  174. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  175. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  176. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  177. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  178. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  179. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  180. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  181. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  182. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  183. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  184. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  185. data/gems/server/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  186. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  187. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  188. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  189. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  190. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  191. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  192. data/gems/server/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  193. data/gems/server/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  194. data/gems/server/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  195. data/gems/server/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  196. data/gems/server/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  197. data/gems/server/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  198. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  199. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  200. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  201. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  202. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  203. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  204. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  205. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  206. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  207. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  208. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  209. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  210. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  211. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  212. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  213. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  214. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  215. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  216. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  217. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  218. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  219. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  220. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  221. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  222. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  223. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  224. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  225. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  226. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  227. data/gems/server/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  228. data/gems/server/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  229. data/gems/server/lib/itsi/server/config/known_paths.rb +20 -0
  230. data/gems/server/lib/itsi/server/config/middleware/_index.md +56 -0
  231. data/gems/server/lib/itsi/server/config/middleware/allow_list.md +46 -0
  232. data/gems/server/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  233. data/gems/server/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  234. data/gems/server/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  235. data/gems/server/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  236. data/gems/server/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
  237. data/gems/server/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  238. data/gems/server/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  239. data/gems/server/lib/itsi/server/config/middleware/cache_control.md +78 -0
  240. data/gems/server/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  241. data/gems/server/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  242. data/gems/server/lib/itsi/server/config/middleware/compression.md +50 -0
  243. data/gems/server/lib/itsi/server/config/middleware/compression.rb +37 -0
  244. data/gems/server/lib/itsi/server/config/middleware/cors.md +93 -0
  245. data/gems/server/lib/itsi/server/config/middleware/cors.rb +32 -0
  246. data/gems/server/lib/itsi/server/config/middleware/csp.md +37 -0
  247. data/gems/server/lib/itsi/server/config/middleware/csp.rb +44 -0
  248. data/gems/server/lib/itsi/server/config/middleware/deny_list.md +45 -0
  249. data/gems/server/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  250. data/gems/server/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
  251. data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  252. data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  253. data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  254. data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
  255. data/gems/server/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
  256. data/gems/server/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  257. data/gems/server/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
  258. data/gems/server/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  259. data/gems/server/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  260. data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  261. data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
  262. data/gems/server/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  263. data/gems/server/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
  264. data/gems/server/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  265. data/gems/server/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
  266. data/gems/server/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  267. data/gems/server/lib/itsi/server/config/middleware/error_response.md +61 -0
  268. data/gems/server/lib/itsi/server/config/middleware/error_response.rb +36 -0
  269. data/gems/server/lib/itsi/server/config/middleware/etag.md +59 -0
  270. data/gems/server/lib/itsi/server/config/middleware/etag.rb +27 -0
  271. data/gems/server/lib/itsi/server/config/middleware/grpc.md +172 -0
  272. data/gems/server/lib/itsi/server/config/middleware/grpc.rb +54 -0
  273. data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  274. data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  275. data/gems/server/lib/itsi/server/config/middleware/location.md +107 -0
  276. data/gems/server/lib/itsi/server/config/middleware/location.rb +99 -0
  277. data/gems/server/lib/itsi/server/config/middleware/log_requests.md +65 -0
  278. data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  279. data/gems/server/lib/itsi/server/config/middleware/max_body.md +18 -0
  280. data/gems/server/lib/itsi/server/config/middleware/max_body.rb +21 -0
  281. data/gems/server/lib/itsi/server/config/middleware/proxy.md +62 -0
  282. data/gems/server/lib/itsi/server/config/middleware/proxy.rb +41 -0
  283. data/gems/server/lib/itsi/server/config/middleware/rackup_file.md +54 -0
  284. data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
  285. data/gems/server/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  286. data/gems/server/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  287. data/gems/server/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  288. data/gems/server/lib/itsi/server/config/middleware/redirect.md +55 -0
  289. data/gems/server/lib/itsi/server/config/middleware/redirect.rb +25 -0
  290. data/gems/server/lib/itsi/server/config/middleware/request_headers.md +34 -0
  291. data/gems/server/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  292. data/gems/server/lib/itsi/server/config/middleware/response_headers.md +33 -0
  293. data/gems/server/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  294. data/gems/server/lib/itsi/server/config/middleware/run.md +60 -0
  295. data/gems/server/lib/itsi/server/config/middleware/run.rb +43 -0
  296. data/gems/server/lib/itsi/server/config/middleware/static_assets.md +73 -0
  297. data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +87 -0
  298. data/gems/server/lib/itsi/server/config/middleware/static_response.md +44 -0
  299. data/gems/server/lib/itsi/server/config/middleware/static_response.rb +29 -0
  300. data/gems/server/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
  301. data/gems/server/lib/itsi/server/config/middleware/token_source.rb +32 -0
  302. data/gems/server/lib/itsi/server/config/middleware.rb +13 -0
  303. data/gems/server/lib/itsi/server/config/option.rb +14 -0
  304. data/gems/server/lib/itsi/server/config/options/_index.md +37 -0
  305. data/gems/server/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  306. data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
  307. data/gems/server/lib/itsi/server/config/options/bind.md +71 -0
  308. data/gems/server/lib/itsi/server/config/options/bind.rb +26 -0
  309. data/gems/server/lib/itsi/server/config/options/certificates.md +65 -0
  310. data/gems/server/lib/itsi/server/config/options/daemonize.md +14 -0
  311. data/gems/server/lib/itsi/server/config/options/daemonize.rb +19 -0
  312. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  313. data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  314. data/gems/server/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  315. data/gems/server/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  316. data/gems/server/lib/itsi/server/config/options/hooks/_index.md +11 -0
  317. data/gems/server/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  318. data/gems/server/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  319. data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  320. data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  321. data/gems/server/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  322. data/gems/server/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  323. data/gems/server/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  324. data/gems/server/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  325. data/gems/server/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  326. data/gems/server/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  327. data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  328. data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  329. data/gems/server/lib/itsi/server/config/options/include.md +20 -0
  330. data/gems/server/lib/itsi/server/config/options/include.rb +36 -0
  331. data/gems/server/lib/itsi/server/config/options/listen_backlog.md +11 -0
  332. data/gems/server/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  333. data/gems/server/lib/itsi/server/config/options/log_format.md +18 -0
  334. data/gems/server/lib/itsi/server/config/options/log_format.rb +19 -0
  335. data/gems/server/lib/itsi/server/config/options/log_level.md +34 -0
  336. data/gems/server/lib/itsi/server/config/options/log_level.rb +20 -0
  337. data/gems/server/lib/itsi/server/config/options/log_target.md +38 -0
  338. data/gems/server/lib/itsi/server/config/options/log_target.rb +19 -0
  339. data/gems/server/lib/itsi/server/config/options/log_target_filters.md +17 -0
  340. data/gems/server/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  341. data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  342. data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  343. data/gems/server/lib/itsi/server/config/options/nodelay.md +16 -0
  344. data/gems/server/lib/itsi/server/config/options/nodelay.rb +19 -0
  345. data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  346. data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  347. data/gems/server/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  348. data/gems/server/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  349. data/gems/server/lib/itsi/server/config/options/preload.md +21 -0
  350. data/gems/server/lib/itsi/server/config/options/preload.rb +18 -0
  351. data/gems/server/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  352. data/gems/server/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  353. data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  354. data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  355. data/gems/server/lib/itsi/server/config/options/request_timeout.md +23 -0
  356. data/gems/server/lib/itsi/server/config/options/request_timeout.rb +19 -0
  357. data/gems/server/lib/itsi/server/config/options/reuse_address.md +16 -0
  358. data/gems/server/lib/itsi/server/config/options/reuse_address.rb +19 -0
  359. data/gems/server/lib/itsi/server/config/options/reuse_port.md +16 -0
  360. data/gems/server/lib/itsi/server/config/options/reuse_port.rb +19 -0
  361. data/gems/server/lib/itsi/server/config/options/scheduler_threads.md +34 -0
  362. data/gems/server/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  363. data/gems/server/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  364. data/gems/server/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  365. data/gems/server/lib/itsi/server/config/options/stream_body.md +32 -0
  366. data/gems/server/lib/itsi/server/config/options/stream_body.rb +18 -0
  367. data/gems/server/lib/itsi/server/config/options/threads.md +44 -0
  368. data/gems/server/lib/itsi/server/config/options/threads.rb +17 -0
  369. data/gems/server/lib/itsi/server/config/options/watch.md +16 -0
  370. data/gems/server/lib/itsi/server/config/options/watch.rb +28 -0
  371. data/gems/server/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  372. data/gems/server/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  373. data/gems/server/lib/itsi/server/config/options/workers.md +42 -0
  374. data/gems/server/lib/itsi/server/config/options/workers.rb +17 -0
  375. data/gems/server/lib/itsi/server/config/typed_struct.rb +242 -0
  376. data/gems/server/lib/itsi/server/config.rb +134 -11
  377. data/gems/server/lib/itsi/server/default_config/Itsi.rb +3 -3
  378. data/gems/server/lib/itsi/server/grpc/grpc_call.rb +1 -1
  379. data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +11 -4
  380. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -3
  381. data/gems/server/lib/itsi/server/route_tester.rb +58 -8
  382. data/gems/server/lib/itsi/server/signal_trap.rb +5 -1
  383. data/gems/server/lib/itsi/server/typed_handlers/param_parser.rb +14 -18
  384. data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +6 -5
  385. data/gems/server/lib/itsi/server/typed_handlers.rb +12 -4
  386. data/gems/server/lib/itsi/server/version.rb +1 -1
  387. data/gems/server/lib/itsi/server.rb +122 -17
  388. data/gems/server/lib/ruby_lsp/itsi/addon.rb +66 -48
  389. data/gems/server/test/helpers/test_helper.rb +130 -11
  390. data/gems/server/test/middleware/allow_list.rb +128 -0
  391. data/gems/server/test/middleware/auth_api_key.rb +141 -0
  392. data/gems/server/test/middleware/auth_basic.rb +91 -0
  393. data/gems/server/test/middleware/auth_jwt.rb +214 -0
  394. data/gems/server/test/middleware/cache_control.rb +82 -0
  395. data/gems/server/test/middleware/cidr_to_regex.rb +46 -0
  396. data/gems/server/test/middleware/compression.rb +89 -0
  397. data/gems/server/test/middleware/cors.rb +113 -0
  398. data/gems/server/test/middleware/csp.rb +62 -0
  399. data/gems/server/test/middleware/deny_list.rb +131 -0
  400. data/gems/server/test/middleware/endpoint.rb +300 -0
  401. data/gems/server/test/middleware/etag.rb +75 -0
  402. data/gems/server/test/middleware/grpc/grpc.rb +158 -0
  403. data/gems/server/test/middleware/grpc/test_service.proto +32 -0
  404. data/gems/server/test/middleware/grpc/test_service_impl.rb +28 -0
  405. data/gems/server/test/middleware/grpc/test_service_pb.rb +18 -0
  406. data/gems/server/test/middleware/grpc/test_service_services_pb.rb +30 -0
  407. data/gems/server/test/middleware/header_interpolation.rb +35 -0
  408. data/gems/server/test/middleware/intrusion_protection.rb +259 -0
  409. data/gems/server/test/middleware/location.rb +220 -0
  410. data/gems/server/test/middleware/max_body.rb +20 -0
  411. data/gems/server/test/middleware/proxy.rb +415 -0
  412. data/gems/server/test/middleware/rate_limit.rb +211 -0
  413. data/gems/server/test/middleware/redirect.rb +85 -0
  414. data/gems/server/test/middleware/request_headers.rb +50 -0
  415. data/gems/server/test/middleware/response_headers.rb +50 -0
  416. data/gems/server/test/middleware/static_assets.rb +374 -0
  417. data/gems/server/test/middleware/static_response.rb +56 -0
  418. data/gems/server/test/middleware/string_rewrite.rb +112 -0
  419. data/gems/server/test/middleware/test_log_requests.rb +17 -0
  420. data/gems/server/test/options/bind.rb +47 -0
  421. data/gems/server/test/options/header_read_timeout.rb +23 -0
  422. data/gems/server/test/options/test_request_timeout.rb +16 -0
  423. data/gems/server/test/options/test_threads.rb +15 -0
  424. data/gems/server/test/options/test_workers.rb +16 -0
  425. data/gems/server/test/{test_itsi_server.rb → rack/test_rack_server.rb} +82 -95
  426. data/grpc_test/Itsi.rb +11 -0
  427. data/grpc_test/echo.proto +14 -0
  428. data/grpc_test/echo_pb.rb +16 -0
  429. data/grpc_test/echo_service_impl.rb +8 -0
  430. data/{sandbox/itsi_file/echo_service_nonitsi → grpc_test}/echo_services_pb.rb +0 -7
  431. data/itsi-scheduler-100.png +0 -0
  432. data/itsi-server-100.png +0 -0
  433. data/lib/itsi/version.rb +1 -1
  434. data/tasks.txt +17 -66
  435. metadata +352 -217
  436. data/crates/_index.md +0 -0
  437. data/crates/itsi_server/src/ruby_types/README.md +0 -21
  438. data/crates/itsi_server/test.md +0 -14
  439. data/docs/Itsi.rb +0 -17
  440. data/docs/content/about.md +0 -6
  441. data/docs/content/docs/_index.md +0 -18
  442. data/docs/content/docs/first-page.md +0 -9
  443. data/docs/content/docs/folder/_index.md +0 -10
  444. data/docs/content/docs/folder/leaf.md +0 -7
  445. data/foo/Itsi.rb +0 -122
  446. data/gems/_index.md +0 -18
  447. data/gems/scheduler/CHANGELOG.md +0 -5
  448. data/gems/scheduler/CODE_OF_CONDUCT.md +0 -139
  449. data/gems/scheduler/LICENSE.txt +0 -21
  450. data/gems/scheduler/_index.md +0 -7
  451. data/gems/server/CHANGELOG.md +0 -10
  452. data/gems/server/CODE_OF_CONDUCT.md +0 -139
  453. data/gems/server/LICENSE.txt +0 -21
  454. data/gems/server/_index.md +0 -6
  455. data/gems/server/lib/itsi/server/default_config/Itsi-rackup.rb +0 -119
  456. data/sandbox/README.md +0 -5
  457. data/sandbox/deploy/main.tf +0 -238
  458. data/sandbox/deploy/outputs.tf +0 -4
  459. data/sandbox/deploy/vars.tf +0 -11
  460. data/sandbox/falcon_benchmark/Gemfile +0 -10
  461. data/sandbox/falcon_benchmark/Gemfile.lock +0 -140
  462. data/sandbox/falcon_benchmark/config.ru +0 -54
  463. data/sandbox/itsi_file/Gemfile +0 -13
  464. data/sandbox/itsi_file/Gemfile.lock +0 -111
  465. data/sandbox/itsi_file/Itsi.rb +0 -474
  466. data/sandbox/itsi_file/call.json +0 -1
  467. data/sandbox/itsi_file/echo_client/Gemfile +0 -10
  468. data/sandbox/itsi_file/echo_client/Gemfile.lock +0 -27
  469. data/sandbox/itsi_file/echo_client/README.md +0 -95
  470. data/sandbox/itsi_file/echo_client/echo_client.rb +0 -164
  471. data/sandbox/itsi_file/echo_client/gen_proto.sh +0 -17
  472. data/sandbox/itsi_file/echo_client/lib/echo_pb.rb +0 -16
  473. data/sandbox/itsi_file/echo_client/lib/echo_services_pb.rb +0 -29
  474. data/sandbox/itsi_file/echo_client/run_client.rb +0 -64
  475. data/sandbox/itsi_file/echo_client/test_compressions.sh +0 -20
  476. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile +0 -10
  477. data/sandbox/itsi_file/echo_service_nonitsi/Gemfile.lock +0 -79
  478. data/sandbox/itsi_file/echo_service_nonitsi/echo.proto +0 -26
  479. data/sandbox/itsi_file/echo_service_nonitsi/echo_pb.rb +0 -16
  480. data/sandbox/itsi_file/echo_service_nonitsi/server.rb +0 -52
  481. data/sandbox/itsi_file/error.html +0 -2
  482. data/sandbox/itsi_file/organisations_controller.rb +0 -20
  483. data/sandbox/itsi_file/public/assets/image.png +0 -0
  484. data/sandbox/itsi_sandbox_async/Gemfile +0 -10
  485. data/sandbox/itsi_sandbox_async/Gemfile.lock +0 -69
  486. data/sandbox/itsi_sandbox_async/config.ru +0 -9
  487. data/sandbox/itsi_sandbox_hanami/.env +0 -2
  488. data/sandbox/itsi_sandbox_hanami/.gitignore +0 -6
  489. data/sandbox/itsi_sandbox_hanami/.rspec +0 -1
  490. data/sandbox/itsi_sandbox_hanami/Gemfile +0 -49
  491. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +0 -440
  492. data/sandbox/itsi_sandbox_hanami/Guardfile +0 -9
  493. data/sandbox/itsi_sandbox_hanami/Procfile.dev +0 -2
  494. data/sandbox/itsi_sandbox_hanami/README.md +0 -1
  495. data/sandbox/itsi_sandbox_hanami/Rakefile +0 -3
  496. data/sandbox/itsi_sandbox_hanami/app/action.rb +0 -12
  497. data/sandbox/itsi_sandbox_hanami/app/actions/.keep +0 -0
  498. data/sandbox/itsi_sandbox_hanami/app/assets/css/app.css +0 -5
  499. data/sandbox/itsi_sandbox_hanami/app/assets/images/favicon.ico +0 -0
  500. data/sandbox/itsi_sandbox_hanami/app/assets/js/app.js +0 -1
  501. data/sandbox/itsi_sandbox_hanami/app/db/relation.rb +0 -10
  502. data/sandbox/itsi_sandbox_hanami/app/db/repo.rb +0 -10
  503. data/sandbox/itsi_sandbox_hanami/app/db/struct.rb +0 -10
  504. data/sandbox/itsi_sandbox_hanami/app/operation.rb +0 -9
  505. data/sandbox/itsi_sandbox_hanami/app/relations/.keep +0 -0
  506. data/sandbox/itsi_sandbox_hanami/app/repos/.keep +0 -0
  507. data/sandbox/itsi_sandbox_hanami/app/structs/.keep +0 -0
  508. data/sandbox/itsi_sandbox_hanami/app/templates/layouts/app.html.erb +0 -14
  509. data/sandbox/itsi_sandbox_hanami/app/view.rb +0 -9
  510. data/sandbox/itsi_sandbox_hanami/app/views/helpers.rb +0 -10
  511. data/sandbox/itsi_sandbox_hanami/bin/dev +0 -8
  512. data/sandbox/itsi_sandbox_hanami/config/app.rb +0 -8
  513. data/sandbox/itsi_sandbox_hanami/config/assets.js +0 -16
  514. data/sandbox/itsi_sandbox_hanami/config/db/migrate/.keep +0 -0
  515. data/sandbox/itsi_sandbox_hanami/config/db/seeds.rb +0 -15
  516. data/sandbox/itsi_sandbox_hanami/config/puma.rb +0 -47
  517. data/sandbox/itsi_sandbox_hanami/config/routes.rb +0 -7
  518. data/sandbox/itsi_sandbox_hanami/config/settings.rb +0 -9
  519. data/sandbox/itsi_sandbox_hanami/config.ru +0 -5
  520. data/sandbox/itsi_sandbox_hanami/db/.keep +0 -0
  521. data/sandbox/itsi_sandbox_hanami/lib/itsi_hanami/types.rb +0 -11
  522. data/sandbox/itsi_sandbox_hanami/lib/tasks/.keep +0 -0
  523. data/sandbox/itsi_sandbox_hanami/package-lock.json +0 -946
  524. data/sandbox/itsi_sandbox_hanami/package.json +0 -8
  525. data/sandbox/itsi_sandbox_hanami/spec/requests/root_spec.rb +0 -11
  526. data/sandbox/itsi_sandbox_hanami/spec/spec_helper.rb +0 -9
  527. data/sandbox/itsi_sandbox_hanami/spec/support/db/cleaning.rb +0 -42
  528. data/sandbox/itsi_sandbox_hanami/spec/support/db.rb +0 -10
  529. data/sandbox/itsi_sandbox_hanami/spec/support/features.rb +0 -5
  530. data/sandbox/itsi_sandbox_hanami/spec/support/operations.rb +0 -8
  531. data/sandbox/itsi_sandbox_hanami/spec/support/requests.rb +0 -13
  532. data/sandbox/itsi_sandbox_hanami/spec/support/rspec.rb +0 -61
  533. data/sandbox/itsi_sandbox_rack/Gemfile +0 -17
  534. data/sandbox/itsi_sandbox_rack/Gemfile.lock +0 -153
  535. data/sandbox/itsi_sandbox_rack/config.ru +0 -5
  536. data/sandbox/itsi_sandbox_rack_lint/Gemfile +0 -7
  537. data/sandbox/itsi_sandbox_rack_lint/Gemfile.lock +0 -27
  538. data/sandbox/itsi_sandbox_rack_lint/config.ru +0 -3
  539. data/sandbox/itsi_sandbox_rails/.dockerignore +0 -48
  540. data/sandbox/itsi_sandbox_rails/.gitattributes +0 -9
  541. data/sandbox/itsi_sandbox_rails/.github/dependabot.yml +0 -12
  542. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +0 -90
  543. data/sandbox/itsi_sandbox_rails/.gitignore +0 -35
  544. data/sandbox/itsi_sandbox_rails/.rubocop.yml +0 -8
  545. data/sandbox/itsi_sandbox_rails/.ruby-version +0 -1
  546. data/sandbox/itsi_sandbox_rails/Dockerfile +0 -69
  547. data/sandbox/itsi_sandbox_rails/Gemfile +0 -66
  548. data/sandbox/itsi_sandbox_rails/Gemfile.lock +0 -429
  549. data/sandbox/itsi_sandbox_rails/README.md +0 -24
  550. data/sandbox/itsi_sandbox_rails/Rakefile +0 -6
  551. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +0 -4
  552. data/sandbox/itsi_sandbox_rails/app/assets/images/.keep +0 -0
  553. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +0 -15
  554. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +0 -4
  555. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +0 -4
  556. data/sandbox/itsi_sandbox_rails/app/controllers/application_controller.rb +0 -4
  557. data/sandbox/itsi_sandbox_rails/app/controllers/concerns/.keep +0 -0
  558. data/sandbox/itsi_sandbox_rails/app/controllers/home_controller.rb +0 -66
  559. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +0 -40
  560. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -29
  561. data/sandbox/itsi_sandbox_rails/app/helpers/application_helper.rb +0 -2
  562. data/sandbox/itsi_sandbox_rails/app/javascript/application.js +0 -3
  563. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/application.js +0 -9
  564. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/hello_controller.js +0 -7
  565. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/index.js +0 -4
  566. data/sandbox/itsi_sandbox_rails/app/jobs/application_job.rb +0 -7
  567. data/sandbox/itsi_sandbox_rails/app/mailers/application_mailer.rb +0 -4
  568. data/sandbox/itsi_sandbox_rails/app/models/application_record.rb +0 -3
  569. data/sandbox/itsi_sandbox_rails/app/models/concerns/.keep +0 -0
  570. data/sandbox/itsi_sandbox_rails/app/models/post.rb +0 -2
  571. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +0 -23
  572. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.html.erb +0 -13
  573. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.text.erb +0 -1
  574. data/sandbox/itsi_sandbox_rails/app/views/pwa/manifest.json.erb +0 -22
  575. data/sandbox/itsi_sandbox_rails/app/views/pwa/service-worker.js +0 -26
  576. data/sandbox/itsi_sandbox_rails/bin/brakeman +0 -7
  577. data/sandbox/itsi_sandbox_rails/bin/bundle +0 -109
  578. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +0 -13
  579. data/sandbox/itsi_sandbox_rails/bin/importmap +0 -4
  580. data/sandbox/itsi_sandbox_rails/bin/rails +0 -4
  581. data/sandbox/itsi_sandbox_rails/bin/rake +0 -4
  582. data/sandbox/itsi_sandbox_rails/bin/rubocop +0 -8
  583. data/sandbox/itsi_sandbox_rails/bin/setup +0 -37
  584. data/sandbox/itsi_sandbox_rails/config/application.rb +0 -27
  585. data/sandbox/itsi_sandbox_rails/config/boot.rb +0 -4
  586. data/sandbox/itsi_sandbox_rails/config/cable.yml +0 -10
  587. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +0 -1
  588. data/sandbox/itsi_sandbox_rails/config/database.yml +0 -30
  589. data/sandbox/itsi_sandbox_rails/config/environment.rb +0 -5
  590. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +0 -82
  591. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +0 -106
  592. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +0 -67
  593. data/sandbox/itsi_sandbox_rails/config/importmap.rb +0 -7
  594. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +0 -12
  595. data/sandbox/itsi_sandbox_rails/config/initializers/content_security_policy.rb +0 -25
  596. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +0 -8
  597. data/sandbox/itsi_sandbox_rails/config/initializers/inflections.rb +0 -16
  598. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +0 -13
  599. data/sandbox/itsi_sandbox_rails/config/locales/en.yml +0 -31
  600. data/sandbox/itsi_sandbox_rails/config/puma.rb +0 -34
  601. data/sandbox/itsi_sandbox_rails/config/routes.rb +0 -23
  602. data/sandbox/itsi_sandbox_rails/config/storage.yml +0 -34
  603. data/sandbox/itsi_sandbox_rails/config.ru +0 -6
  604. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +0 -10
  605. data/sandbox/itsi_sandbox_rails/db/schema.rb +0 -23
  606. data/sandbox/itsi_sandbox_rails/db/seeds.rb +0 -9
  607. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  608. data/sandbox/itsi_sandbox_rails/lib/tasks/.keep +0 -0
  609. data/sandbox/itsi_sandbox_rails/log/.keep +0 -0
  610. data/sandbox/itsi_sandbox_rails/public/404.html +0 -67
  611. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +0 -66
  612. data/sandbox/itsi_sandbox_rails/public/422.html +0 -67
  613. data/sandbox/itsi_sandbox_rails/public/500.html +0 -66
  614. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  615. data/sandbox/itsi_sandbox_rails/public/icon.svg +0 -3
  616. data/sandbox/itsi_sandbox_rails/public/robots.txt +0 -1
  617. data/sandbox/itsi_sandbox_rails/storage/.keep +0 -0
  618. data/sandbox/itsi_sandbox_rails/test/application_system_test_case.rb +0 -5
  619. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +0 -13
  620. data/sandbox/itsi_sandbox_rails/test/controllers/.keep +0 -0
  621. data/sandbox/itsi_sandbox_rails/test/fixtures/files/.keep +0 -0
  622. data/sandbox/itsi_sandbox_rails/test/helpers/.keep +0 -0
  623. data/sandbox/itsi_sandbox_rails/test/integration/.keep +0 -0
  624. data/sandbox/itsi_sandbox_rails/test/mailers/.keep +0 -0
  625. data/sandbox/itsi_sandbox_rails/test/models/.keep +0 -0
  626. data/sandbox/itsi_sandbox_rails/test/system/.keep +0 -0
  627. data/sandbox/itsi_sandbox_rails/test/test_helper.rb +0 -15
  628. data/sandbox/itsi_sandbox_rails/tmp/.keep +0 -0
  629. data/sandbox/itsi_sandbox_rails/tmp/pids/.keep +0 -0
  630. data/sandbox/itsi_sandbox_rails/tmp/storage/.keep +0 -0
  631. data/sandbox/itsi_sandbox_rails/vendor/.keep +0 -0
  632. data/sandbox/itsi_sandbox_rails/vendor/javascript/.keep +0 -0
  633. data/sandbox/itsi_sandbox_roda/Gemfile +0 -5
  634. data/sandbox/itsi_sandbox_roda/Gemfile.lock +0 -37
  635. data/sandbox/itsi_sandbox_roda/config.ru +0 -39
  636. data/sandbox/itsi_sinatra/Gemfile +0 -9
  637. data/sandbox/itsi_sinatra/Gemfile.lock +0 -81
  638. data/sandbox/itsi_sinatra/app.rb +0 -8
  639. data/sandbox/pebble/docker-compose.yml +0 -11
  640. data/sandbox/static_files/.env +0 -1
  641. data/sandbox/static_files/404.html +0 -25
  642. data/sandbox/static_files/_DSC0102.NEF.jpg +0 -0
  643. data/sandbox/static_files/about.html +0 -68
  644. data/sandbox/static_files/tiny.html +0 -1
  645. data/sandbox/static_files/writebook.zip +0 -0
@@ -23,21 +23,21 @@ module Itsi
23
23
  case v
24
24
  when true, 'true', '1', 1 then true
25
25
  when false, 'false', '0', 0 then false
26
- else raise "Cannot cast #{v.inspect} to Boolean"
26
+ else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
27
27
  end
28
28
  },
29
29
  FalseClass => ->(v){
30
30
  case v
31
31
  when true, 'true', '1', 1 then true
32
32
  when false, 'false', '0', 0 then false
33
- else raise "Cannot cast #{v.inspect} to Boolean"
33
+ else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
34
34
  end
35
35
  },
36
36
  :Boolean => ->(v){
37
37
  case v
38
38
  when true, 'true', '1', 1 then true
39
39
  when false, 'false', '0', 0 then false
40
- else raise "Cannot cast #{v.inspect} to Boolean"
40
+ else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
41
41
  end
42
42
  },
43
43
  Date => ->(v){ Date.parse(v.to_s) },
@@ -45,17 +45,6 @@ module Itsi
45
45
  DateTime => ->(v){ DateTime.parse(v.to_s) }
46
46
  }.compare_by_identity
47
47
 
48
- # Extracts the expected type and required flag from a schema definition.
49
- def extract_schema(schema_def)
50
- if schema_def.is_a?(Hash) && schema_def.key?(:_type)
51
- expected_type = schema_def[:_type]
52
- required = schema_def.fetch(:required, true)
53
- [expected_type, required]
54
- else
55
- [schema_def, true]
56
- end
57
- end
58
-
59
48
  # Preprocess the schema into fixed keys (as symbols) and regex keys.
60
49
  # Memoizes the result based on the schema.
61
50
  def processed_schema(schema)
@@ -63,8 +52,9 @@ module Itsi
63
52
  @@schema_cache[schema] ||= begin
64
53
  fixed = {}
65
54
  regex = []
55
+ required_params = schema[:_required] || []
66
56
  schema.each do |k, schema_def|
67
- expected_type, required = extract_schema(schema_def)
57
+ expected_type, required = schema_def, required_params.include?(k)
68
58
  if k.is_a?(Regexp)
69
59
  regex << [k, [expected_type, required]]
70
60
  else
@@ -179,16 +169,22 @@ module Itsi
179
169
  end
180
170
 
181
171
  # Process regex keys (only string keys not already handled as fixed keys).
182
- params.keys.select { |k| k.is_a?(String) }.each do |key|
172
+ params.keys.each do |key|
173
+ if key == :_required
174
+ params.delete(key)
175
+ next
176
+ end
183
177
  next if fixed_schema.has_key?(key.to_sym) || fixed_schema.has_key?(key)
184
- regex_schema.each do |regex, (expected_type, _required)|
178
+ unless regex_schema.find do |regex, (expected_type, _required)|
185
179
  if regex.match(key)
186
180
  new_path = path + [key]
187
181
  err = cast_value!(params, key, expected_type, new_path)
188
182
  errors << err if err
189
- break # only use the first matching regex
183
+ true # only use the first matching regex
190
184
  end
191
185
  end
186
+ params.delete(key)
187
+ end
192
188
  end
193
189
 
194
190
  raise ValidationError.new(errors) unless errors.empty?
@@ -6,17 +6,18 @@ module Itsi
6
6
 
7
7
 
8
8
  def self.extract_expr_from_source_location(proc)
9
- source_lines = IO.readlines(proc.source_location.first)
9
+ source_location = proc.source_location
10
+ source_lines = IO.readlines(source_location.first)
10
11
 
11
12
  proc_line = source_location.last - 1
12
13
  first_line = source_lines[proc_line]
13
- binding.b
14
- until first_line =~ /(?:lambda|proc|->|def|.*?do\s*\|)/ || proc_line.zero?
14
+
15
+ until first_line =~ /(?:lambda|proc|->|def|.*?do\s*|.*?\{.*?\|)/ || proc_line.zero?
15
16
  proc_line -= 1
16
17
  first_line = source_lines[proc_line]
17
18
  end
18
19
  lines = source_lines[proc_line..]
19
- lines[0] = lines[0][/(?:lambda|proc|->|def|.*?do\s*\|).*/]
20
+ lines[0] = lines[0][/(?:lambda|proc|->|def|.*?do\s+|.*?\{.*?\|).*/]
20
21
  src_str = lines.first << "\n"
21
22
  intermediate = Prism.parse(src_str)
22
23
 
@@ -47,7 +48,7 @@ module Itsi
47
48
 
48
49
  [requireds.length, keywords]
49
50
  rescue
50
- [ proc.parameters.first&.length || 0, {}]
51
+ [ proc.parameters.select{|p| p == :req }&.length || 0, {}]
51
52
  end
52
53
  end
53
54
  end
@@ -5,10 +5,18 @@ module Itsi
5
5
  class Server
6
6
  module TypedHandlers
7
7
  def self.handler_for(proc, input_schema)
8
- input_schema = proc.binding.eval(input_schema) if input_schema
9
- lambda do |req|
10
- req.params(input_schema) do |params|
11
- proc.call(req, params: params)
8
+ if input_schema
9
+ input_schema = proc.binding.eval(input_schema)
10
+ lambda do |req|
11
+ req.params(input_schema) do |params|
12
+ proc.call(req, params: params)
13
+ end
14
+ end
15
+ else
16
+ lambda do |req|
17
+ req.params do |params|
18
+ proc.call(req, params)
19
+ end
12
20
  end
13
21
  end
14
22
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Itsi
4
4
  class Server
5
- VERSION = "0.1.19"
5
+ VERSION = "0.2.2"
6
6
  end
7
7
  end
@@ -17,6 +17,9 @@ require_relative "http_response"
17
17
  require_relative "passfile"
18
18
  require_relative "../shell_completions/completions"
19
19
 
20
+ require "securerandom"
21
+ require "fileutils"
22
+
20
23
  module Itsi
21
24
  class Server
22
25
  extend RackInterface
@@ -26,26 +29,42 @@ module Itsi
26
29
  class << self
27
30
 
28
31
  def running?
29
- !!@running
32
+ @running && !@running.empty?
30
33
  end
31
34
 
32
35
  def start_in_background_thread(cli_params = {}, &blk)
33
- @background_thread = start(cli_params, background: true, &blk)
36
+ @background_threads ||= []
37
+ server, background_thread = start(cli_params, background: true, &blk)
38
+ @background_threads << background_thread
39
+ server
34
40
  end
35
41
 
36
42
  def start(cli_params, background: false, &blk)
37
43
  itsi_file = Itsi::Server::Config.config_file_path(cli_params[:config_file])
44
+ Itsi.log_debug "Constructing server #{cli_params}: #{itsi_file}"
38
45
  server = new(cli_params, itsi_file, blk)
39
46
  previous_handler = Signal.trap(:INT, :DEFAULT)
40
47
  run = lambda do
48
+ @running ||= []
49
+ @running << server
50
+
51
+ if cli_params[:daemonize]
52
+ Itsi.log_info("Itsi is running in the background. Writing pid to #{Itsi::Server::Config.pid_file_path}")
53
+ Itsi.log_info("To stop Itsi, run 'itsi stop' from this directory.")
54
+ Process.daemon(true, false)
55
+ end
41
56
  write_pid
42
- @running = server
57
+
58
+ Itsi.log_info "Starting Itsi..."
43
59
  server.start
44
- @running = false
60
+ @running.delete(server)
45
61
  Signal.trap(:INT, previous_handler)
46
62
  server
47
63
  end
48
- background ? Thread.new(&run) : run[]
64
+ background ? [server, Thread.new(&run)] : run[]
65
+ rescue Exception => e
66
+ Itsi.log_error e.message
67
+ raise e
49
68
  end
50
69
 
51
70
  def static(cli_params)
@@ -55,30 +74,45 @@ module Itsi
55
74
  def stop
56
75
  return unless pid = get_pid
57
76
  Process.kill(:INT, pid)
77
+ i = 0
78
+ while i < 10
79
+ sleep 0.25
80
+ unless get_pid(false)
81
+ puts "Itsi stopped"
82
+ break
83
+ end
84
+ i += 1
85
+ end
58
86
  end
59
87
 
60
- def stop_background_thread
61
- @running&.stop
62
- @background_thread&.join
88
+ def stop_background_threads
89
+ @running && @running.each(&:stop)
90
+ @background_threads&.each(&:join)
91
+ @background_threads = []
92
+ @running = []
63
93
  end
64
94
 
65
95
  def write_pid
66
96
  File.write(Itsi::Server::Config.pid_file_path, Process.pid)
67
97
  end
68
98
 
69
- def get_pid
99
+ def get_pid(warn=true)
70
100
  pid = File.read(Itsi::Server::Config.pid_file_path).to_i
71
101
  if Process.kill(0, pid)
72
102
  pid
73
103
  else
74
- puts "No server running"
104
+ warn ? puts("No server running") : nil
75
105
  nil
76
106
  end
77
107
  rescue StandardError
78
- puts "No server running"
108
+ warn ? puts("No server running") : nil
79
109
  nil
80
110
  end
81
111
 
112
+ def test
113
+ Itsi::Server::Config.test!(cli_params = {})
114
+ end
115
+
82
116
  def init
83
117
  Config.write_default
84
118
  end
@@ -97,7 +131,7 @@ module Itsi
97
131
 
98
132
  def passfile(options, subcmd)
99
133
  filename = options[:passfile]
100
- unless filename
134
+ unless filename || subcmd == 'echo'
101
135
  puts "Error: passfile not set. Use --passfile option to provide a path to a file containing hashed credentials."
102
136
  puts "This file contains hashed credentials and should not be included in source control without additional protection."
103
137
  exit(1)
@@ -120,6 +154,73 @@ module Itsi
120
154
  end
121
155
  end
122
156
 
157
+ def unique_path(dir, filename)
158
+ base = File.basename(filename, ".*")
159
+ ext = File.extname(filename)
160
+ candidate = File.join(dir, filename)
161
+ return candidate unless File.exist?(candidate)
162
+
163
+ i = 1
164
+ loop do
165
+ new_name = "#{base}_#{i}#{ext}"
166
+ candidate = File.join(dir, new_name)
167
+ return candidate unless File.exist?(candidate)
168
+ i += 1
169
+ end
170
+ end
171
+
172
+ def save_or_print(filename, content, options)
173
+ if options[:save_dir]
174
+ FileUtils.mkdir_p(options[:save_dir])
175
+ path = unique_path(options[:save_dir], filename)
176
+ File.write(path, content)
177
+ puts "Written to #{path}"
178
+ else
179
+ puts content
180
+ end
181
+ end
182
+
183
+ def secret(options)
184
+ require "openssl"
185
+ require "base64"
186
+
187
+ puts "Enter algorithm (one of: HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384):"
188
+ alg = $stdin.gets.chomp.upcase
189
+
190
+ case alg
191
+ when /^HS(\d+)$/
192
+ bits = $1.to_i
193
+ bytes = bits / 8
194
+ key = SecureRandom.random_bytes(bytes)
195
+ pem = Base64.strict_encode64(key)
196
+ content = "=== HMAC #{bits}-bit Secret (base64) ===\n#{pem}\n"
197
+ save_or_print("hmac_#{bits}_secret.txt", content, options)
198
+
199
+ when /^RS/, /^PS/
200
+ rsa = OpenSSL::PKey::RSA.new(2048)
201
+ priv = rsa.to_pem
202
+ pub = rsa.public_key.to_pem
203
+ save_or_print("rsa_private.pem", "=== RSA Private Key ===\n#{priv}", options)
204
+ save_or_print("rsa_public.pem", "=== RSA Public Key ===\n#{pub}", options)
205
+
206
+ when "ES256", "ES384"
207
+ curve = (alg == "ES256" ? "prime256v1" : "secp384r1")
208
+ ec = OpenSSL::PKey::EC.new(curve)
209
+ ec.generate_key
210
+ priv = ec.to_pem
211
+ pub_ec = ec.dup
212
+ pub_ec.private_key = nil
213
+ pub = pub_ec.to_pem
214
+ save_or_print("ecdsa_private.pem", "=== ECDSA Private Key ===\n#{priv}", options)
215
+ save_or_print("ecdsa_public.pem", "=== ECDSA Public Key ===\n#{pub}", options)
216
+
217
+ else
218
+ STDERR.puts "Unsupported algorithm: #{alg}"
219
+ exit 1
220
+ end
221
+ end
222
+
223
+
123
224
  def add_worker
124
225
  return unless pid = get_pid
125
226
 
@@ -134,17 +235,21 @@ module Itsi
134
235
 
135
236
  def status
136
237
  return unless pid = get_pid
137
-
238
+ Itsi.log_info("Itsi running on #{pid}")
138
239
  Process.kill(:USR2, pid)
139
240
  end
140
241
 
141
242
  def load_route_middleware_stack(cli_params)
142
- Config.build_config(cli_params, Itsi::Server::Config.config_file_path(cli_params[:config_file_path]))[
143
- "middleware_loader"
144
- ][]
243
+ middleware, errors = Config.build_config(cli_params, Itsi::Server::Config.config_file_path(cli_params[:config_file_path]))
244
+ if errors.any?
245
+ puts errors
246
+ []
247
+ else
248
+ middleware["middleware_loader"][]
249
+ end
145
250
  end
146
251
 
147
- def test_route(cli_params = {}, route_str)
252
+ def test_route(cli_params, route_str)
148
253
  matched_route = load_route_middleware_stack(cli_params).find do |route|
149
254
  route["route"] =~ route_str
150
255
  end
@@ -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,62 @@ 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
+ Array(middleware.insert_text).zip(Array(middleware.detail)).each do |insert_text, detail|
104
+ completion_item = Interface::CompletionItem.new(
105
+ label: middleware.middleware_name,
106
+ kind: Constant::CompletionItemKind::METHOD,
107
+ label_details: Interface::CompletionItemLabelDetails.new(
108
+ detail: detail,
109
+ description: middleware.documentation
110
+ ),
111
+ documentation: Interface::MarkupContent.new(
112
+ kind: Constant::MarkupKind::MARKDOWN,
113
+ value: middleware.documentation
114
+ ),
115
+ insert_text: insert_text,
116
+ insert_text_format: Constant::InsertTextFormat::SNIPPET,
117
+ data: {
118
+ delegateCompletion: true
119
+ }
120
+ )
121
+ @response_builder << completion_item
122
+ end
123
+ end
108
124
  end
125
+
126
+
109
127
  end
110
128
  end
111
129
  end
@@ -4,28 +4,147 @@ 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
 
10
- def free_bind(protocol)
11
- server = TCPServer.new("0.0.0.0", 0)
12
- port = server.addr[1]
13
- server.close
14
- "#{protocol}://0.0.0.0:#{port}"
14
+ def free_bind(protocol="http", unix_socket: false)
15
+ if unix_socket
16
+ socket_path = "/tmp/itsi_socket_#{Process.pid}_#{rand(1000)}.sock"
17
+ UNIXServer.new(socket_path).close
18
+ protocol == 'https' ? "tls://#{socket_path}" : "unix://#{socket_path}"
19
+ else
20
+ server = TCPServer.new("0.0.0.0", 0)
21
+ port = server.addr[1]
22
+ server.close
23
+ "#{protocol}://0.0.0.0:#{port}"
24
+ end
15
25
  end
16
26
 
17
- def run_app(app, protocol: "http", bind: free_bind(protocol), scheduler_class: nil)
18
- Itsi::Server.start_in_background_thread do
27
+
28
+ def server(app: nil, protocol: "http", bind: free_bind(protocol), itsi_rb: nil, cleanup: true, timeout: 5, &blk)
29
+ itsi_rb ||= lambda do
19
30
  # Inline Itsi.rb
20
31
  bind bind
21
32
  workers 1
22
33
  threads 1
23
- fiber_scheduler scheduler_class
24
34
  log_level :warn
25
- run app
35
+ run app if app
26
36
  end
27
37
 
28
- yield URI(bind)
38
+ cli_params = {}
39
+ cli_params[:binds] = [bind] if bind
40
+
41
+ sync = Queue.new
42
+ cli_params[:hooks] ||= {}
43
+ cli_params[:hooks]["after_start"] = lambda do
44
+ sync.push(true)
45
+ end
46
+
47
+ Itsi::Server.start_in_background_thread(cli_params, &itsi_rb)
48
+
49
+ sync.pop
50
+ uri = URI(bind)
51
+ # Timeout.timeout(timeout) do
52
+ RequestContext.new(uri, self).instance_exec(uri, &blk)
53
+ # end
54
+ rescue StandardError => e
55
+ puts e
56
+ # puts e.message
57
+ # puts e.backtrace.join("\n")
58
+ raise
29
59
  ensure
30
- Itsi::Server.stop_background_thread
60
+ Itsi::Server.stop_background_threads if cleanup
61
+ end
62
+
63
+ require 'net/http'
64
+ require 'net_http_unix'
65
+ require 'uri'
66
+
67
+ class RequestContext
68
+ def initialize(uri, binding)
69
+ @uri = uri
70
+ @binding = binding
71
+ end
72
+
73
+ def method_missing(method_name, *args, &block)
74
+ @binding.send(method_name, *args, &block)
75
+ end
76
+
77
+ def post(path, data="", headers = {})
78
+ client.post(uri_for(path), data, headers)
79
+ end
80
+
81
+ def get(path, headers = {})
82
+ request = Net::HTTP::Get.new(uri_for(path))
83
+ headers.each { |k, v| request[k] = v }
84
+ client.request(request).body
85
+ end
86
+
87
+ def get_resp(path, headers = {})
88
+ request = Net::HTTP::Get.new(uri_for(path))
89
+ headers.each { |k, v| request[k] = v }
90
+ client.request(request)
91
+ end
92
+
93
+ def head(path)
94
+ request = Net::HTTP::Head.new(uri_for(path))
95
+ client.request(request)
96
+ end
97
+
98
+ def options(path, headers = {})
99
+ request = Net::HTTP::Options.new(uri_for(path))
100
+ headers.each { |k, v| request[k] = v }
101
+ client.request(request)
102
+ end
103
+
104
+ def put(path, data="", headers = {})
105
+ request = Net::HTTP::Put.new(uri_for(path))
106
+ request.body = data
107
+ headers.each { |k, v| request[k] = v }
108
+ client.request(request)
109
+ end
110
+
111
+ def delete(path, headers = {})
112
+ request = Net::HTTP::Delete.new(uri_for(path))
113
+ headers.each { |k, v| request[k] = v }
114
+ client.request(request)
115
+ end
116
+
117
+ def patch(path, data="", headers = {})
118
+ request = Net::HTTP::Patch.new(uri_for(path))
119
+ request.body = data
120
+ client.request(request)
121
+ end
122
+
123
+ private
124
+
125
+ def client
126
+ opts = {
127
+ read_timeout: 1,
128
+ open_timeout: 1
129
+ }
130
+ if @uri.scheme == 'unix'
131
+ NetX::HTTPUnix.new(
132
+ @uri.to_s,
133
+ **opts)
134
+ else
135
+ Net::HTTP.start(
136
+ @uri.host,
137
+ @uri.port,
138
+ use_ssl: @uri.scheme == 'https',
139
+ **opts)
140
+ end
141
+ end
142
+
143
+ def uri_for(path)
144
+ if @uri.scheme == 'unix'
145
+ URI::HTTP.build(path: path, host: "localhost")
146
+ else
147
+ URI.join(@uri.to_s, path)
148
+ end
149
+ end
31
150
  end