itsi-server 0.2.22-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +8 -0
  3. data/Cargo.lock +4452 -0
  4. data/Cargo.toml +11 -0
  5. data/Rakefile +57 -0
  6. data/exe/itsi +193 -0
  7. data/ext/itsi_acme/Cargo.toml +86 -0
  8. data/ext/itsi_acme/examples/high_level.rs +63 -0
  9. data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
  10. data/ext/itsi_acme/examples/low_level.rs +87 -0
  11. data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
  12. data/ext/itsi_acme/src/acceptor.rs +81 -0
  13. data/ext/itsi_acme/src/acme.rs +354 -0
  14. data/ext/itsi_acme/src/axum.rs +86 -0
  15. data/ext/itsi_acme/src/cache.rs +39 -0
  16. data/ext/itsi_acme/src/caches/boxed.rs +80 -0
  17. data/ext/itsi_acme/src/caches/composite.rs +69 -0
  18. data/ext/itsi_acme/src/caches/dir.rs +106 -0
  19. data/ext/itsi_acme/src/caches/mod.rs +11 -0
  20. data/ext/itsi_acme/src/caches/no.rs +78 -0
  21. data/ext/itsi_acme/src/caches/test.rs +136 -0
  22. data/ext/itsi_acme/src/config.rs +172 -0
  23. data/ext/itsi_acme/src/https_helper.rs +69 -0
  24. data/ext/itsi_acme/src/incoming.rs +142 -0
  25. data/ext/itsi_acme/src/jose.rs +161 -0
  26. data/ext/itsi_acme/src/lib.rs +142 -0
  27. data/ext/itsi_acme/src/resolver.rs +59 -0
  28. data/ext/itsi_acme/src/state.rs +424 -0
  29. data/ext/itsi_error/Cargo.lock +368 -0
  30. data/ext/itsi_error/Cargo.toml +12 -0
  31. data/ext/itsi_error/src/lib.rs +140 -0
  32. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  33. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  34. data/ext/itsi_rb_helpers/Cargo.lock +355 -0
  35. data/ext/itsi_rb_helpers/Cargo.toml +11 -0
  36. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  37. data/ext/itsi_rb_helpers/src/lib.rs +232 -0
  38. data/ext/itsi_scheduler/Cargo.toml +24 -0
  39. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  40. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  41. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  42. data/ext/itsi_scheduler/src/itsi_scheduler.rs +320 -0
  43. data/ext/itsi_scheduler/src/lib.rs +39 -0
  44. data/ext/itsi_server/Cargo.lock +2956 -0
  45. data/ext/itsi_server/Cargo.toml +94 -0
  46. data/ext/itsi_server/extconf.rb +11 -0
  47. data/ext/itsi_server/src/default_responses/html/401.html +68 -0
  48. data/ext/itsi_server/src/default_responses/html/403.html +68 -0
  49. data/ext/itsi_server/src/default_responses/html/404.html +68 -0
  50. data/ext/itsi_server/src/default_responses/html/413.html +71 -0
  51. data/ext/itsi_server/src/default_responses/html/429.html +68 -0
  52. data/ext/itsi_server/src/default_responses/html/500.html +71 -0
  53. data/ext/itsi_server/src/default_responses/html/502.html +71 -0
  54. data/ext/itsi_server/src/default_responses/html/503.html +68 -0
  55. data/ext/itsi_server/src/default_responses/html/504.html +69 -0
  56. data/ext/itsi_server/src/default_responses/html/index.html +238 -0
  57. data/ext/itsi_server/src/default_responses/json/401.json +6 -0
  58. data/ext/itsi_server/src/default_responses/json/403.json +6 -0
  59. data/ext/itsi_server/src/default_responses/json/404.json +6 -0
  60. data/ext/itsi_server/src/default_responses/json/413.json +6 -0
  61. data/ext/itsi_server/src/default_responses/json/429.json +6 -0
  62. data/ext/itsi_server/src/default_responses/json/500.json +6 -0
  63. data/ext/itsi_server/src/default_responses/json/502.json +6 -0
  64. data/ext/itsi_server/src/default_responses/json/503.json +6 -0
  65. data/ext/itsi_server/src/default_responses/json/504.json +6 -0
  66. data/ext/itsi_server/src/default_responses/mod.rs +14 -0
  67. data/ext/itsi_server/src/env.rs +43 -0
  68. data/ext/itsi_server/src/lib.rs +154 -0
  69. data/ext/itsi_server/src/prelude.rs +2 -0
  70. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +116 -0
  71. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +149 -0
  72. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +346 -0
  73. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +265 -0
  74. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +399 -0
  75. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +447 -0
  76. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +545 -0
  77. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +650 -0
  78. data/ext/itsi_server/src/ruby_types/itsi_server.rs +102 -0
  79. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  80. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  81. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  82. data/ext/itsi_server/src/server/binds/listener.rs +485 -0
  83. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  84. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  85. data/ext/itsi_server/src/server/binds/tls.rs +278 -0
  86. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  87. data/ext/itsi_server/src/server/frame_stream.rs +143 -0
  88. data/ext/itsi_server/src/server/http_message_types.rs +230 -0
  89. data/ext/itsi_server/src/server/io_stream.rs +128 -0
  90. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  91. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  92. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
  93. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  94. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +93 -0
  95. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  96. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  97. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +329 -0
  98. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +300 -0
  99. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  100. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  101. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +188 -0
  102. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +168 -0
  103. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +183 -0
  104. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  105. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
  106. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +133 -0
  107. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  108. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +122 -0
  109. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +407 -0
  110. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +155 -0
  111. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +54 -0
  112. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  113. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +138 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +269 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +62 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +218 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  119. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  120. data/ext/itsi_server/src/server/mod.rs +14 -0
  121. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  122. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  123. data/ext/itsi_server/src/server/request_job.rs +11 -0
  124. data/ext/itsi_server/src/server/serve_strategy/acceptor.rs +100 -0
  125. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +411 -0
  126. data/ext/itsi_server/src/server/serve_strategy/mod.rs +31 -0
  127. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +449 -0
  128. data/ext/itsi_server/src/server/signal.rs +129 -0
  129. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  130. data/ext/itsi_server/src/server/thread_worker.rs +504 -0
  131. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  132. data/ext/itsi_server/src/services/itsi_http_service.rs +270 -0
  133. data/ext/itsi_server/src/services/mime_types.rs +2896 -0
  134. data/ext/itsi_server/src/services/mod.rs +6 -0
  135. data/ext/itsi_server/src/services/password_hasher.rs +89 -0
  136. data/ext/itsi_server/src/services/rate_limiter.rs +609 -0
  137. data/ext/itsi_server/src/services/static_file_server.rs +1400 -0
  138. data/ext/itsi_tracing/Cargo.lock +274 -0
  139. data/ext/itsi_tracing/Cargo.toml +17 -0
  140. data/ext/itsi_tracing/src/lib.rs +370 -0
  141. data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
  142. data/lib/itsi/http_request.rb +228 -0
  143. data/lib/itsi/http_response.rb +49 -0
  144. data/lib/itsi/passfile.rb +108 -0
  145. data/lib/itsi/rack_env_pool.rb +49 -0
  146. data/lib/itsi/server/3.1/itsi_server.so +0 -0
  147. data/lib/itsi/server/3.2/itsi_server.so +0 -0
  148. data/lib/itsi/server/3.3/itsi_server.so +0 -0
  149. data/lib/itsi/server/3.4/itsi_server.so +0 -0
  150. data/lib/itsi/server/4.0/itsi_server.so +0 -0
  151. data/lib/itsi/server/config/config_helpers.rb +116 -0
  152. data/lib/itsi/server/config/dsl.rb +208 -0
  153. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  154. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  155. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  156. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  157. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  158. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  159. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  160. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  161. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  162. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  163. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  164. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  165. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  166. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  167. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  168. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  169. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  170. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  171. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  172. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  173. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  174. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  175. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  176. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  177. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  178. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  179. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  180. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  181. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  182. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  183. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  184. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  185. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  186. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  187. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  188. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  189. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  190. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  191. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  192. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  193. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  194. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  212. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  213. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  214. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  215. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  216. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  217. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  218. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  219. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  220. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  221. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  222. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  223. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  224. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  225. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  226. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  227. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  228. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  229. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  230. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  231. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  232. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  233. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  234. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  235. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  236. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  237. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  238. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  239. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  240. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  241. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  242. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  254. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  255. data/lib/itsi/server/config/known_paths.rb +24 -0
  256. data/lib/itsi/server/config/middleware/_index.md +56 -0
  257. data/lib/itsi/server/config/middleware/allow_list.md +46 -0
  258. data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  259. data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  260. data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  261. data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  262. data/lib/itsi/server/config/middleware/auth_basic.rb +46 -0
  263. data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  264. data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  265. data/lib/itsi/server/config/middleware/cache_control.md +78 -0
  266. data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  267. data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  268. data/lib/itsi/server/config/middleware/compression.md +50 -0
  269. data/lib/itsi/server/config/middleware/compression.rb +37 -0
  270. data/lib/itsi/server/config/middleware/cors.md +93 -0
  271. data/lib/itsi/server/config/middleware/cors.rb +32 -0
  272. data/lib/itsi/server/config/middleware/csp.md +37 -0
  273. data/lib/itsi/server/config/middleware/csp.rb +44 -0
  274. data/lib/itsi/server/config/middleware/deny_list.md +45 -0
  275. data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  276. data/lib/itsi/server/config/middleware/endpoint/_index.md +160 -0
  277. data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  278. data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  279. data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  280. data/lib/itsi/server/config/middleware/endpoint/delete.rb +43 -0
  281. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +106 -0
  282. data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  283. data/lib/itsi/server/config/middleware/endpoint/get.rb +43 -0
  284. data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  285. data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  286. data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  287. data/lib/itsi/server/config/middleware/endpoint/patch.rb +43 -0
  288. data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  289. data/lib/itsi/server/config/middleware/endpoint/post.rb +43 -0
  290. data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  291. data/lib/itsi/server/config/middleware/endpoint/put.rb +43 -0
  292. data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  293. data/lib/itsi/server/config/middleware/error_response.md +74 -0
  294. data/lib/itsi/server/config/middleware/error_response.rb +36 -0
  295. data/lib/itsi/server/config/middleware/etag.md +55 -0
  296. data/lib/itsi/server/config/middleware/etag.rb +25 -0
  297. data/lib/itsi/server/config/middleware/grpc.md +170 -0
  298. data/lib/itsi/server/config/middleware/grpc.rb +54 -0
  299. data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  300. data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  301. data/lib/itsi/server/config/middleware/location.md +107 -0
  302. data/lib/itsi/server/config/middleware/location.rb +103 -0
  303. data/lib/itsi/server/config/middleware/log_requests.md +67 -0
  304. data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  305. data/lib/itsi/server/config/middleware/max_body.md +18 -0
  306. data/lib/itsi/server/config/middleware/max_body.rb +21 -0
  307. data/lib/itsi/server/config/middleware/proxy.md +62 -0
  308. data/lib/itsi/server/config/middleware/proxy.rb +42 -0
  309. data/lib/itsi/server/config/middleware/rackup_file.md +72 -0
  310. data/lib/itsi/server/config/middleware/rackup_file.rb +43 -0
  311. data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  312. data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  313. data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  314. data/lib/itsi/server/config/middleware/redirect.md +55 -0
  315. data/lib/itsi/server/config/middleware/redirect.rb +25 -0
  316. data/lib/itsi/server/config/middleware/request_headers.md +34 -0
  317. data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  318. data/lib/itsi/server/config/middleware/response_headers.md +33 -0
  319. data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  320. data/lib/itsi/server/config/middleware/run.md +79 -0
  321. data/lib/itsi/server/config/middleware/run.rb +45 -0
  322. data/lib/itsi/server/config/middleware/static_assets.md +113 -0
  323. data/lib/itsi/server/config/middleware/static_assets.rb +99 -0
  324. data/lib/itsi/server/config/middleware/static_response.md +44 -0
  325. data/lib/itsi/server/config/middleware/static_response.rb +30 -0
  326. data/lib/itsi/server/config/middleware/string_rewrite.md +81 -0
  327. data/lib/itsi/server/config/middleware/token_source.rb +32 -0
  328. data/lib/itsi/server/config/middleware.rb +13 -0
  329. data/lib/itsi/server/config/option.rb +13 -0
  330. data/lib/itsi/server/config/options/_index.md +41 -0
  331. data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  332. data/lib/itsi/server/config/options/auto_reload_config.rb +46 -0
  333. data/lib/itsi/server/config/options/bind.md +71 -0
  334. data/lib/itsi/server/config/options/bind.rb +26 -0
  335. data/lib/itsi/server/config/options/certificates.md +65 -0
  336. data/lib/itsi/server/config/options/daemonize.md +14 -0
  337. data/lib/itsi/server/config/options/daemonize.rb +19 -0
  338. data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  339. data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  340. data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  341. data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  342. data/lib/itsi/server/config/options/hooks/_index.md +11 -0
  343. data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  344. data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  345. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  346. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  347. data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  348. data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  349. data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  350. data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  351. data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  352. data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  353. data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  354. data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  355. data/lib/itsi/server/config/options/include.md +21 -0
  356. data/lib/itsi/server/config/options/include.rb +41 -0
  357. data/lib/itsi/server/config/options/listen_backlog.md +11 -0
  358. data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  359. data/lib/itsi/server/config/options/log_format.md +18 -0
  360. data/lib/itsi/server/config/options/log_format.rb +19 -0
  361. data/lib/itsi/server/config/options/log_level.md +34 -0
  362. data/lib/itsi/server/config/options/log_level.rb +20 -0
  363. data/lib/itsi/server/config/options/log_target.md +38 -0
  364. data/lib/itsi/server/config/options/log_target.rb +19 -0
  365. data/lib/itsi/server/config/options/log_target_filters.md +17 -0
  366. data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  367. data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  368. data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  369. data/lib/itsi/server/config/options/nodelay.md +16 -0
  370. data/lib/itsi/server/config/options/nodelay.rb +19 -0
  371. data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  372. data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  373. data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  374. data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  375. data/lib/itsi/server/config/options/pipeline_flush.md +16 -0
  376. data/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
  377. data/lib/itsi/server/config/options/preload.md +21 -0
  378. data/lib/itsi/server/config/options/preload.rb +18 -0
  379. data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  380. data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  381. data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  382. data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  383. data/lib/itsi/server/config/options/request_timeout.md +23 -0
  384. data/lib/itsi/server/config/options/request_timeout.rb +19 -0
  385. data/lib/itsi/server/config/options/reuse_address.md +18 -0
  386. data/lib/itsi/server/config/options/reuse_address.rb +19 -0
  387. data/lib/itsi/server/config/options/reuse_port.md +18 -0
  388. data/lib/itsi/server/config/options/reuse_port.rb +17 -0
  389. data/lib/itsi/server/config/options/ruby_thread_request_backlog_size.md +18 -0
  390. data/lib/itsi/server/config/options/ruby_thread_request_backlog_size.rb +19 -0
  391. data/lib/itsi/server/config/options/scheduler_threads.md +41 -0
  392. data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  393. data/lib/itsi/server/config/options/send_buffer_size.md +15 -0
  394. data/lib/itsi/server/config/options/send_buffer_size.rb +19 -0
  395. data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  396. data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  397. data/lib/itsi/server/config/options/stream_body.md +32 -0
  398. data/lib/itsi/server/config/options/stream_body.rb +18 -0
  399. data/lib/itsi/server/config/options/threads.md +44 -0
  400. data/lib/itsi/server/config/options/threads.rb +17 -0
  401. data/lib/itsi/server/config/options/watch.md +16 -0
  402. data/lib/itsi/server/config/options/watch.rb +28 -0
  403. data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  404. data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  405. data/lib/itsi/server/config/options/workers.md +42 -0
  406. data/lib/itsi/server/config/options/workers.rb +17 -0
  407. data/lib/itsi/server/config/options/writev.md +25 -0
  408. data/lib/itsi/server/config/options/writev.rb +19 -0
  409. data/lib/itsi/server/config/typed_struct.rb +239 -0
  410. data/lib/itsi/server/config.rb +321 -0
  411. data/lib/itsi/server/default_app/default_app.rb +34 -0
  412. data/lib/itsi/server/default_app/index.html +115 -0
  413. data/lib/itsi/server/default_config/Itsi.rb +108 -0
  414. data/lib/itsi/server/grpc/grpc_call.rb +247 -0
  415. data/lib/itsi/server/grpc/grpc_interface.rb +106 -0
  416. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  417. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  418. data/lib/itsi/server/native_extension.rb +34 -0
  419. data/lib/itsi/server/rack/handler/itsi.rb +29 -0
  420. data/lib/itsi/server/rack_interface.rb +109 -0
  421. data/lib/itsi/server/route_tester.rb +159 -0
  422. data/lib/itsi/server/scheduler_interface.rb +23 -0
  423. data/lib/itsi/server/scheduler_mode.rb +10 -0
  424. data/lib/itsi/server/signal_trap.rb +33 -0
  425. data/lib/itsi/server/typed_handlers/param_parser.rb +221 -0
  426. data/lib/itsi/server/typed_handlers/source_parser.rb +58 -0
  427. data/lib/itsi/server/typed_handlers.rb +25 -0
  428. data/lib/itsi/server/version.rb +7 -0
  429. data/lib/itsi/server.rb +288 -0
  430. data/lib/itsi/standard_headers.rb +86 -0
  431. data/lib/ruby_lsp/itsi/addon.rb +128 -0
  432. data/lib/shell_completions/completions.rb +26 -0
  433. data/vendor/rb-sys-build/.cargo-ok +1 -0
  434. data/vendor/rb-sys-build/.cargo_vcs_info.json +6 -0
  435. data/vendor/rb-sys-build/Cargo.lock +294 -0
  436. data/vendor/rb-sys-build/Cargo.toml +71 -0
  437. data/vendor/rb-sys-build/Cargo.toml.orig +32 -0
  438. data/vendor/rb-sys-build/LICENSE-APACHE +190 -0
  439. data/vendor/rb-sys-build/LICENSE-MIT +21 -0
  440. data/vendor/rb-sys-build/src/bindings/sanitizer.rs +185 -0
  441. data/vendor/rb-sys-build/src/bindings/stable_api.rs +247 -0
  442. data/vendor/rb-sys-build/src/bindings/wrapper.h +71 -0
  443. data/vendor/rb-sys-build/src/bindings.rs +280 -0
  444. data/vendor/rb-sys-build/src/cc.rs +421 -0
  445. data/vendor/rb-sys-build/src/lib.rs +12 -0
  446. data/vendor/rb-sys-build/src/rb_config/flags.rs +101 -0
  447. data/vendor/rb-sys-build/src/rb_config/library.rs +132 -0
  448. data/vendor/rb-sys-build/src/rb_config/search_path.rs +57 -0
  449. data/vendor/rb-sys-build/src/rb_config.rs +906 -0
  450. data/vendor/rb-sys-build/src/utils.rs +53 -0
  451. metadata +569 -0
