itsi-server 0.1.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +4487 -0
  3. data/Cargo.toml +7 -0
  4. data/README.md +6 -0
  5. data/Rakefile +7 -4
  6. data/exe/itsi +152 -46
  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.toml +3 -0
  30. data/ext/itsi_error/src/lib.rs +98 -24
  31. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  32. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  33. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  34. data/ext/itsi_error/target/debug/build/rb-sys-49f554618693db24/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  35. data/ext/itsi_error/target/debug/incremental/itsi_error-1mmt5sux7jb0i/s-h510z7m8v9-0bxu7yd.lock +0 -0
  36. data/ext/itsi_error/target/debug/incremental/itsi_error-2vn3jey74oiw0/s-h5113n0e7e-1v5qzs6.lock +0 -0
  37. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510ykifhe-0tbnep2.lock +0 -0
  38. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510yyocpj-0tz7ug7.lock +0 -0
  39. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510z0xc8g-14ol18k.lock +0 -0
  40. data/ext/itsi_error/target/debug/incremental/itsi_error-3g5qf4y7d54uj/s-h5113n0e7d-1trk8on.lock +0 -0
  41. data/ext/itsi_error/target/debug/incremental/itsi_error-3lpfftm45d3e2/s-h510z7m8r3-1pxp20o.lock +0 -0
  42. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510ykifek-1uxasnk.lock +0 -0
  43. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510yyocki-11u37qm.lock +0 -0
  44. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510z0xc93-0pmy0zm.lock +0 -0
  45. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  46. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  47. data/ext/itsi_rb_helpers/Cargo.toml +3 -0
  48. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  49. data/ext/itsi_rb_helpers/src/lib.rs +141 -10
  50. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  51. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  52. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  53. data/ext/itsi_rb_helpers/target/debug/build/rb-sys-eb9ed4ff3a60f995/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  54. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-040pxg6yhb3g3/s-h5113n7a1b-03bwlt4.lock +0 -0
  55. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h51113xnh3-1eik1ip.lock +0 -0
  56. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h5111704jj-0g4rj8x.lock +0 -0
  57. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-1q2d3drtxrzs5/s-h5113n79yl-0bxcqc5.lock +0 -0
  58. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h51113xoox-10de2hp.lock +0 -0
  59. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h5111704w7-0vdq7gq.lock +0 -0
  60. data/ext/itsi_scheduler/Cargo.toml +24 -0
  61. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  62. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  63. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  64. data/ext/itsi_scheduler/src/itsi_scheduler.rs +314 -0
  65. data/ext/itsi_scheduler/src/lib.rs +39 -0
  66. data/ext/itsi_server/Cargo.lock +2956 -0
  67. data/ext/itsi_server/Cargo.toml +75 -14
  68. data/ext/itsi_server/extconf.rb +1 -1
  69. data/ext/itsi_server/src/default_responses/html/401.html +68 -0
  70. data/ext/itsi_server/src/default_responses/html/403.html +68 -0
  71. data/ext/itsi_server/src/default_responses/html/404.html +68 -0
  72. data/ext/itsi_server/src/default_responses/html/413.html +71 -0
  73. data/ext/itsi_server/src/default_responses/html/429.html +68 -0
  74. data/ext/itsi_server/src/default_responses/html/500.html +71 -0
  75. data/ext/itsi_server/src/default_responses/html/502.html +71 -0
  76. data/ext/itsi_server/src/default_responses/html/503.html +68 -0
  77. data/ext/itsi_server/src/default_responses/html/504.html +69 -0
  78. data/ext/itsi_server/src/default_responses/html/index.html +238 -0
  79. data/ext/itsi_server/src/default_responses/json/401.json +6 -0
  80. data/ext/itsi_server/src/default_responses/json/403.json +6 -0
  81. data/ext/itsi_server/src/default_responses/json/404.json +6 -0
  82. data/ext/itsi_server/src/default_responses/json/413.json +6 -0
  83. data/ext/itsi_server/src/default_responses/json/429.json +6 -0
  84. data/ext/itsi_server/src/default_responses/json/500.json +6 -0
  85. data/ext/itsi_server/src/default_responses/json/502.json +6 -0
  86. data/ext/itsi_server/src/default_responses/json/503.json +6 -0
  87. data/ext/itsi_server/src/default_responses/json/504.json +6 -0
  88. data/ext/itsi_server/src/default_responses/mod.rs +11 -0
  89. data/ext/itsi_server/src/env.rs +43 -0
  90. data/ext/itsi_server/src/lib.rs +133 -40
  91. data/ext/itsi_server/src/prelude.rs +2 -0
  92. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +109 -0
  93. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +143 -0
  94. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +344 -0
  95. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +264 -0
  96. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +362 -0
  97. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +391 -0
  98. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +233 -0
  99. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +565 -0
  100. data/ext/itsi_server/src/ruby_types/itsi_server.rs +86 -0
  101. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  102. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  103. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  104. data/ext/itsi_server/src/server/binds/listener.rs +444 -0
  105. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  106. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  107. data/ext/itsi_server/src/server/binds/tls.rs +278 -0
  108. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  109. data/ext/itsi_server/src/server/http_message_types.rs +97 -0
  110. data/ext/itsi_server/src/server/io_stream.rs +105 -0
  111. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  112. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  113. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +94 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +316 -0
  119. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +301 -0
  120. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  121. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  122. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +192 -0
  123. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +171 -0
  124. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +198 -0
  125. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  126. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
  127. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
  128. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  129. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +116 -0
  130. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +411 -0
  131. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +142 -0
  132. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +55 -0
  133. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  134. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
  135. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +126 -0
  136. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +187 -0
  137. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +55 -0
  138. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +173 -0
  139. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  140. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  141. data/ext/itsi_server/src/server/mod.rs +13 -5
  142. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  143. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  144. data/ext/itsi_server/src/server/request_job.rs +11 -0
  145. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +354 -0
  146. data/ext/itsi_server/src/server/serve_strategy/mod.rs +30 -0
  147. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +481 -0
  148. data/ext/itsi_server/src/server/signal.rs +77 -0
  149. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  150. data/ext/itsi_server/src/server/thread_worker.rs +479 -0
  151. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  152. data/ext/itsi_server/src/services/itsi_http_service.rs +257 -0
  153. data/ext/itsi_server/src/services/mime_types.rs +1416 -0
  154. data/ext/itsi_server/src/services/mod.rs +6 -0
  155. data/ext/itsi_server/src/services/password_hasher.rs +83 -0
  156. data/ext/itsi_server/src/services/rate_limiter.rs +580 -0
  157. data/ext/itsi_server/src/services/static_file_server.rs +1340 -0
  158. data/ext/itsi_tracing/Cargo.toml +5 -0
  159. data/ext/itsi_tracing/src/lib.rs +366 -7
  160. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
  161. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
  162. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
  163. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
  164. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
  165. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
  166. data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
  167. data/lib/itsi/http_request.rb +218 -0
  168. data/lib/itsi/http_response.rb +42 -0
  169. data/lib/itsi/passfile.rb +108 -0
  170. data/lib/itsi/server/config/config_helpers.rb +105 -0
  171. data/lib/itsi/server/config/dsl.rb +211 -0
  172. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  173. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  174. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  175. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  176. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  177. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  178. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  179. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  180. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  181. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  182. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  183. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  184. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  185. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  186. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  187. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  188. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  189. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  190. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  191. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  192. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  193. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  194. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  212. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  213. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  214. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  215. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  216. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  217. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  218. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  219. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  220. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  221. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  222. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  223. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  224. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  225. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  226. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  227. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  228. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  229. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  230. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  231. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  232. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  233. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  234. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  235. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  236. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  237. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  238. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  239. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  240. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  241. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  242. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  254. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  255. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  256. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  257. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  258. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  259. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  260. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  261. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  262. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  263. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  264. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  265. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  266. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  267. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  268. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  269. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  270. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  271. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  272. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  273. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  274. data/lib/itsi/server/config/known_paths.rb +20 -0
  275. data/lib/itsi/server/config/middleware/_index.md +56 -0
  276. data/lib/itsi/server/config/middleware/allow_list.md +46 -0
  277. data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  278. data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  279. data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  280. data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  281. data/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
  282. data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  283. data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  284. data/lib/itsi/server/config/middleware/cache_control.md +78 -0
  285. data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  286. data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  287. data/lib/itsi/server/config/middleware/compression.md +50 -0
  288. data/lib/itsi/server/config/middleware/compression.rb +37 -0
  289. data/lib/itsi/server/config/middleware/cors.md +93 -0
  290. data/lib/itsi/server/config/middleware/cors.rb +32 -0
  291. data/lib/itsi/server/config/middleware/csp.md +37 -0
  292. data/lib/itsi/server/config/middleware/csp.rb +44 -0
  293. data/lib/itsi/server/config/middleware/deny_list.md +45 -0
  294. data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  295. data/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
  296. data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  297. data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  298. data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  299. data/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
  300. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
  301. data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  302. data/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
  303. data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  304. data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  305. data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  306. data/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
  307. data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  308. data/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
  309. data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  310. data/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
  311. data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  312. data/lib/itsi/server/config/middleware/error_response.md +61 -0
  313. data/lib/itsi/server/config/middleware/error_response.rb +36 -0
  314. data/lib/itsi/server/config/middleware/etag.md +59 -0
  315. data/lib/itsi/server/config/middleware/etag.rb +27 -0
  316. data/lib/itsi/server/config/middleware/grpc.md +172 -0
  317. data/lib/itsi/server/config/middleware/grpc.rb +54 -0
  318. data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  319. data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  320. data/lib/itsi/server/config/middleware/location.md +107 -0
  321. data/lib/itsi/server/config/middleware/location.rb +99 -0
  322. data/lib/itsi/server/config/middleware/log_requests.md +65 -0
  323. data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  324. data/lib/itsi/server/config/middleware/max_body.md +18 -0
  325. data/lib/itsi/server/config/middleware/max_body.rb +21 -0
  326. data/lib/itsi/server/config/middleware/proxy.md +62 -0
  327. data/lib/itsi/server/config/middleware/proxy.rb +41 -0
  328. data/lib/itsi/server/config/middleware/rackup_file.md +54 -0
  329. data/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
  330. data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  331. data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  332. data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  333. data/lib/itsi/server/config/middleware/redirect.md +55 -0
  334. data/lib/itsi/server/config/middleware/redirect.rb +25 -0
  335. data/lib/itsi/server/config/middleware/request_headers.md +34 -0
  336. data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  337. data/lib/itsi/server/config/middleware/response_headers.md +33 -0
  338. data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  339. data/lib/itsi/server/config/middleware/run.md +60 -0
  340. data/lib/itsi/server/config/middleware/run.rb +43 -0
  341. data/lib/itsi/server/config/middleware/static_assets.md +73 -0
  342. data/lib/itsi/server/config/middleware/static_assets.rb +87 -0
  343. data/lib/itsi/server/config/middleware/static_response.md +44 -0
  344. data/lib/itsi/server/config/middleware/static_response.rb +29 -0
  345. data/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
  346. data/lib/itsi/server/config/middleware/token_source.rb +32 -0
  347. data/lib/itsi/server/config/middleware.rb +13 -0
  348. data/lib/itsi/server/config/option.rb +14 -0
  349. data/lib/itsi/server/config/options/_index.md +37 -0
  350. data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  351. data/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
  352. data/lib/itsi/server/config/options/bind.md +71 -0
  353. data/lib/itsi/server/config/options/bind.rb +26 -0
  354. data/lib/itsi/server/config/options/certificates.md +65 -0
  355. data/lib/itsi/server/config/options/daemonize.md +14 -0
  356. data/lib/itsi/server/config/options/daemonize.rb +19 -0
  357. data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  358. data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  359. data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  360. data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  361. data/lib/itsi/server/config/options/hooks/_index.md +11 -0
  362. data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  363. data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  364. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  365. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  366. data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  367. data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  368. data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  369. data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  370. data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  371. data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  372. data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  373. data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  374. data/lib/itsi/server/config/options/include.md +20 -0
  375. data/lib/itsi/server/config/options/include.rb +36 -0
  376. data/lib/itsi/server/config/options/listen_backlog.md +11 -0
  377. data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  378. data/lib/itsi/server/config/options/log_format.md +18 -0
  379. data/lib/itsi/server/config/options/log_format.rb +19 -0
  380. data/lib/itsi/server/config/options/log_level.md +34 -0
  381. data/lib/itsi/server/config/options/log_level.rb +20 -0
  382. data/lib/itsi/server/config/options/log_target.md +38 -0
  383. data/lib/itsi/server/config/options/log_target.rb +19 -0
  384. data/lib/itsi/server/config/options/log_target_filters.md +17 -0
  385. data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  386. data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  387. data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  388. data/lib/itsi/server/config/options/nodelay.md +16 -0
  389. data/lib/itsi/server/config/options/nodelay.rb +19 -0
  390. data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  391. data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  392. data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  393. data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  394. data/lib/itsi/server/config/options/preload.md +21 -0
  395. data/lib/itsi/server/config/options/preload.rb +18 -0
  396. data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  397. data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  398. data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  399. data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  400. data/lib/itsi/server/config/options/request_timeout.md +23 -0
  401. data/lib/itsi/server/config/options/request_timeout.rb +19 -0
  402. data/lib/itsi/server/config/options/reuse_address.md +16 -0
  403. data/lib/itsi/server/config/options/reuse_address.rb +19 -0
  404. data/lib/itsi/server/config/options/reuse_port.md +16 -0
  405. data/lib/itsi/server/config/options/reuse_port.rb +19 -0
  406. data/lib/itsi/server/config/options/scheduler_threads.md +34 -0
  407. data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  408. data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  409. data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  410. data/lib/itsi/server/config/options/stream_body.md +32 -0
  411. data/lib/itsi/server/config/options/stream_body.rb +18 -0
  412. data/lib/itsi/server/config/options/threads.md +44 -0
  413. data/lib/itsi/server/config/options/threads.rb +17 -0
  414. data/lib/itsi/server/config/options/watch.md +16 -0
  415. data/lib/itsi/server/config/options/watch.rb +28 -0
  416. data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  417. data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  418. data/lib/itsi/server/config/options/workers.md +42 -0
  419. data/lib/itsi/server/config/options/workers.rb +17 -0
  420. data/lib/itsi/server/config/typed_struct.rb +242 -0
  421. data/lib/itsi/server/config.rb +289 -0
  422. data/lib/itsi/server/default_app/default_app.rb +34 -0
  423. data/lib/itsi/server/default_app/index.html +115 -0
  424. data/lib/itsi/server/default_config/Itsi.rb +107 -0
  425. data/lib/itsi/server/grpc/grpc_call.rb +246 -0
  426. data/lib/itsi/server/grpc/grpc_interface.rb +107 -0
  427. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  428. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  429. data/lib/itsi/server/rack/handler/itsi.rb +27 -0
  430. data/lib/itsi/server/rack_interface.rb +94 -0
  431. data/lib/itsi/server/route_tester.rb +157 -0
  432. data/lib/itsi/server/scheduler_interface.rb +21 -0
  433. data/lib/itsi/server/scheduler_mode.rb +10 -0
  434. data/lib/itsi/server/signal_trap.rb +33 -0
  435. data/lib/itsi/server/typed_handlers/param_parser.rb +196 -0
  436. data/lib/itsi/server/typed_handlers/source_parser.rb +56 -0
  437. data/lib/itsi/server/typed_handlers.rb +25 -0
  438. data/lib/itsi/server/version.rb +1 -1
  439. data/lib/itsi/server.rb +265 -9
  440. data/lib/itsi/standard_headers.rb +86 -0
  441. data/lib/ruby_lsp/itsi/addon.rb +129 -0
  442. data/lib/shell_completions/completions.rb +26 -0
  443. metadata +454 -28
  444. data/CHANGELOG.md +0 -5
  445. data/CODE_OF_CONDUCT.md +0 -132
  446. data/LICENSE.txt +0 -21
  447. data/ext/itsi_server/src/request/itsi_request.rs +0 -143
  448. data/ext/itsi_server/src/request/mod.rs +0 -1
  449. data/ext/itsi_server/src/server/bind.rs +0 -138
  450. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -32
  451. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -52
  452. data/ext/itsi_server/src/server/itsi_server.rs +0 -182
  453. data/ext/itsi_server/src/server/listener.rs +0 -218
  454. data/ext/itsi_server/src/server/tls.rs +0 -138
  455. data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
  456. data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
  457. data/lib/itsi/request.rb +0 -39
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the default Itsi configuration file, installed when you run `itsi init`
4
+ # It contains a sane starting point for configuring your Itsi server.
5
+ # You can use this file in both development and production environments.
6
+ # Most of the options in this file can be overridden by command line options.
7
+ # Check out itsi -h to learn more about the command line options available to you.
8
+
9
+ env = ENV.fetch("APP_ENV") { ENV.fetch("RACK_ENV", "development") }
10
+
11
+ # Number of worker processes to spawn
12
+ # If more than 1, Itsi will be booted in Cluster mode
13
+ workers ENV.fetch("ITSI_WORKERS") {
14
+ require "etc"
15
+ env == "development" ? 1 : nil
16
+ }
17
+
18
+ # Number of threads to spawn per worker process
19
+ # For pure CPU bound applicationss, you'll get the best results keeping this number low
20
+ # Setting a value of 1 is great for superficial benchmarks, but in reality
21
+ # it's better to set this a bit higher to allow expensive requests to get overtaken and minimize head-of-line blocking
22
+ threads ENV.fetch("ITSI_THREADS", 3)
23
+
24
+ # If your application is IO bound (e.g. performing a lot of proxied HTTP requests, or heavy queries etc)
25
+ # you can see *substantial* benefits from enabling this option.
26
+ # To set this option, pass a string, not a class (as we will not have loaded the class yet)
27
+ # E.g.
28
+ # `fiber_scheduler "Itsi::Scheduler"` - The default fast and light-weight scheduler that comes with Itsi
29
+ # `fiber_scheduler "Async::Scheduler"` - Bring your own scheduler!
30
+ fiber_scheduler nil
31
+
32
+ # If you bind to https, without specifying a certificate, Itsi will use a self-signed certificate.
33
+ # The self-signed certificate will use a CA generated for your host and stored inside `ITSI_LOCAL_CA_DIR` (Defaults to ~/.itsi)
34
+ # bind "https://localhost:3000"
35
+ # bind "https://localhost:3000?domains=dev.itsi.fyi"
36
+ #
37
+ # If you want to use let's encrypt to generate you a real certificate you and pass cert=acme and an acme_email address to generate one.
38
+ # bind "https://itsi.fyi?cert=acme&acme_email=admin@itsi.fyi"
39
+ # You can generate certificates for multiple domains at once, by passing a comma-separated list of domains
40
+ # bind "https://0.0.0.0?domains=foo.itsi.fyi,bar.itsi.fyi&cert=acme&acme_email=admin@itsi.fyi"
41
+ #
42
+ # If you already have a certificate you can specify it using the cert and key parameters
43
+ # bind "https://itsi.fyi?cert=/path/to/cert.pem&key=/path/to/key.pem"
44
+ #
45
+ # You can also bind to a unix socket or a tls unix socket. E.g.
46
+ # bind "unix:///tmp/itsi.sock"
47
+ # bind "tls:///tmp/itsi.secure.sock"
48
+
49
+ if env == "development"
50
+ bind "http://localhost:3000"
51
+ else
52
+ bind "https://0.0.0.0?domains=#{ENV["PRODUCTION_DOMAINS"]}&cert=acme&acme_email=admin@itsi.fyi"
53
+ end
54
+
55
+ # If you want to preload the application, set preload to true
56
+ # to load the entire rack-app defined in rack_file_name before forking.
57
+ # Alternatively, you can preload just a specific set of gems in a group in your gemfile,
58
+ # by providing the group name here.
59
+ # E.g.
60
+ #
61
+ # preload :preload # Load gems inside the preload group
62
+ # preload false # Don't preload.
63
+ #
64
+ # If you want to be able to perform zero-downtime deploys using a single itsi process,
65
+ # you should disable preloads, so that the application is loaded fresh each time a new worker boots
66
+ preload true
67
+
68
+ # Set the maximum memory limit for each worker process in bytes
69
+ # When this limit is reached, the worker will be gracefully restarted.
70
+ # Only one worker is restarted at a time to ensure we don't take down
71
+ # all of them at once, if they reach the threshold simultaneously.
72
+ worker_memory_limit 1024 * 1024 * 1024
73
+
74
+ # You can provide an optional block of code to run, when a worker hits its memory threshold (Use this to send yourself an alert,
75
+ # write metrics to disk etc. etc.)
76
+ after_memory_limit_reached do |pid|
77
+ puts "Worker #{pid} has reached its memory threshold and will restart"
78
+ end
79
+
80
+ # Do clean up of any non-threadsafe resources before forking a new worker here.
81
+ before_fork {}
82
+
83
+ # Reinitialize any non-threadsafe resources after forking a new worker here.
84
+ after_fork {}
85
+
86
+ # Shutdown timeout
87
+ # Number of seconds to wait for workers to gracefully shutdown before killing them.
88
+ shutdown_timeout 5
89
+
90
+ # Set this to false for application environments that require rack.input to be a rewindable body
91
+ # (like Rails). For rack applications that can stream inputs, you can set this to true for a more memory-efficient approach.
92
+ stream_body false
93
+
94
+ # OOB GC responses threshold
95
+ # Specifies how frequently OOB gc should be triggered during periods where there is a gap in queued requests.
96
+ # Setting this too low can substantially worsen performance
97
+ oob_gc_responses_threshold 512
98
+
99
+ # Log level
100
+ # Set this to one of the following values: debug, info, warn, error, fatal
101
+ # Can also be set using the ITSI_LOG environment variable
102
+ log_level :info
103
+
104
+ # Log Format
105
+ # Set this to be either :plain or :json. If you leave it blank Itsi will try
106
+ # and auto-detect the format based on the TTY environment.
107
+ log_format :plain
@@ -0,0 +1,246 @@
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
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
+
93
+ if in_string
94
+ if escape
95
+ escape = false
96
+ next
97
+ end
98
+ if ch == "\\"
99
+ escape = true
100
+ elsif ch == '"'
101
+ in_string = false
102
+ end
103
+ elsif ch == '"'
104
+ in_string = true
105
+ elsif ["{", "["].include?(ch)
106
+ stack.push(ch)
107
+ elsif ["}", "]"].include?(ch)
108
+ expected = (ch == "}" ? "{" : "[")
109
+ # Check for matching bracket.
110
+ return nil unless stack.last == expected
111
+
112
+ stack.pop
113
+ end
114
+ end
115
+ # Yield the complete JSON object (as a string).
116
+ return buffer
117
+ end
118
+ end
119
+
120
+ def remote_read
121
+ if content_type == "application/json"
122
+ if input_stream?
123
+ if next_item = parse_from_json_stream(reader)
124
+ input_type.decode_json(next_item)
125
+ end
126
+ else
127
+ input_type.decode_json(reader.read)
128
+ end
129
+ else
130
+ header = reader.read(5)
131
+ return nil if header.nil? || header.bytesize < 5
132
+
133
+ compressed = header.bytes[0] == 1
134
+ length = header[1..4].unpack1("N")
135
+
136
+ data = reader.read(length)
137
+ return nil if data.nil?
138
+
139
+ data = decompress_input(data) if compressed
140
+
141
+ input_type.decode(data)
142
+ end
143
+ end
144
+
145
+ def send_framed_message(message_data, compressed = nil)
146
+ if content_type == "application/json"
147
+ if output_stream?
148
+ if @opened
149
+ stream.write(",\n")
150
+ else
151
+ stream.write("[")
152
+ @opened = true
153
+ end
154
+ end
155
+ message_data = output_type.encode_json(message_data)
156
+ stream.write(message_data)
157
+ else
158
+ message_data = output_type.encode(message_data)
159
+ should_compress = compressed.nil? ? should_compress_output?(message_data.bytesize) : compressed
160
+
161
+ if should_compress
162
+ message_data = compress_output(message_data)
163
+ compressed_flag = 1
164
+ else
165
+ compressed_flag = 0
166
+ end
167
+
168
+ message = [compressed_flag, message_data.bytesize].pack("CN") << message_data
169
+ stream.write(message)
170
+
171
+ @body_written = true
172
+ end
173
+ rescue IOError
174
+ close
175
+ end
176
+
177
+ def remote_send(response)
178
+ send_framed_message(response)
179
+ end
180
+
181
+ def deadline_exceeded?
182
+ @deadline && @deadline <= Time.now
183
+ end
184
+
185
+ def each_remote_read
186
+ return enum_for(:each_remote_read) unless block_given?
187
+
188
+ while (resp = remote_read) || !cancelled?
189
+
190
+ yield resp
191
+ end
192
+ end
193
+
194
+ def bidi_streamer?
195
+ input_stream? && output_stream?
196
+ end
197
+
198
+ def client_streamer?
199
+ input_stream? && !output_stream?
200
+ end
201
+
202
+ def server_streamer?
203
+ !input_stream? && output_stream?
204
+ end
205
+
206
+ def request_response?
207
+ !input_stream? && !output_stream?
208
+ end
209
+
210
+ def send_initial_metadata(kv_pairs)
211
+ add_headers(kv_pairs.transform_values { |v| Array(v) })
212
+ end
213
+
214
+ def send_empty
215
+ remote_send(output_type.new) unless @body_written
216
+ end
217
+
218
+ def send_status(status_code, status_details, trailing_metadata = {})
219
+ trailers = {
220
+ "grpc-status" => status_code.to_s
221
+ }
222
+
223
+ unless status_details.nil? || status_details.empty?
224
+ encoded_message = status_details.gsub(/[ #%&+,:;<=>?@\[\]^`{|}~\\"]/) do |c|
225
+ "%" + c.ord.to_s(16).upcase
226
+ end
227
+ trailers["grpc-message"] = encoded_message
228
+ end
229
+
230
+ trailing_metadata.each do |key, value|
231
+ trailers[key] = \
232
+ if key.to_s.end_with?("-bin")
233
+ Base64.strict_encode64(value.to_s)
234
+ else
235
+ value.to_s
236
+ end
237
+ end
238
+
239
+ send_trailers(trailers)
240
+ end
241
+
242
+ def send_trailers(trailers)
243
+ stream.send_trailers(trailers)
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,107 @@
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
+ puts "Handling active call"
33
+ unless (active_call.rpc_desc = @rpc_descs[active_call.method_name])
34
+ active_call.stream.write("\n")
35
+ active_call.send_status(13, "Method not found")
36
+ active_call.close
37
+ return
38
+ end
39
+
40
+ active_call.send_initial_metadata(
41
+ {
42
+ "grpc-accept-encoding" => "gzip, deflate, identity",
43
+ "content-type" => active_call.json? ? "application/json" : "application/grpc"
44
+ }
45
+ )
46
+
47
+ begin
48
+ if active_call.bidi_streamer?
49
+ handle_bidi_streaming(active_call)
50
+ elsif active_call.client_streamer?
51
+ handle_client_streaming(active_call)
52
+ elsif active_call.server_streamer?
53
+ handle_server_streaming(active_call)
54
+ elsif active_call.request_response?
55
+ handle_unary(active_call)
56
+ end
57
+ active_call.send_status(0, "Success")
58
+ rescue Google::Protobuf::ParseError => e
59
+ active_call.send_empty
60
+ active_call.send_status(3, e.message)
61
+ rescue DeadlineExceeded => e
62
+ active_call.send_empty
63
+ active_call.send_status(4, e.message)
64
+ rescue StandardError => e
65
+ active_call.send_empty
66
+ active_call.send_status(13, e.message)
67
+ end
68
+ rescue StandardError => e
69
+ Itsi.log_warn("Unhandled error in grpc_interface: #{e.message}")
70
+ ensure
71
+ active_call.close
72
+ end
73
+
74
+ private
75
+
76
+ def handle_unary(active_call)
77
+ message = active_call.remote_read
78
+ response = service.send(active_call.method_name, message, active_call)
79
+ active_call.remote_send(response)
80
+ end
81
+
82
+ def handle_client_streaming(active_call)
83
+ response = service.send(active_call.method_name, active_call.each_remote_read, active_call)
84
+ active_call.remote_send(response)
85
+ end
86
+
87
+ def handle_server_streaming(active_call)
88
+ message = active_call.remote_read
89
+ result = service.send(active_call.method_name, message, active_call) do |response|
90
+ active_call.remote_send(response)
91
+ end
92
+ if result.kind_of?(Enumerator)
93
+ result.each { |response| active_call.remote_send(response) }
94
+ end
95
+ end
96
+
97
+ def handle_bidi_streaming(active_call)
98
+ result = service.send(active_call.method_name, active_call.each_remote_read, active_call) do |response|
99
+ active_call.remote_send(response)
100
+ end
101
+ if result.kind_of?(Enumerator)
102
+ result.each { |response| active_call.remote_send(response) }
103
+ end
104
+ end
105
+ end
106
+ end
107
+ 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,27 @@
1
+ return unless defined?(::Rackup::Handler) || defined?(Rack::Handler)
2
+
3
+
4
+ module Rack
5
+ module Handler
6
+ module Itsi
7
+ def self.run(app, options = {})
8
+ host = options.fetch(:host, "127.0.0.1")
9
+ port = options.fetch(:Port, 3001)
10
+ ::Itsi::Server.start(
11
+ {
12
+ app: app,
13
+ binds: ["http://#{host}:#{port}"]
14
+ }
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ if defined?(Rackup)
22
+ ::Rackup::Handler.register("itsi", Rack::Handler::Itsi)
23
+ ::Rackup::Handler.register("Itsi", Rack::Handler::Itsi)
24
+ elsif defined?(Rack)
25
+ ::Rack::Handler.register("itsi", Rack::Handler::Itsi)
26
+ ::Rack::Handler.register("Itsi", Rack::Handler::Itsi)
27
+ end