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,247 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "stringio"
4
+
5
+ module Itsi
6
+ class GrpcCall
7
+ attr_accessor :rpc_desc
8
+
9
+ def input_stream?
10
+ @input_stream ||= @rpc_desc&.input.is_a?(GRPC::RpcDesc::Stream) || false
11
+ end
12
+
13
+ def output_stream?
14
+ @output_stream ||= @rpc_desc&.output.is_a?(GRPC::RpcDesc::Stream) || false
15
+ end
16
+
17
+ def input_type
18
+ @input_type ||= input_stream? ? rpc_desc.input.type : rpc_desc.input
19
+ end
20
+
21
+ def output_type
22
+ @output_type ||= output_stream? ? rpc_desc.output.type : rpc_desc.output
23
+ end
24
+
25
+ def reader
26
+ @reader ||= IO.open(stream.reader_fileno, "rb")
27
+ end
28
+
29
+ def close
30
+ if output_stream? && content_type == "application/json"
31
+ stream.write("[") unless @opened
32
+ stream.write("]")
33
+ end
34
+
35
+ @reader&.close
36
+ stream.close
37
+ end
38
+
39
+ def deadline
40
+ return @deadline if defined?(@deadline)
41
+ return @deadline = nil unless timeout
42
+
43
+ @deadline = Time.now + timeout
44
+ end
45
+
46
+ def parse_from_json_stream(json_stream)
47
+ first_char = nil
48
+ loop do
49
+ char = json_stream.read(1)
50
+ break if char.nil?
51
+ if char =~ /\s/
52
+ next
53
+ elsif ["[", ","].include?(char)
54
+ first_char = char
55
+ break
56
+ elsif char == "]"
57
+ return nil
58
+ else
59
+ # If the first non-whitespace character is not '[' or comma, return nil.
60
+ return nil
61
+ end
62
+ end
63
+
64
+ return nil if first_char.nil?
65
+
66
+ # Step 2: Process objects until we hit the end of the JSON stream or array.
67
+ loop do # rubocop:disable Lint/UnreachableLoop,Metrics/BlockLength
68
+ # Skip any whitespace or commas preceding an object.
69
+ char = nil
70
+ loop do
71
+ char = json_stream.read(1)
72
+ break if char.nil?
73
+ next if char =~ /\s/
74
+
75
+ break
76
+ end
77
+ # The next non-whitespace, non-comma character should be the start of an object.
78
+ return nil unless char == "{"
79
+
80
+ # Step 3: Start buffering the JSON object.
81
+ buffer = "{".dup
82
+ stack = ["{"]
83
+ in_string = false
84
+ escape = false
85
+
86
+ while stack.any?
87
+ ch = json_stream.read(1)
88
+ return nil if ch.nil? # premature end of stream
89
+
90
+ buffer << ch
91
+
92
+ if in_string
93
+ if escape
94
+ escape = false
95
+ next
96
+ end
97
+ if ch == "\\"
98
+ escape = true
99
+ elsif ch == '"'
100
+ in_string = false
101
+ end
102
+ elsif ch == '"'
103
+ in_string = true
104
+ elsif ["{", "["].include?(ch)
105
+ stack.push(ch)
106
+ elsif ["}", "]"].include?(ch)
107
+ expected = (ch == "}" ? "{" : "[")
108
+ # Check for matching bracket.
109
+ return nil unless stack.last == expected
110
+
111
+ stack.pop
112
+ end
113
+ end
114
+ # Yield the complete JSON object (as a string).
115
+ return buffer
116
+ end
117
+ end
118
+
119
+ def remote_read
120
+ if content_type == "application/json"
121
+ if input_stream?
122
+ if (next_item = parse_from_json_stream(reader))
123
+ input_type.decode_json(next_item)
124
+ end
125
+ else
126
+ input_type.decode_json(reader.read)
127
+ end
128
+ else
129
+ header = reader.read(5)
130
+ return nil if header.nil? || header.bytesize < 5
131
+
132
+ compressed = header.bytes[0] == 1
133
+ length = header[1..4].unpack1("N")
134
+
135
+ data = reader.read(length)
136
+ return nil if data.nil?
137
+
138
+ data = decompress_input(data) if compressed
139
+
140
+ input_type.decode(data)
141
+ end
142
+ end
143
+
144
+ def send_framed_message(message_data, compressed = nil)
145
+ if content_type == "application/json"
146
+ if output_stream?
147
+ if @opened
148
+ stream.write(",\n")
149
+ else
150
+ stream.write("[")
151
+ @opened = true
152
+ end
153
+ end
154
+ message_data = output_type.encode_json(message_data)
155
+ stream.write(message_data)
156
+ else
157
+ message_data = output_type.encode(message_data)
158
+ should_compress = compressed.nil? ? should_compress_output?(message_data.bytesize) : compressed
159
+
160
+ if should_compress
161
+ message_data = compress_output(message_data)
162
+ compressed_flag = 1
163
+ else
164
+ compressed_flag = 0
165
+ end
166
+
167
+ message = [compressed_flag, message_data.bytesize].pack("CN") << message_data
168
+ stream.write(message)
169
+
170
+ @body_written = true
171
+ end
172
+ rescue IOError
173
+ close
174
+ end
175
+
176
+ def remote_send(response)
177
+ send_framed_message(response)
178
+ end
179
+
180
+ def deadline_exceeded?
181
+ @deadline && @deadline <= Time.now
182
+ end
183
+
184
+ def each_remote_read
185
+ return enum_for(:each_remote_read) unless block_given?
186
+
187
+ while (resp = remote_read) || !cancelled?
188
+
189
+ yield resp
190
+ end
191
+ end
192
+
193
+ alias_method :each, :each_remote_read
194
+
195
+ def bidi_streamer?
196
+ input_stream? && output_stream?
197
+ end
198
+
199
+ def client_streamer?
200
+ input_stream? && !output_stream?
201
+ end
202
+
203
+ def server_streamer?
204
+ !input_stream? && output_stream?
205
+ end
206
+
207
+ def request_response?
208
+ !input_stream? && !output_stream?
209
+ end
210
+
211
+ def send_initial_metadata(kv_pairs)
212
+ add_headers(kv_pairs.transform_values { |v| Array(v) })
213
+ end
214
+
215
+ def send_empty
216
+ remote_send(output_type.new) unless @body_written
217
+ end
218
+
219
+ def send_status(status_code, status_details, trailing_metadata = {})
220
+ trailers = {
221
+ "grpc-status" => status_code.to_s
222
+ }
223
+
224
+ unless status_details.nil? || status_details.empty?
225
+ encoded_message = status_details.gsub(/[ #%&+,:;<=>?@\[\]^`{|}~\\"]/) do |c|
226
+ "%" + c.ord.to_s(16).upcase
227
+ end
228
+ trailers["grpc-message"] = encoded_message
229
+ end
230
+
231
+ trailing_metadata.each do |key, value|
232
+ trailers[key] = \
233
+ if key.to_s.end_with?("-bin")
234
+ Base64.strict_encode64(value.to_s)
235
+ else
236
+ value.to_s
237
+ end
238
+ end
239
+
240
+ send_trailers(trailers)
241
+ end
242
+
243
+ def send_trailers(trailers)
244
+ stream.send_trailers(trailers)
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,106 @@
1
+ module Itsi
2
+ class Server
3
+ class GrpcInterface
4
+ DeadlineExceeded = Class.new(StandardError)
5
+
6
+ attr_accessor :service, :service_class
7
+
8
+ def self.for(service)
9
+ interface = new(service)
10
+ lambda do |request|
11
+ interface.handle_request(request)
12
+ end
13
+ end
14
+
15
+ def self.reflection_for(handlers)
16
+ require_relative "reflection/v1/reflection_services_pb"
17
+ interface = new(Grpc::Reflection::V1::ServerReflection::Service.new(handlers))
18
+ lambda do |request|
19
+ interface.handle_request(request)
20
+ end
21
+ end
22
+
23
+ def initialize(service)
24
+ @service = service
25
+ @service_class = service.class
26
+ @rpc_descs = @service_class.rpc_descs.transform_keys do |k|
27
+ k.to_s.gsub(/([a-z])([A-Z])/, "\\1_\\2").downcase.to_sym
28
+ end
29
+ end
30
+
31
+ def handle_request(active_call)
32
+ unless (active_call.rpc_desc = @rpc_descs[active_call.method_name])
33
+ active_call.stream.write("\n")
34
+ active_call.send_status(13, "Method not found")
35
+ active_call.close
36
+ return
37
+ end
38
+
39
+ active_call.send_initial_metadata(
40
+ {
41
+ "grpc-accept-encoding" => "gzip, deflate, identity",
42
+ "content-type" => active_call.json? ? "application/json" : "application/grpc"
43
+ }
44
+ )
45
+
46
+ begin
47
+ if active_call.bidi_streamer?
48
+ handle_bidi_streaming(active_call)
49
+ elsif active_call.client_streamer?
50
+ handle_client_streaming(active_call)
51
+ elsif active_call.server_streamer?
52
+ handle_server_streaming(active_call)
53
+ elsif active_call.request_response?
54
+ handle_unary(active_call)
55
+ end
56
+ active_call.send_status(0, "Success")
57
+ rescue Google::Protobuf::ParseError => e
58
+ active_call.send_empty
59
+ active_call.send_status(3, e.message)
60
+ rescue DeadlineExceeded => e
61
+ active_call.send_empty
62
+ active_call.send_status(4, e.message)
63
+ rescue StandardError => e
64
+ active_call.send_empty
65
+ active_call.send_status(13, e.message)
66
+ end
67
+ rescue StandardError => e
68
+ Itsi.log_warn("Unhandled error in grpc_interface: #{e.message}")
69
+ ensure
70
+ active_call.close
71
+ end
72
+
73
+ private
74
+
75
+ def handle_unary(active_call)
76
+ message = active_call.remote_read
77
+ response = service.send(active_call.method_name, message, active_call)
78
+ active_call.remote_send(response)
79
+ end
80
+
81
+ def handle_client_streaming(active_call)
82
+ response = service.send(active_call.method_name, active_call)
83
+ active_call.remote_send(response)
84
+ end
85
+
86
+ def handle_server_streaming(active_call)
87
+ message = active_call.remote_read
88
+ result = service.send(active_call.method_name, message, active_call) do |response|
89
+ active_call.remote_send(response)
90
+ end
91
+ return unless result.is_a?(Enumerator)
92
+
93
+ result.each { |response| active_call.remote_send(response) }
94
+ end
95
+
96
+ def handle_bidi_streaming(active_call)
97
+ result = service.send(active_call.method_name, active_call.each, active_call) do |response|
98
+ active_call.remote_send(response)
99
+ end
100
+ return unless result.is_a?(Enumerator)
101
+
102
+ result.each { |response| active_call.remote_send(response) }
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: reflection.proto
4
+
5
+ require 'google/protobuf'
6
+ require "google/protobuf/descriptor_pb"
7
+
8
+ descriptor_data = "\n\x10reflection.proto\x12\x12grpc.reflection.v1\"\x85\x02\n\x17ServerReflectionRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x1a\n\x10\x66ile_by_filename\x18\x03 \x01(\tH\x00\x12 \n\x16\x66ile_containing_symbol\x18\x04 \x01(\tH\x00\x12I\n\x19\x66ile_containing_extension\x18\x05 \x01(\x0b\x32$.grpc.reflection.v1.ExtensionRequestH\x00\x12\'\n\x1d\x61ll_extension_numbers_of_type\x18\x06 \x01(\tH\x00\x12\x17\n\rlist_services\x18\x07 \x01(\tH\x00\x42\x11\n\x0fmessage_request\"E\n\x10\x45xtensionRequest\x12\x17\n\x0f\x63ontaining_type\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x01(\x05\"\xb8\x03\n\x18ServerReflectionResponse\x12\x12\n\nvalid_host\x18\x01 \x01(\t\x12\x45\n\x10original_request\x18\x02 \x01(\x0b\x32+.grpc.reflection.v1.ServerReflectionRequest\x12N\n\x18\x66ile_descriptor_response\x18\x04 \x01(\x0b\x32*.grpc.reflection.v1.FileDescriptorResponseH\x00\x12U\n\x1e\x61ll_extension_numbers_response\x18\x05 \x01(\x0b\x32+.grpc.reflection.v1.ExtensionNumberResponseH\x00\x12I\n\x16list_services_response\x18\x06 \x01(\x0b\x32\'.grpc.reflection.v1.ListServiceResponseH\x00\x12;\n\x0e\x65rror_response\x18\x07 \x01(\x0b\x32!.grpc.reflection.v1.ErrorResponseH\x00\x42\x12\n\x10message_response\"7\n\x16\x46ileDescriptorResponse\x12\x1d\n\x15\x66ile_descriptor_proto\x18\x01 \x03(\x0c\"K\n\x17\x45xtensionNumberResponse\x12\x16\n\x0e\x62\x61se_type_name\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x03(\x05\"K\n\x13ListServiceResponse\x12\x34\n\x07service\x18\x01 \x03(\x0b\x32#.grpc.reflection.v1.ServiceResponse\"\x1f\n\x0fServiceResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\":\n\rErrorResponse\x12\x12\n\nerror_code\x18\x01 \x01(\x05\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x89\x01\n\x10ServerReflection\x12u\n\x14ServerReflectionInfo\x12+.grpc.reflection.v1.ServerReflectionRequest\x1a,.grpc.reflection.v1.ServerReflectionResponse(\x01\x30\x01\x42\x66\n\x15io.grpc.reflection.v1B\x15ServerReflectionProtoP\x01Z4google.golang.org/grpc/reflection/grpc_reflection_v1b\x06proto3"
9
+
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Grpc
14
+ module Reflection
15
+ module V1
16
+ ServerReflectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionRequest").msgclass
17
+ ExtensionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionRequest").msgclass
18
+ ServerReflectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionResponse").msgclass
19
+ FileDescriptorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.FileDescriptorResponse").msgclass
20
+ ExtensionNumberResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionNumberResponse").msgclass
21
+ ListServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ListServiceResponse").msgclass
22
+ ServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServiceResponse").msgclass
23
+ ErrorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ErrorResponse").msgclass
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,122 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # Source: reflection.proto for package 'grpc.reflection.v1'
3
+ # Original file comments:
4
+ # Copyright 2016 The gRPC Authors
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ # Service exported by server reflection. A more complete description of how
19
+ # server reflection works can be found at
20
+ # https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
21
+ #
22
+ # The canonical version of this proto can be found at
23
+ # https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto
24
+ #
25
+
26
+ require "grpc"
27
+ require_relative "reflection_pb"
28
+
29
+ module Grpc
30
+ module Reflection
31
+ module V1
32
+ module ServerReflection
33
+ class Service
34
+ include ::GRPC::GenericService
35
+
36
+ self.marshal_class_method = :encode
37
+ self.unmarshal_class_method = :decode
38
+ self.service_name = "grpc.reflection.v1.ServerReflection"
39
+
40
+ # The reflection service is structured as a bidirectional stream, ensuring
41
+ # all related requests go to a single server.
42
+ rpc :ServerReflectionInfo, stream(::Grpc::Reflection::V1::ServerReflectionRequest),
43
+ stream(::Grpc::Reflection::V1::ServerReflectionResponse)
44
+
45
+ def initialize(handlers)
46
+ @handlers = handlers
47
+ super()
48
+ end
49
+
50
+ def server_reflection_info(req, _unused_call)
51
+ req.each do |request|
52
+ res = Grpc::Reflection::V1::ServerReflectionResponse.new
53
+
54
+ if !request.list_services.empty?
55
+ res.list_services_response = Grpc::Reflection::V1::ListServiceResponse.new(service: list_services_response)
56
+ elsif !request.file_containing_symbol.empty?
57
+ res.file_descriptor_response = Grpc::Reflection::V1::FileDescriptorResponse.new(
58
+ file_descriptor_proto: [
59
+ Google::Protobuf::FileDescriptorProto.encode(Google::Protobuf::DescriptorPool.generated_pool.lookup(request.file_containing_symbol).file_descriptor.to_proto)
60
+ ]
61
+ )
62
+ elsif !request.file_by_filename.empty?
63
+ # Handle file_by_filename requests
64
+ file_descriptor = find_file_descriptor_by_filename(request.file_by_filename)
65
+ if file_descriptor
66
+ res.file_descriptor_response = Grpc::Reflection::V1::FileDescriptorResponse.new(
67
+ file_descriptor_proto: [Google::Protobuf::FileDescriptorProto.encode(file_descriptor)]
68
+ )
69
+ else
70
+ res.error_response = Grpc::Reflection::V1::ErrorResponse.new(
71
+ error_code: 5, # NOT_FOUND
72
+ error_message: "File not found: #{request.file_by_filename}"
73
+ )
74
+ end
75
+ end
76
+ yield res
77
+ # We can loop here if running in Fiber mode, but for best compatibility with blocking IO modes
78
+ # we'll close the connection and force the client to reconnect force
79
+ # subsequent reflection requests
80
+ break
81
+ end
82
+ end
83
+
84
+ def find_file_descriptor_by_filename(filename)
85
+ # First try direct lookup in the pool
86
+
87
+ descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(filename)&.file_descriptor
88
+ return descriptor.to_proto if descriptor
89
+
90
+ proto_name = convert_file_path_to_proto_name(filename)
91
+ descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(proto_name)&.file_descriptor
92
+ return descriptor.to_proto if descriptor
93
+
94
+ nil
95
+ end
96
+
97
+ def convert_file_path_to_proto_name(file_path)
98
+ # Remove .proto extension
99
+ file_path = file_path.sub(/\.proto$/, "")
100
+
101
+ # Split path into parts
102
+ parts = file_path.split("/")
103
+
104
+ # Convert last part to PascalCase (e.g., money -> Money)
105
+ parts[-1] = parts[-1].split("_").map(&:capitalize).join
106
+
107
+ # Join with dots
108
+ parts.join(".")
109
+ end
110
+
111
+ def list_services_response
112
+ @list_services_response ||= @handlers.map(&:class).map(&:service_name).map do |name|
113
+ Grpc::Reflection::V1::ServiceResponse.new(name: name)
114
+ end
115
+ end
116
+ end
117
+
118
+ Stub = Service.rpc_stub_class
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+
5
+ module Itsi
6
+ class Server
7
+ module NativeExtension
8
+ module_function
9
+
10
+ def require!
11
+ ruby_abi = RUBY_VERSION[/\A\d+\.\d+/]
12
+
13
+ if ruby_abi && versioned_binary_present?(ruby_abi)
14
+ begin
15
+ require_relative "#{ruby_abi}/itsi_server"
16
+ return
17
+ rescue LoadError
18
+ # Fall back to the source-built extension when a packaged binary
19
+ # exists but cannot be loaded on this machine.
20
+ end
21
+ end
22
+
23
+ require_relative "itsi_server"
24
+ end
25
+
26
+ def versioned_binary_present?(ruby_abi)
27
+ binary_path = File.join(__dir__, ruby_abi, "itsi_server.#{RbConfig::CONFIG.fetch("DLEXT")}")
28
+ File.exist?(binary_path)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ Itsi::Server::NativeExtension.require!
@@ -0,0 +1,29 @@
1
+ return unless defined?(::Rackup::Handler) || defined?(Rack::Handler)
2
+
3
+ module Rack
4
+ module Handler
5
+ module Itsi
6
+ def self.run(app, options = {})
7
+ host = options.fetch(:host, "127.0.0.1")
8
+ port = options.fetch(:Port, 3001)
9
+ ::Itsi::Server.start(
10
+ {
11
+ binds: ["http://#{host}:#{port}"],
12
+ threads: 5,
13
+ workers: 1
14
+ }
15
+ ) do
16
+ run app
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ if defined?(Rackup)
24
+ ::Rackup::Handler.register("itsi", Rack::Handler::Itsi)
25
+ ::Rackup::Handler.register("Itsi", Rack::Handler::Itsi)
26
+ elsif defined?(Rack)
27
+ ::Rack::Handler.register("itsi", Rack::Handler::Itsi)
28
+ ::Rack::Handler.register("Itsi", Rack::Handler::Itsi)
29
+ end
@@ -0,0 +1,109 @@
1
+ module Itsi
2
+ class Server
3
+ module RackInterface
4
+ # Builds a handler proc that is compatible with Rack applications.
5
+ def self.for(app)
6
+ require "rack"
7
+ if app.is_a?(String)
8
+ dir = File.expand_path(File.dirname(app))
9
+ Dir.chdir(dir) do
10
+ loaded_app = ::Rack::Builder.parse_file(File.basename(app))
11
+ app = loaded_app.is_a?(Array) ? loaded_app.first : loaded_app
12
+ end
13
+ end
14
+ lambda do |request|
15
+ Server.respond(request, app.call(env = request.to_rack_env), env)
16
+ end
17
+ end
18
+
19
+ # Interface to Rack applications.
20
+ # Here we build the env, and invoke the Rack app's call method.
21
+ # We then turn the Rack response into something Itsi server understands.
22
+ def call(app, request)
23
+ respond request, app.call(env = request.to_rack_env), env
24
+ end
25
+
26
+ # Itsi responses are asynchronous and can be streamed.
27
+ # Response chunks are sent using response.send_frame
28
+ # and the response is finished using response.close_write.
29
+ # If only a single chunk is written, you can use the #send_and_close method.
30
+ def respond(request, (status, headers, body), env)
31
+ response = request.response
32
+
33
+ # Don't try and respond if we've been hijacked.
34
+ # The hijacker is now responsible for this.
35
+ return if request.hijacked
36
+
37
+ # 1. Set Status
38
+ response.status = status
39
+
40
+ # 2. Set Headers
41
+ body_streamer = streaming_body?(body) ? body : headers.delete("rack.hijack")
42
+
43
+ response.reserve_headers(headers.size)
44
+
45
+ for key, value in headers
46
+ case value
47
+ when String then response[key] = value
48
+ when Array
49
+ value.each do |v|
50
+ response[key] = v
51
+ end
52
+ end
53
+ end
54
+
55
+ # 3. Set Body
56
+ # As soon as we start setting the response
57
+ # the server will begin to stream it to the client.
58
+
59
+
60
+ if body_streamer
61
+ # If we're partially hijacked or returned a streaming body,
62
+ # stream this response.
63
+ body_streamer.call(response)
64
+
65
+ elsif body.is_a?(Array)
66
+ if body.length == 1
67
+ response.send_and_close(body[0].to_s)
68
+ else
69
+ buffer = nil
70
+ body.each do |part|
71
+ response << buffer.to_s if buffer
72
+ buffer = part
73
+ end
74
+
75
+ response.send_and_close(buffer.to_s)
76
+ end
77
+ elsif body.respond_to?(:each) || body.respond_to?(:to_ary)
78
+ # If we're enumerable with more than one chunk
79
+ # also stream, otherwise write in a single chunk
80
+ unless body.respond_to?(:each)
81
+ body = body.to_ary
82
+ raise "Body #to_ary didn't return an array" unless body.is_a?(Array)
83
+ end
84
+ # We offset this iteration intentionally,
85
+ # to optimize for the case where there's only one chunk.
86
+ buffer = nil
87
+ body.each do |part|
88
+ response << buffer.to_s if buffer
89
+ buffer = part
90
+ end
91
+
92
+ response.send_and_close(buffer.to_s)
93
+ else
94
+ response.send_and_close(body.to_s)
95
+ end
96
+ rescue EOFError
97
+ response.close
98
+ ensure
99
+ RackEnvPool.checkin(env)
100
+ body.close if body.respond_to?(:close)
101
+ end
102
+
103
+ # A streaming body is one that responds to #call and not #each.
104
+ def streaming_body?(body)
105
+ body.respond_to?(:call) && !body.respond_to?(:each)
106
+ end
107
+ end
108
+ end
109
+ end