@@ -0,0 +1,43 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Put < Middleware
5
+
6
+ insert_text [
7
+ <<~SNIPPET,
8
+ put "${1:/path}", :${2:handler}
9
+ SNIPPET
10
+ <<~SNIPPET,
11
+ put "${1:/path}" do |req|
12
+ $2
13
+ end
14
+ SNIPPET
15
+ <<~SNIPPET,
16
+ put "${1:/path}" do |req, params|
17
+ $2
18
+ end
19
+ SNIPPET
20
+ ]
21
+
22
+ detail ["A light-weight PUT endpoint (controller)", "A light-weight PUT endpoint (inline block)", "A light-weight PUT endpoint (inline params)"]
23
+
24
+ schema do
25
+ {
26
+ paths: Array(Or(Type(String), Type(Regexp))),
27
+ handler: Type(Proc) & Required(),
28
+ http_methods: Array(Type(String)),
29
+ script_name: Type(String).default(nil),
30
+ nonblocking: Bool()
31
+ }
32
+ end
33
+
34
+ def initialize(location, path="", handler=nil, http_methods: [], nonblocking: false, script_name: nil, &handler_proc) # rubocop:disable Lint/MissingSuper,Metrics/ParameterLists
35
+ location.endpoint(path, handler, http_methods: ["PUT"], nonblocking: nonblocking, script_name: script_name, &handler_proc)
36
+ end
37
+
38
+ def build!
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,122 @@
1
+ ---
2
+ title: Schemas
3
+ url: /middleware/endpoint/schemas
4
+ next: error_response/
5
+ ---
6
+
7
+ Endpoints also support basic schema enforcement for both request and and response bodies. Endpoint **Schemas** are simply plain-old Ruby hashes, which map named keys to allowed types.
8
+
9
+ E.g.
10
+ ```ruby {filename=Itsi.rb}
11
+ # This is a valid schema
12
+ SimpleSchema = {
13
+ score: Integer
14
+ }
15
+ ```
16
+
17
+ A few special rules/conventions apply:
18
+
19
+ * Regexp patterns are used in place of symbol keys to define dynamic parameters that must match a specific pattern (A key of `/.*/` matches any string).
20
+ * A `:Boolean` symbol can be used instead of a class to require boolean parameters (as a proxy for the combination of TrueClass and FalseClass)
21
+ * `Array` keys are used to define arrays of values.
22
+ * Objects can be nested
23
+ * A special `_required` key indicates which parameters in the current object are required.
24
+ * Arrays must be homogeneous (No support for union types).
25
+ * Schema validation *only* supports primitive Ruby types, Date, Time, Datetime, arrays and hashes (no unions or advanced coercion).
26
+
27
+
28
+ ## Supported types
29
+ ```ruby {filename=Itsi.rb}
30
+ # Demo schema with all supported types included
31
+ SupportedTypesSchema = {
32
+ _required: %i[name age active preferences created_at last_login],
33
+ name: String, # A user's name
34
+ age: Integer, # The user's age
35
+ active: :Boolean, # Whether the user is active
36
+ preferences: {
37
+ _required: %i[theme notifications],
38
+ theme: Symbol, # Preferred theme (e.g., :dark, :light)
39
+ notifications: :Boolean # Whether notifications are enabled
40
+ },
41
+ scores: Array[Float], # A list of user scores
42
+ metadata: {
43
+ _required: %i[signup_date last_purchase],
44
+ signup_date: Date, # The date the user signed up
45
+ last_purchase: DateTime # The timestamp of the last purchase
46
+ },
47
+ last_login: Time # The last login time
48
+ }
49
+ ```
50
+
51
+ {{< callout >}}
52
+ Itsi will check for the presence and structure of all:
53
+ * [Schemas](/middleware/schemas)
54
+ * [Controller methods](/middleware/controller)
55
+
56
+ at **boot time** ensuring that you can't be caught out by naming mismatches at runtime, or during a hot-reload.
57
+ If Itsi boots successfully, the referenced schemas objects can be found.
58
+ {{</ callout >}}
59
+
60
+
61
+ ## Request Body Schemas
62
+
63
+ ```ruby {filename=Itsi.rb}
64
+ AddressSchema = {
65
+ _required: %i[street city postcode],
66
+ street: String,
67
+ city: String,
68
+ postcode: String,
69
+ country: String # Optional
70
+ }
71
+
72
+ UserInputSchema = {
73
+ _required: %i[first_name last_name email address],
74
+ first_name: String,
75
+ last_name: String,
76
+ email: String,
77
+ age: Integer,
78
+ active: :Boolean,
79
+ roles: Array[String],
80
+ address: AddressSchema
81
+ }
82
+
83
+ UserResponseSchema = {
84
+ _required: %i[id email full_name],
85
+ id: Integer,
86
+ email: String,
87
+ full_name: String,
88
+ created_at: String,
89
+ address: AddressSchema
90
+ }
91
+
92
+ post "/users" do |request, params: UserInputSchema, response_format: UserResponseSchema|
93
+ user = User.create!(params)
94
+ request.created \
95
+ json: {
96
+ id: user.id,
97
+ email: user.email,
98
+ full_name: "#{user.first_name} #{user.last_name}",
99
+ created_at: user.created_at.iso8601,
100
+ address: {
101
+ street: user.address.street,
102
+ city: user.address.city,
103
+ postcode: user.address.postcode
104
+ }
105
+ },
106
+ as: response_format
107
+ end
108
+ ```
109
+ Endpoints with schema validation applied can count on requests *only* being invoked with correctly formed parameters (and descriptive errors being returned if schema enforcement fails.)
110
+
111
+ You can *optionally* choose to apply a corresponding response schema validation to response objects.
112
+
113
+ ## Response Body Schemas
114
+ ```ruby {filename=Itsi.rb}
115
+ PingSchema = {
116
+ status: String
117
+ }
118
+
119
+ get "/ping" do |req, response_format: PingSchema|
120
+ req.ok json: { status: "ok" }, as: response_format
121
+ end
122
+ ```
@@ -0,0 +1,74 @@
1
+ ---
2
+ title: Error Response
3
+ url: /middleware/error_response
4
+ prev: schemas/
5
+ ---
6
+
7
+ All of the below middlewares allow error responses to be customized (though will select a sane default if left unspecified).
8
+ * [`allow_list`](/middleware/allow_list)
9
+ * [`auth_api_key`](/middleware/auth_api_key)
10
+ * [`auth_jwt`](/middleware/auth_jwt)
11
+ * [`deny_list`](/middleware/deny_list)
12
+ * [`intrusion_protection`](/middleware/intrusion_protection)
13
+ * [`max_body`](/middleware/max_body)
14
+ * [`proxy`](/middleware/proxy)
15
+ * [`rate_limit`](/middleware/rate_limit)
16
+
17
+ You can override the default error responses by providing a custom error response, either selecting a different built-in type,
18
+ or providing a completely overridden options.
19
+ The following built-in types are available:
20
+ * `internal_server_error` (500)
21
+ * `not_found` (404)
22
+ * `unauthorized` (401)
23
+ * `forbidden` (403)
24
+ * `payload_too_large` (413)
25
+ * `too_many_requests` (429)
26
+ * `bad_gateway` (502)
27
+ * `service_unavailable` (503)
28
+ * `gateway_timeout` (504)
29
+
30
+ ## Reuse a built-in type
31
+ To reuse a built-in type you can provide a string option for the `error_response` property.
32
+ E.g.
33
+ ```ruby
34
+ auth_api_key .. other options.., error_response: 'forbidden'
35
+ ```
36
+
37
+ ## Example of built-in response
38
+ ### HTML
39
+ {{< card title="Built-in error page" image="/error_page.jpg" subtitle="Default Itsi Error Page." method="Resize" options="10x q80 webp" >}}
40
+ ### JSON
41
+ ```json
42
+ {
43
+ "error": "Too Many Requests",
44
+ "message": "Too many requests within a limited time frame.",
45
+ "code": 429,
46
+ "status": "error"
47
+ }
48
+ ```
49
+
50
+ ## Override the error response
51
+ You may instead wish to completely override the error response. You can provide a status code, and a message in up to three
52
+ formats: plain-text, JSON, or HTML (at least one must be provided). Itsi will serve the appropriate type based on the `Accept` header of the incoming request, or fall back to the default if the requested type is not available.
53
+ Each of these three response formats can either be provided as an in-memory string, or a file path.
54
+
55
+ E.g.
56
+
57
+ ```ruby
58
+ auth_api_key .. other options.., error_response: {
59
+ status: 403,
60
+ plaintext: nil, # No plain-text response provided
61
+ json: { inline: {"message": "Forbidden"} }, # We provide the JSON response inline
62
+ html: { file: './forbidden.html'}, # We provide the HTML response as a file path
63
+ default: 'json' # When the Accept header doesn't match a supported response type, we'll default to JSON
64
+ }
65
+
66
+ # Or, e.g.
67
+ auth_api_key .. other options.., error_response: {
68
+ status: 401,
69
+ plaintext: "Unauthorized",
70
+ json: { file: "unauthorized.json" },
71
+ html: { inline: "<h1>Unauthorized</h1>" },
72
+ default: 'html'
73
+ }
74
+ ```
@@ -0,0 +1,36 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ InlineContentSource = TypedStruct.new do
5
+ {
6
+ inline: Type(String)
7
+ }
8
+ end
9
+
10
+ FileContentSource = TypedStruct.new do
11
+ {
12
+ file: Type(String)
13
+ }
14
+ end
15
+
16
+ ContentSource = TypedStruct.new do
17
+ Or(Type(InlineContentSource), Type(FileContentSource))
18
+ end
19
+
20
+ ErrorResponse = TypedStruct.new do
21
+ {
22
+ code: Type(Integer) & Required(),
23
+ plaintext: Type(ContentSource),
24
+ html: Type(ContentSource),
25
+ json: Type(ContentSource),
26
+ default: Enum(["plaintext", "html", "json"]) & Required()
27
+ }
28
+ end
29
+
30
+ ErrorResponseDef = TypedStruct.new do
31
+ Or(Enum(%w[internal_server_error not_found unauthorized forbidden payload_too_large
32
+ too_many_requests bad_gateway service_unavailable gateway_timeout]), Type(ErrorResponse)) & Required()
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,55 @@
1
+ ---
2
+ title: ETag
3
+ url: /middleware/etag
4
+ ---
5
+
6
+ The ETag middleware enables HTTP entity tag generation for responses. It provides cache validation by automatically computing and attaching an ETag to outgoing responses, and optionally responding with `304 Not Modified` if the client includes a matching `If-None-Match` header.
7
+
8
+ ETags are useful for optimizing client-side caching, conditional GETs, and reducing unnecessary data transfer.
9
+
10
+
11
+ ## ETag configuration
12
+ ```ruby {filename=Itsi.rb}
13
+ etag \
14
+ type: "strong",
15
+ algorithm: "sha256",
16
+ min_body_size: 0
17
+ ```
18
+
19
+ ## ETag Applied to a sub-location
20
+ ```ruby {filename=Itsi.rb}
21
+ location "/assets" do
22
+ etag \
23
+ type: "weak",
24
+ algorithm: "md5",
25
+ min_body_size: 1024
26
+ end
27
+ ```
28
+
29
+ ## Configuration Options
30
+
31
+ - **type**: Specifies whether the generated ETag is `"strong"` or `"weak"`.
32
+ - `strong`: ETag changes with any byte-level difference in the body.
33
+ - `weak`: Indicates a semantic equivalence rather than byte-level identity.
34
+
35
+ - **algorithm**: Specifies the hash algorithm used to compute the ETag.
36
+ - `sha256` (default)
37
+ - `md5`
38
+
39
+ - **min_body_size**: Minimum response body size (in bytes) required before an ETag is generated. Use this to skip ETags for small or trivial responses.
40
+
41
+ ## How It Works
42
+
43
+ ### Before the Response
44
+ If the request includes an `If-None-Match` header, the value is stored in the request context for comparison later.
45
+
46
+ ### After the Response
47
+
48
+ 1. If the status code is cacheable (e.g., 200 OK, 201 Created), the middleware proceeds.
49
+ 2. If an ETag header is already present or if `Cache-Control: no-store` is set, it skips computation.
50
+ 3. If the response body is not streamable and meets the `min_body_size`, it is buffered.
51
+ 4. A hash (SHA-256 or MD5) is computed from the full body content.
52
+ 5. The ETag header is inserted using either strong (`"abc123"`) or weak (`W/"abc123"`) formatting.
53
+ 6. If the incoming request had a matching `If-None-Match`, the response is replaced with a 304 Not Modified.
54
+
55
+ ---
@@ -0,0 +1,25 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Etag < Middleware
5
+
6
+ insert_text <<~SNIPPET
7
+ etag \\
8
+ type: ${1|"strong","weak"|},
9
+ algorithm: ${2|"sha256","md5"|},
10
+ min_body_size: ${3|0,1024|}
11
+ SNIPPET
12
+
13
+ detail "Enables ETag generation for the server."
14
+
15
+ schema do
16
+ {
17
+ type: (Enum(["strong", "weak"]) & Required()).default("strong"),
18
+ algorithm: (Enum(["sha256", "md5"]) & Required()).default("sha256"),
19
+ min_body_size: Range(0...1024 ** 3).default(0)
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,170 @@
1
+ ---
2
+ title: gRPC
3
+ url: /middleware/grpc
4
+ ---
5
+
6
+ The **gRPC** middleware lets you expose one or more Ruby gRPC service handlers directly in Itsi.
7
+ This allows you to use Itsi's efficient asynchronous server to serve requests and gain enhanced performance and asynchronous capabilities.
8
+
9
+ Under the covers it:
10
+
11
+ 1. Serves a full HTTP/2 gRPC endpoint (with binary frames, trailers, `HTTP/2` compression, and reflection).
12
+ 2. Provides a **JSON‑over‑HTTP** gateway for each unary or streaming method—so you can POST JSON and receive JSON arrays without a gRPC client.
13
+ 3. Automatically enables `gRPC` reflection (so client like `evans`, `grpcurl` or `Postman` can discover your service endpoints without needing access to raw `.proto` files).
14
+ 4. Supports optional per‑call compression (`none`, `deflate`, `gzip`) and a non‑blocking execution mode.
15
+
16
+
17
+ ## Usage
18
+
19
+ ```ruby
20
+ # Define (or require) your service implementation:
21
+ # Mount it in your Itsi.rb:
22
+ grpc EchoServiceImpl.new,
23
+ nonblocking: false do # prepend response with grpc‑encoding:gzip
24
+ # any additional middleware can nest here, e.g.:
25
+ response_headers additions: { "X-Service" => ["Echo"] }
26
+ end
27
+ ```
28
+
29
+ ## Options
30
+
31
+ | Option | Type | Default | Description |
32
+ |---------------|---------|---------|---------------------------------------------------------------|
33
+ | `*handlers` | Object | – | One or more gRPC service implementations |
34
+ | `nonblocking` | Boolean | false | Run handler in fiber/thread‑pool (nonblocking mode). Only effective if using [hybrid mode](/options/scheduler_threads), otherwise the gRPC handler will adopt the server global concurrency mode (threads or fibers) |
35
+ | `reflection` | Boolean | true | Determines whether to serve reflection endpoints. (Useful for clients to auto-discover services) |
36
+ | `&block` | Proc | – | **Optional** You can add additional middleware inside an optional block, to apply to all gRPC requests (e.g. rate limiters, deny lists, max body etc. etc.). |
37
+
38
+ Reflection is served only over HTTP/2; JSON‑over‑HTTP works with HTTP/1.1.
39
+
40
+
41
+
42
+ ## Walkthrough
43
+ The below is a simple walkthrough of using Itsi and the [Ruby gRPC](https://grpc.io/docs/languages/ruby/basics/) library to expose a simple "Echo" service in Itsi, complete with both native gRPC/HTTP2 and a JSON‑over‑HTTP gateway.
44
+
45
+ {{% steps %}}
46
+
47
+ ### Step 1 — Define your gRPC contract
48
+
49
+ Create a file `echo.proto` with:
50
+ ```proto
51
+ syntax = "proto3";
52
+ package echo;
53
+
54
+ service EchoService {
55
+ rpc Echo(EchoRequest) returns (EchoResponse);
56
+ }
57
+
58
+ message EchoRequest {
59
+ string message = 1;
60
+ }
61
+
62
+ message EchoResponse {
63
+ string message = 1;
64
+ }
65
+ ```
66
+
67
+ ### Step 2 — Generate Ruby stubs
68
+
69
+ Install the Ruby gRPC tools and run:
70
+ ```bash
71
+ gem install grpc-tools
72
+ grpc_tools_ruby_protoc -I . --ruby_out=./ --grpc_out=./ echo.proto
73
+ ```
74
+ This produces `echo_services_pb.rb` and supporting files.
75
+
76
+ ### Step 3 — Implement the service
77
+
78
+ Create `echo_service_impl.rb`:
79
+ ```ruby {filename=echo_service_impl.rb}
80
+ require_relative 'echo_services_pb'
81
+
82
+ class EchoServiceImpl < Echo::EchoService::Service
83
+ # Unary RPC implementation
84
+ def echo(req, _unused_call)
85
+ Echo::EchoResponse.new(message: req.message)
86
+ end
87
+ end
88
+ ```
89
+
90
+ ### Step 4 — Mount in Itsi
91
+
92
+ In your `Itsi.rb` at the project root, add:
93
+
94
+ ```ruby {filename=Itsi.rb}
95
+ require_relative 'echo_service_impl'
96
+
97
+ bind "https://localhost:3000"
98
+ grpc EchoServiceImpl.new,
99
+ nonblocking: false do
100
+ # Nested middleware still works:
101
+ response_headers additions: { 'X-Service' => ['Echo'] }
102
+ end
103
+ ```
104
+ ### Step 5 — Start the server
105
+ ```bash
106
+ itsi serve
107
+ ```
108
+
109
+ ### Step 6 — Test with a gRPC client
110
+
111
+ E.g. using [Evans](https://github.com/ktr0731/evans)
112
+
113
+ ```bash
114
+ evans --host localhost --port 3000 repl
115
+
116
+ ______
117
+ | ____|
118
+ | |__ __ __ __ _ _ __ ___
119
+ | __| \ \ / / / _. | | '_ \ / __|
120
+ | |____ \ V / | (_| | | | | | \__ \
121
+ |______| \_/ \__,_| |_| |_| |___/
122
+
123
+ more expressive universal gRPC client
124
+
125
+
126
+ echo.EchoService@127.0.0.1:3000> call Echo
127
+ message (TYPE_STRING) => Hello
128
+ {
129
+ "message": "Hello"
130
+ }
131
+
132
+ echo.EchoService@127.0.0.1:3000>
133
+ ```
134
+
135
+ ### Step 7 — Try the JSON gateway
136
+
137
+ You can also POST plain JSON (works over HTTP/1.1 or HTTP/2):
138
+ ```bash
139
+ curl \
140
+ -H 'Content-Type: application/json' \
141
+ -H "Content-Type: application/json" \
142
+ -X POST http://localhost:3000/echo.EchoService/Echo \
143
+ -d '{"message":"world"}'
144
+
145
+ {"message":"world"}
146
+
147
+ ```
148
+
149
+ {{% /steps %}}
150
+
151
+
152
+ ## JSON gateway
153
+ Itsi exposes gRPC services via a secondary JSON gateways for use with simple HTTP clients.
154
+ Once mounted, each service‐method is *also* reachable via HTTP/2 and via simple JSON POSTs:
155
+
156
+ ```bash
157
+ # Unary RPC (Echo)
158
+ curl -X POST http://0.0.0.0:3000/EchoService/Echo \
159
+ -H "Content-Type: application/json" \
160
+ -d '{"message":"hello"}'
161
+ # → 200 OK, body: {"message":"hello"}
162
+
163
+ # Server streaming RPC (e.g. "Numbers"): POST an array, receive JSON array:
164
+ curl -X POST http://0.0.0.0:3000/NumberService/Stream \
165
+ -H "Content-Type: application/json" \
166
+ -d '[{"n":1},{"n":2},{"n":3}]'
167
+ # → 200 OK, body: [{"n":1},{"n":2},{"n":3}]
168
+ ```
169
+
170
+ Under the hood, the same framing machinery is used—you just get plain JSON arrays instead of gRPC frames.
@@ -0,0 +1,54 @@
1
+ module Itsi
2
+ class Server
3
+ module Config
4
+ class Grpc < Middleware
5
+ insert_text [
6
+ <<~SNIPPET,
7
+ grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|} do
8
+ ${3:# nested middleware…}
9
+ end
10
+ SNIPPET
11
+
12
+ <<~SNIPPET,
13
+ grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|}
14
+ SNIPPET
15
+ ]
16
+
17
+ detail [
18
+ "gRPC service with middleware (with HTTP/2, compression, reflection and JSON gateway)",
19
+ "gRPC service (with HTTP/2, compression, reflection and JSON gateway)"
20
+ ]
21
+
22
+ schema do
23
+ {
24
+ handlers: Array(Type(Object)) & Required(),
25
+ reflection: Bool().default(true),
26
+ nonblocking: Bool().default(false),
27
+ inner_block: Type(Proc)
28
+ }
29
+ end
30
+
31
+ def initialize(location, *handlers, reflection: true, nonblocking: false, &block)
32
+ super(location, {
33
+ handlers: handlers,
34
+ reflection: reflection,
35
+ nonblocking: nonblocking,
36
+ inner_block: block
37
+ })
38
+ end
39
+
40
+ def build!
41
+ location.grpc_reflection(@params[:handlers]) if @params[:reflection]
42
+ nonblocking = @params[:nonblocking]
43
+ blk = @params[:inner_block]
44
+ @params[:handlers].each do |handler|
45
+ location.location(Regexp.new("#{Regexp.escape(handler.class.service_name)}/(?:#{handler.class.rpc_descs.keys.map(&:to_s).join("|")})")) do
46
+ @middleware[:app] = { preloader: -> { Itsi::Server::GrpcInterface.for(handler) }, request_type: "grpc", nonblocking: nonblocking }
47
+ instance_exec(&blk) if blk
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end