itsi 0.1.9 → 0.1.12

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 (294) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1542 -43
  3. data/Itsi.rb +125 -0
  4. data/Rakefile +8 -4
  5. data/crates/itsi_error/src/lib.rs +9 -0
  6. data/crates/itsi_rb_helpers/Cargo.toml +1 -0
  7. data/crates/itsi_rb_helpers/src/heap_value.rs +18 -0
  8. data/crates/itsi_rb_helpers/src/lib.rs +59 -9
  9. data/crates/itsi_server/Cargo.toml +70 -28
  10. data/crates/itsi_server/src/lib.rs +80 -80
  11. data/crates/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
  12. data/{gems/server/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs → crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs} +22 -3
  13. data/crates/itsi_server/src/ruby_types/itsi_grpc_request.rs +147 -0
  14. data/crates/itsi_server/src/ruby_types/itsi_grpc_response.rs +19 -0
  15. data/crates/itsi_server/src/ruby_types/itsi_grpc_stream/mod.rs +216 -0
  16. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +282 -0
  17. data/crates/itsi_server/src/{response/itsi_response.rs → ruby_types/itsi_http_response.rs} +72 -41
  18. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
  19. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +355 -0
  20. data/crates/itsi_server/src/ruby_types/itsi_server.rs +82 -0
  21. data/crates/itsi_server/src/ruby_types/mod.rs +55 -0
  22. data/crates/itsi_server/src/server/bind.rs +29 -17
  23. data/crates/itsi_server/src/server/byte_frame.rs +32 -0
  24. data/crates/itsi_server/src/server/cache_store.rs +74 -0
  25. data/crates/itsi_server/src/server/itsi_service.rs +172 -0
  26. data/crates/itsi_server/src/server/lifecycle_event.rs +3 -0
  27. data/crates/itsi_server/src/server/listener.rs +111 -11
  28. data/crates/itsi_server/src/server/middleware_stack/middleware.rs +153 -0
  29. data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +47 -0
  30. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +58 -0
  31. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +82 -0
  32. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +321 -0
  33. data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +139 -0
  34. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +300 -0
  35. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +287 -0
  36. data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +48 -0
  37. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +127 -0
  38. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +191 -0
  39. data/crates/itsi_server/src/server/middleware_stack/middlewares/grpc_service.rs +72 -0
  40. data/crates/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +85 -0
  41. data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +195 -0
  42. data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
  43. data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +82 -0
  44. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +216 -0
  45. data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +124 -0
  46. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
  47. data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +43 -0
  48. data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +34 -0
  49. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +93 -0
  50. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +162 -0
  51. data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +158 -0
  52. data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
  53. data/crates/itsi_server/src/server/middleware_stack/mod.rs +315 -0
  54. data/crates/itsi_server/src/server/mod.rs +8 -1
  55. data/crates/itsi_server/src/server/process_worker.rs +44 -11
  56. data/crates/itsi_server/src/server/rate_limiter.rs +565 -0
  57. data/crates/itsi_server/src/server/request_job.rs +11 -0
  58. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +129 -46
  59. data/crates/itsi_server/src/server/serve_strategy/mod.rs +9 -6
  60. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +325 -167
  61. data/crates/itsi_server/src/server/signal.rs +20 -4
  62. data/crates/itsi_server/src/server/static_file_server.rs +984 -0
  63. data/crates/itsi_server/src/server/thread_worker.rs +165 -88
  64. data/crates/itsi_server/src/server/tls.rs +1 -1
  65. data/crates/itsi_server/src/server/types.rs +43 -0
  66. data/crates/itsi_server/test.md +14 -0
  67. data/crates/itsi_tracing/Cargo.toml +1 -0
  68. data/crates/itsi_tracing/src/lib.rs +216 -45
  69. data/docs/.gitignore +7 -0
  70. data/docs/.gitpod.yml +15 -0
  71. data/docs/Itsi.rb +17 -0
  72. data/docs/content/_index.md +17 -0
  73. data/docs/content/about.md +6 -0
  74. data/docs/content/docs/_index.md +18 -0
  75. data/docs/content/docs/first-page.md +9 -0
  76. data/docs/content/docs/folder/_index.md +10 -0
  77. data/docs/content/docs/folder/leaf.md +7 -0
  78. data/docs/go.mod +5 -0
  79. data/docs/go.sum +2 -0
  80. data/docs/hugo.yaml +77 -0
  81. data/examples/static_assets_example.rb +83 -0
  82. data/gems/_index.md +18 -0
  83. data/gems/scheduler/CODE_OF_CONDUCT.md +7 -0
  84. data/gems/scheduler/Cargo.lock +75 -14
  85. data/gems/scheduler/README.md +5 -0
  86. data/gems/scheduler/_index.md +7 -0
  87. data/gems/scheduler/itsi-scheduler.gemspec +4 -1
  88. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  89. data/gems/scheduler/lib/itsi/scheduler.rb +2 -2
  90. data/gems/scheduler/test/test_file_io.rb +0 -1
  91. data/gems/scheduler/test/test_itsi_scheduler.rb +1 -1
  92. data/gems/server/CHANGELOG.md +5 -0
  93. data/gems/server/CODE_OF_CONDUCT.md +7 -0
  94. data/gems/server/Cargo.lock +1543 -43
  95. data/gems/server/README.md +4 -0
  96. data/gems/server/_index.md +6 -0
  97. data/gems/server/exe/itsi +46 -57
  98. data/gems/server/itsi-server.gemspec +3 -2
  99. data/gems/server/lib/itsi/{request.rb → http_request.rb} +29 -5
  100. data/gems/server/lib/itsi/http_response.rb +39 -0
  101. data/gems/server/lib/itsi/server/Itsi.rb +119 -0
  102. data/gems/server/lib/itsi/server/config/dsl.rb +506 -0
  103. data/gems/server/lib/itsi/server/config.rb +131 -0
  104. data/gems/server/lib/itsi/server/default_app/default_app.rb +38 -0
  105. data/gems/server/lib/itsi/server/grpc_interface.rb +213 -0
  106. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +9 -6
  107. data/gems/server/lib/itsi/server/rack_interface.rb +24 -9
  108. data/gems/server/lib/itsi/server/scheduler_interface.rb +1 -1
  109. data/gems/server/lib/itsi/server/scheduler_mode.rb +4 -0
  110. data/gems/server/lib/itsi/server/signal_trap.rb +6 -1
  111. data/gems/server/lib/itsi/server/version.rb +1 -1
  112. data/gems/server/lib/itsi/server.rb +75 -60
  113. data/gems/server/lib/itsi/standard_headers.rb +86 -0
  114. data/gems/server/test/helpers/test_helper.rb +14 -12
  115. data/gems/server/test/test_itsi_server.rb +21 -2
  116. data/lib/itsi/version.rb +1 -1
  117. data/sandbox/itsi_file/Gemfile +11 -0
  118. data/sandbox/itsi_file/Gemfile.lock +69 -0
  119. data/sandbox/itsi_file/Itsi.rb +276 -0
  120. data/sandbox/itsi_file/error.html +2 -0
  121. data/sandbox/itsi_file/organisations_controller.rb +20 -0
  122. data/sandbox/itsi_file/public/assets/image.png +0 -0
  123. data/sandbox/itsi_file/public/assets/index.html +1 -0
  124. data/sandbox/itsi_sandbox_async/Gemfile +1 -1
  125. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +2 -2
  126. data/sandbox/itsi_sandbox_rack/Gemfile.lock +2 -2
  127. data/sandbox/itsi_sandbox_rack/config.ru +2 -15
  128. data/sandbox/itsi_sandbox_rails/.dockerignore +2 -5
  129. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +1 -1
  130. data/sandbox/itsi_sandbox_rails/.gitignore +2 -1
  131. data/sandbox/itsi_sandbox_rails/Dockerfile +6 -9
  132. data/sandbox/itsi_sandbox_rails/Gemfile +16 -22
  133. data/sandbox/itsi_sandbox_rails/Gemfile.lock +100 -225
  134. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +4 -0
  135. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +11 -6
  136. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +4 -0
  137. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +4 -0
  138. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +7 -8
  139. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -3
  140. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +2 -7
  141. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +3 -4
  142. data/sandbox/itsi_sandbox_rails/bin/setup +8 -5
  143. data/sandbox/itsi_sandbox_rails/config/application.rb +1 -35
  144. data/sandbox/itsi_sandbox_rails/config/cable.yml +3 -10
  145. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -1
  146. data/sandbox/itsi_sandbox_rails/config/database.yml +9 -19
  147. data/sandbox/itsi_sandbox_rails/config/environment.rb +1 -1
  148. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +21 -12
  149. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +49 -34
  150. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +19 -5
  151. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +5 -0
  152. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +1 -1
  153. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +13 -0
  154. data/sandbox/itsi_sandbox_rails/config/puma.rb +2 -9
  155. data/sandbox/itsi_sandbox_rails/config.ru +0 -1
  156. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +1 -1
  157. data/sandbox/itsi_sandbox_rails/db/schema.rb +2 -2
  158. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  159. data/sandbox/itsi_sandbox_rails/public/404.html +66 -113
  160. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +65 -113
  161. data/sandbox/itsi_sandbox_rails/public/422.html +66 -113
  162. data/sandbox/itsi_sandbox_rails/public/500.html +65 -113
  163. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  164. data/sandbox/itsi_sandbox_rails/public/icon.svg +2 -2
  165. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +13 -0
  166. data/sandbox/itsi_sandbox_roda/Gemfile.lock +3 -10
  167. data/tasks.txt +72 -12
  168. metadata +94 -139
  169. data/crates/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  170. data/crates/itsi_server/src/body_proxy/mod.rs +0 -2
  171. data/crates/itsi_server/src/request/itsi_request.rs +0 -305
  172. data/crates/itsi_server/src/request/mod.rs +0 -1
  173. data/crates/itsi_server/src/response/mod.rs +0 -1
  174. data/crates/itsi_server/src/server/itsi_server.rs +0 -294
  175. data/gems/scheduler/ext/itsi_error/Cargo.lock +0 -368
  176. data/gems/scheduler/ext/itsi_error/Cargo.toml +0 -11
  177. data/gems/scheduler/ext/itsi_error/src/from.rs +0 -68
  178. data/gems/scheduler/ext/itsi_error/src/lib.rs +0 -24
  179. data/gems/scheduler/ext/itsi_instrument_entry/Cargo.toml +0 -15
  180. data/gems/scheduler/ext/itsi_instrument_entry/src/lib.rs +0 -31
  181. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.lock +0 -355
  182. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.toml +0 -10
  183. data/gems/scheduler/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  184. data/gems/scheduler/ext/itsi_rb_helpers/src/lib.rs +0 -178
  185. data/gems/scheduler/ext/itsi_scheduler/Cargo.toml +0 -24
  186. data/gems/scheduler/ext/itsi_scheduler/extconf.rb +0 -6
  187. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  188. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  189. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  190. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  191. data/gems/scheduler/ext/itsi_scheduler/src/lib.rs +0 -38
  192. data/gems/scheduler/ext/itsi_server/Cargo.lock +0 -2956
  193. data/gems/scheduler/ext/itsi_server/Cargo.toml +0 -47
  194. data/gems/scheduler/ext/itsi_server/extconf.rb +0 -6
  195. data/gems/scheduler/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  196. data/gems/scheduler/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  197. data/gems/scheduler/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  198. data/gems/scheduler/ext/itsi_server/src/env.rs +0 -43
  199. data/gems/scheduler/ext/itsi_server/src/lib.rs +0 -112
  200. data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +0 -305
  201. data/gems/scheduler/ext/itsi_server/src/request/mod.rs +0 -1
  202. data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +0 -357
  203. data/gems/scheduler/ext/itsi_server/src/response/mod.rs +0 -1
  204. data/gems/scheduler/ext/itsi_server/src/server/bind.rs +0 -170
  205. data/gems/scheduler/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  206. data/gems/scheduler/ext/itsi_server/src/server/io_stream.rs +0 -104
  207. data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +0 -294
  208. data/gems/scheduler/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  209. data/gems/scheduler/ext/itsi_server/src/server/listener.rs +0 -318
  210. data/gems/scheduler/ext/itsi_server/src/server/mod.rs +0 -11
  211. data/gems/scheduler/ext/itsi_server/src/server/process_worker.rs +0 -196
  212. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -254
  213. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  214. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -263
  215. data/gems/scheduler/ext/itsi_server/src/server/signal.rs +0 -77
  216. data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +0 -367
  217. data/gems/scheduler/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  218. data/gems/scheduler/ext/itsi_server/src/server/tls.rs +0 -265
  219. data/gems/scheduler/ext/itsi_tracing/Cargo.lock +0 -274
  220. data/gems/scheduler/ext/itsi_tracing/Cargo.toml +0 -16
  221. data/gems/scheduler/ext/itsi_tracing/src/lib.rs +0 -58
  222. data/gems/server/ext/itsi_error/Cargo.lock +0 -368
  223. data/gems/server/ext/itsi_error/Cargo.toml +0 -11
  224. data/gems/server/ext/itsi_error/src/from.rs +0 -68
  225. data/gems/server/ext/itsi_error/src/lib.rs +0 -24
  226. data/gems/server/ext/itsi_instrument_entry/Cargo.toml +0 -15
  227. data/gems/server/ext/itsi_instrument_entry/src/lib.rs +0 -31
  228. data/gems/server/ext/itsi_rb_helpers/Cargo.lock +0 -355
  229. data/gems/server/ext/itsi_rb_helpers/Cargo.toml +0 -10
  230. data/gems/server/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  231. data/gems/server/ext/itsi_rb_helpers/src/lib.rs +0 -178
  232. data/gems/server/ext/itsi_scheduler/Cargo.toml +0 -24
  233. data/gems/server/ext/itsi_scheduler/extconf.rb +0 -6
  234. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  235. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  236. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  237. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  238. data/gems/server/ext/itsi_scheduler/src/lib.rs +0 -38
  239. data/gems/server/ext/itsi_server/Cargo.lock +0 -2956
  240. data/gems/server/ext/itsi_server/Cargo.toml +0 -47
  241. data/gems/server/ext/itsi_server/extconf.rb +0 -6
  242. data/gems/server/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  243. data/gems/server/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  244. data/gems/server/ext/itsi_server/src/env.rs +0 -43
  245. data/gems/server/ext/itsi_server/src/lib.rs +0 -112
  246. data/gems/server/ext/itsi_server/src/request/itsi_request.rs +0 -305
  247. data/gems/server/ext/itsi_server/src/request/mod.rs +0 -1
  248. data/gems/server/ext/itsi_server/src/response/itsi_response.rs +0 -357
  249. data/gems/server/ext/itsi_server/src/response/mod.rs +0 -1
  250. data/gems/server/ext/itsi_server/src/server/bind.rs +0 -170
  251. data/gems/server/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  252. data/gems/server/ext/itsi_server/src/server/io_stream.rs +0 -104
  253. data/gems/server/ext/itsi_server/src/server/itsi_server.rs +0 -294
  254. data/gems/server/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  255. data/gems/server/ext/itsi_server/src/server/listener.rs +0 -318
  256. data/gems/server/ext/itsi_server/src/server/mod.rs +0 -11
  257. data/gems/server/ext/itsi_server/src/server/process_worker.rs +0 -196
  258. data/gems/server/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -254
  259. data/gems/server/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  260. data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -263
  261. data/gems/server/ext/itsi_server/src/server/signal.rs +0 -77
  262. data/gems/server/ext/itsi_server/src/server/thread_worker.rs +0 -367
  263. data/gems/server/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  264. data/gems/server/ext/itsi_server/src/server/tls.rs +0 -265
  265. data/gems/server/ext/itsi_tracing/Cargo.lock +0 -274
  266. data/gems/server/ext/itsi_tracing/Cargo.toml +0 -16
  267. data/gems/server/ext/itsi_tracing/src/lib.rs +0 -58
  268. data/gems/server/lib/itsi/stream_io.rb +0 -38
  269. data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +0 -3
  270. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +0 -3
  271. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +0 -14
  272. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +0 -3
  273. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +0 -3
  274. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +0 -51
  275. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +0 -47
  276. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +0 -109
  277. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +0 -3
  278. data/sandbox/itsi_sandbox_rails/.kamal/secrets +0 -17
  279. data/sandbox/itsi_sandbox_rails/bin/dev +0 -2
  280. data/sandbox/itsi_sandbox_rails/bin/jobs +0 -6
  281. data/sandbox/itsi_sandbox_rails/bin/kamal +0 -27
  282. data/sandbox/itsi_sandbox_rails/bin/thrust +0 -5
  283. data/sandbox/itsi_sandbox_rails/config/cache.yml +0 -16
  284. data/sandbox/itsi_sandbox_rails/config/deploy.yml +0 -116
  285. data/sandbox/itsi_sandbox_rails/config/queue.yml +0 -18
  286. data/sandbox/itsi_sandbox_rails/config/recurring.yml +0 -10
  287. data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +0 -11
  288. data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +0 -14
  289. data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +0 -129
  290. data/sandbox/itsi_sandbox_rails/public/400.html +0 -114
  291. data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +0 -9
  292. data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +0 -7
  293. /data/{sandbox/itsi_sandbox_rails/script/.keep → crates/_index.md} +0 -0
  294. /data/gems/server/lib/itsi/{index.html → server/default_app/index.html} +0 -0
@@ -1,294 +0,0 @@
1
- use super::{
2
- bind::Bind,
3
- listener::Listener,
4
- serve_strategy::{cluster_mode::ClusterMode, single_mode::SingleMode},
5
- signal::{
6
- clear_signal_handlers, reset_signal_handlers, send_shutdown_event, SIGNAL_HANDLER_CHANNEL,
7
- },
8
- };
9
- use crate::{request::itsi_request::ItsiRequest, server::serve_strategy::ServeStrategy};
10
- use derive_more::Debug;
11
- use itsi_rb_helpers::{call_without_gvl, HeapVal};
12
- use itsi_tracing::{error, run_silently};
13
- use magnus::{
14
- block::Proc,
15
- error::Result,
16
- scan_args::{get_kwargs, scan_args, Args, KwArgs, ScanArgsKw, ScanArgsOpt, ScanArgsRequired},
17
- value::{InnerValue, Opaque, ReprValue},
18
- ArgList, RHash, Ruby, Symbol, Value,
19
- };
20
- use parking_lot::{Mutex, RwLock};
21
- use std::{cmp::max, ops::Deref, sync::Arc};
22
- use tracing::{info, instrument};
23
-
24
- static DEFAULT_BIND: &str = "http://localhost:3000";
25
-
26
- #[magnus::wrap(class = "Itsi::Server", free_immediately, size)]
27
- #[derive(Clone)]
28
- pub struct Server {
29
- pub config: Arc<ServerConfig>,
30
- }
31
-
32
- impl Deref for Server {
33
- type Target = ServerConfig;
34
-
35
- fn deref(&self) -> &Self::Target {
36
- &self.config
37
- }
38
- }
39
- type AfterFork = Mutex<Arc<Option<Box<dyn Fn() + Send + Sync>>>>;
40
-
41
- #[derive(Debug)]
42
- pub struct ServerConfig {
43
- #[debug(skip)]
44
- pub app: HeapVal,
45
- #[allow(unused)]
46
- pub workers: u8,
47
- #[allow(unused)]
48
- pub threads: u8,
49
- #[allow(unused)]
50
- pub shutdown_timeout: f64,
51
- pub script_name: String,
52
- pub(crate) binds: Mutex<Vec<Bind>>,
53
- #[debug(skip)]
54
- pub before_fork: Mutex<Option<Box<dyn FnOnce() + Send + Sync>>>,
55
- #[debug(skip)]
56
- pub after_fork: AfterFork,
57
- pub scheduler_class: Option<String>,
58
- pub stream_body: Option<bool>,
59
- pub worker_memory_limit: Option<u64>,
60
- #[debug(skip)]
61
- pub(crate) strategy: RwLock<Option<ServeStrategy>>,
62
- pub silence: bool,
63
- }
64
-
65
- #[derive(Debug)]
66
- pub enum RequestJob {
67
- ProcessRequest(ItsiRequest),
68
- Shutdown,
69
- }
70
-
71
- // Define your helper function.
72
- // Here P, A, C correspond to the types for the first tuple, second tuple, and extra parameters respectively.
73
- fn extract_args<Req, Opt, Splat>(
74
- scan_args: &Args<(), (), (), (), RHash, ()>,
75
- primaries: &[&str],
76
- rest: &[&str],
77
- ) -> Result<KwArgs<Req, Opt, Splat>>
78
- where
79
- Req: ScanArgsRequired,
80
- Opt: ScanArgsOpt,
81
- Splat: ScanArgsKw,
82
- {
83
- // Combine the primary and rest names into one Vec of Symbols.
84
- let symbols: Vec<Symbol> = primaries
85
- .iter()
86
- .chain(rest.iter())
87
- .map(|&name| Symbol::new(name))
88
- .collect();
89
-
90
- // Call the "slice" function with the combined symbols.
91
- let hash = scan_args
92
- .keywords
93
- .funcall::<_, _, RHash>("slice", symbols.into_arg_list_with(&Ruby::get().unwrap()))
94
- .unwrap();
95
-
96
- // Finally, call get_kwargs with the original name slices.
97
- get_kwargs(hash, primaries, rest)
98
- }
99
-
100
- impl Server {
101
- #[instrument(
102
- name = "Itsi",
103
- parent=None,
104
- skip(args),
105
- fields(workers = 1, threads = 1, shutdown_timeout = 5)
106
- )]
107
- pub fn new(args: &[Value]) -> Result<Self> {
108
- let scan_args: Args<(), (), (), (), RHash, ()> = scan_args(args)?;
109
-
110
- type Args1 = KwArgs<
111
- (Value,),
112
- (
113
- // Workers
114
- Option<u8>,
115
- // Threads
116
- Option<u8>,
117
- // Shutdown Timeout
118
- Option<f64>,
119
- // Script Name
120
- Option<String>,
121
- // Binds
122
- Option<Vec<String>>,
123
- // Stream Body
124
- Option<bool>,
125
- ),
126
- (),
127
- >;
128
-
129
- type Args2 = KwArgs<
130
- (),
131
- (
132
- // Before Fork
133
- Option<Proc>,
134
- // After Fork
135
- Option<Proc>,
136
- // Scheduler Class
137
- Option<String>,
138
- // Worker Memory Limit
139
- Option<u64>,
140
- // Silence
141
- Option<bool>,
142
- ),
143
- (),
144
- >;
145
-
146
- let args1: Args1 = extract_args(
147
- &scan_args,
148
- &["app"],
149
- &[
150
- "workers",
151
- "threads",
152
- "shutdown_timeout",
153
- "script_name",
154
- "binds",
155
- "stream_body",
156
- ],
157
- )?;
158
-
159
- let args2: Args2 = extract_args(
160
- &scan_args,
161
- &[],
162
- &[
163
- "before_fork",
164
- "after_fork",
165
- "scheduler_class",
166
- "worker_memory_limit",
167
- "silence",
168
- ],
169
- )?;
170
-
171
- let config = ServerConfig {
172
- app: HeapVal::from(args1.required.0),
173
- workers: max(args1.optional.0.unwrap_or(1), 1),
174
- threads: max(args1.optional.1.unwrap_or(1), 1),
175
- shutdown_timeout: args1.optional.2.unwrap_or(5.0),
176
- script_name: args1.optional.3.unwrap_or("".to_string()),
177
- binds: Mutex::new(
178
- args1
179
- .optional
180
- .4
181
- .unwrap_or_else(|| vec![DEFAULT_BIND.to_string()])
182
- .into_iter()
183
- .map(|s| s.parse())
184
- .collect::<itsi_error::Result<Vec<Bind>>>()?,
185
- ),
186
- stream_body: args1.optional.5,
187
- before_fork: Mutex::new(args2.optional.0.map(|p| {
188
- let opaque_proc = Opaque::from(p);
189
- Box::new(move || {
190
- opaque_proc
191
- .get_inner_with(&Ruby::get().unwrap())
192
- .call::<_, Value>(())
193
- .unwrap();
194
- }) as Box<dyn FnOnce() + Send + Sync>
195
- })),
196
- after_fork: Mutex::new(Arc::new(args2.optional.1.map(|p| {
197
- let opaque_proc = Opaque::from(p);
198
- Box::new(move || {
199
- opaque_proc
200
- .get_inner_with(&Ruby::get().unwrap())
201
- .call::<_, Value>(())
202
- .unwrap();
203
- }) as Box<dyn Fn() + Send + Sync>
204
- }))),
205
- scheduler_class: args2.optional.2.clone(),
206
- worker_memory_limit: args2.optional.3,
207
- silence: args2.optional.4.is_some_and(|s| s),
208
- strategy: RwLock::new(None),
209
- };
210
-
211
- if !config.silence {
212
- if let Some(scheduler_class) = args2.optional.2 {
213
- info!(scheduler_class, fiber_scheduler = true);
214
- } else {
215
- info!(fiber_scheduler = false);
216
- }
217
- }
218
-
219
- Ok(Server {
220
- config: Arc::new(config),
221
- })
222
- }
223
-
224
- #[instrument(name = "Bind", skip_all, fields(binds=format!("{:?}", self.config.binds.lock())))]
225
- pub(crate) fn build_listeners(&self) -> Result<Arc<Vec<Arc<Listener>>>> {
226
- let listeners = self
227
- .config
228
- .binds
229
- .lock()
230
- .iter()
231
- .cloned()
232
- .map(Listener::try_from)
233
- .collect::<std::result::Result<Vec<Listener>, _>>()?
234
- .into_iter()
235
- .map(Arc::new)
236
- .collect::<Vec<_>>();
237
- info!("Bound {:?} listeners", listeners.len());
238
- Ok(Arc::new(listeners))
239
- }
240
-
241
- pub(crate) fn build_strategy(self, listeners: Arc<Vec<Arc<Listener>>>) -> Result<()> {
242
- let server = Arc::new(self);
243
- let server_clone = server.clone();
244
-
245
- let strategy = if server.config.workers == 1 {
246
- ServeStrategy::Single(Arc::new(SingleMode::new(
247
- server,
248
- listeners,
249
- SIGNAL_HANDLER_CHANNEL.0.clone(),
250
- )?))
251
- } else {
252
- ServeStrategy::Cluster(Arc::new(ClusterMode::new(
253
- server,
254
- listeners,
255
- SIGNAL_HANDLER_CHANNEL.0.clone(),
256
- )))
257
- };
258
-
259
- *server_clone.strategy.write() = Some(strategy);
260
- Ok(())
261
- }
262
-
263
- pub fn stop(&self) -> Result<()> {
264
- send_shutdown_event();
265
- Ok(())
266
- }
267
-
268
- pub fn start(&self) -> Result<()> {
269
- if self.silence {
270
- run_silently(|| self.build_and_run_strategy())
271
- } else {
272
- self.build_and_run_strategy()
273
- }
274
- }
275
-
276
- fn build_and_run_strategy(&self) -> Result<()> {
277
- reset_signal_handlers();
278
- let rself = self.clone();
279
- let listeners = self.build_listeners()?;
280
- let listeners_clone = listeners.clone();
281
- call_without_gvl(move || -> Result<()> {
282
- rself.clone().build_strategy(listeners_clone)?;
283
- if let Err(e) = rself.clone().strategy.read().as_ref().unwrap().run() {
284
- error!("Error running server: {}", e);
285
- rself.strategy.read().as_ref().unwrap().stop()?;
286
- }
287
- Ok(())
288
- })?;
289
- clear_signal_handlers();
290
- self.strategy.write().take();
291
- info!("Server stopped");
292
- Ok(())
293
- }
294
- }
@@ -1,9 +0,0 @@
1
- #[derive(Debug, Clone)]
2
- pub enum LifecycleEvent {
3
- Start,
4
- Shutdown,
5
- Restart,
6
- IncreaseWorkers,
7
- DecreaseWorkers,
8
- ForceShutdown,
9
- }
@@ -1,318 +0,0 @@
1
- use super::bind::{Bind, BindAddress};
2
- use super::bind_protocol::BindProtocol;
3
- use super::io_stream::IoStream;
4
- use super::serve_strategy::single_mode::RunningPhase;
5
- use super::tls::ItsiTlsAcceptor;
6
- use itsi_error::{ItsiError, Result};
7
- use itsi_tracing::info;
8
- use socket2::{Domain, Protocol, Socket, Type};
9
- use std::net::{IpAddr, SocketAddr, TcpListener};
10
- use std::sync::Arc;
11
- use std::{os::unix::net::UnixListener, path::PathBuf};
12
- use tokio::net::TcpListener as TokioTcpListener;
13
- use tokio::net::UnixListener as TokioUnixListener;
14
- use tokio::net::{unix, TcpStream, UnixStream};
15
- use tokio::sync::watch::Receiver;
16
- use tokio_rustls::TlsAcceptor;
17
- use tokio_stream::StreamExt;
18
- use tracing::error;
19
-
20
- pub(crate) enum Listener {
21
- Tcp(TcpListener),
22
- TcpTls((TcpListener, ItsiTlsAcceptor)),
23
- Unix(UnixListener),
24
- UnixTls((UnixListener, ItsiTlsAcceptor)),
25
- }
26
-
27
- pub(crate) enum TokioListener {
28
- Tcp(TokioTcpListener),
29
- TcpTls(TokioTcpListener, ItsiTlsAcceptor),
30
- Unix(TokioUnixListener),
31
- UnixTls(TokioUnixListener, ItsiTlsAcceptor),
32
- }
33
-
34
- #[derive(Debug, Clone)]
35
- pub struct ListenerInfo {
36
- pub host: String,
37
- pub port: u16,
38
- pub scheme: String,
39
- }
40
-
41
- impl TokioListener {
42
- pub fn listener_info(&self) -> ListenerInfo {
43
- match self {
44
- TokioListener::Tcp(listener) => ListenerInfo {
45
- host: listener
46
- .local_addr()
47
- .unwrap()
48
- .ip()
49
- .to_canonical()
50
- .to_string(),
51
- port: listener.local_addr().unwrap().port(),
52
- scheme: "http".to_string(),
53
- },
54
- TokioListener::TcpTls(listener, _) => ListenerInfo {
55
- host: listener
56
- .local_addr()
57
- .unwrap()
58
- .ip()
59
- .to_canonical()
60
- .to_string(),
61
- port: listener.local_addr().unwrap().port(),
62
- scheme: "https".to_string(),
63
- },
64
- TokioListener::Unix(listener) => ListenerInfo {
65
- host: listener
66
- .local_addr()
67
- .unwrap()
68
- .as_pathname()
69
- .unwrap()
70
- .to_str()
71
- .unwrap()
72
- .to_owned(),
73
- port: 0,
74
- scheme: "unix".to_string(),
75
- },
76
- TokioListener::UnixTls(listener, _) => ListenerInfo {
77
- host: listener
78
- .local_addr()
79
- .unwrap()
80
- .as_pathname()
81
- .unwrap()
82
- .to_str()
83
- .unwrap()
84
- .to_owned(),
85
- port: 0,
86
- scheme: "ssl".to_string(),
87
- },
88
- }
89
- }
90
-
91
- pub(crate) async fn accept(&self) -> Result<IoStream> {
92
- match self {
93
- TokioListener::Tcp(listener) => TokioListener::accept_tcp(listener).await,
94
- TokioListener::TcpTls(listener, acceptor) => {
95
- TokioListener::accept_tls(listener, acceptor).await
96
- }
97
- TokioListener::Unix(listener) => TokioListener::accept_unix(listener).await,
98
- TokioListener::UnixTls(listener, acceptor) => {
99
- TokioListener::accept_unix_tls(listener, acceptor).await
100
- }
101
- }
102
- }
103
-
104
- async fn accept_tcp(listener: &TokioTcpListener) -> Result<IoStream> {
105
- let tcp_stream = listener.accept().await?;
106
- Self::to_tokio_io(Stream::TcpStream(tcp_stream), None).await
107
- }
108
-
109
- pub async fn spawn_state_task(&self, mut shutdown_receiver: Receiver<RunningPhase>) {
110
- if let TokioListener::TcpTls(
111
- _,
112
- ItsiTlsAcceptor::Automatic(_acme_acceptor, state, _server_config),
113
- ) = self
114
- {
115
- let mut state = state.lock().await;
116
- loop {
117
- tokio::select! {
118
- stream_event = StreamExt::next(&mut *state) => {
119
- match stream_event {
120
- Some(event) => info!("ACME Event: {:?}", event),
121
- None => error!("Received no acme event"),
122
- }
123
- },
124
- _ = shutdown_receiver.changed() => {
125
- break;
126
- }
127
- }
128
- }
129
- }
130
- }
131
-
132
- async fn accept_tls(
133
- listener: &TokioTcpListener,
134
- acceptor: &ItsiTlsAcceptor,
135
- ) -> Result<IoStream> {
136
- let tcp_stream = listener.accept().await?;
137
- match acceptor {
138
- ItsiTlsAcceptor::Manual(tls_acceptor) => {
139
- Self::to_tokio_io(Stream::TcpStream(tcp_stream), Some(tls_acceptor)).await
140
- }
141
- ItsiTlsAcceptor::Automatic(acme_acceptor, _, rustls_config) => {
142
- let accept_future = acme_acceptor.accept(tcp_stream.0);
143
- match accept_future.await {
144
- Ok(None) => Err(ItsiError::Pass()),
145
- Ok(Some(start_handshake)) => {
146
- let tls_stream = start_handshake.into_stream(rustls_config.clone()).await?;
147
- Ok(IoStream::TcpTls {
148
- stream: tls_stream,
149
- addr: SockAddr::Tcp(Arc::new(tcp_stream.1)),
150
- })
151
- }
152
- Err(error) => {
153
- error!(error = format!("{:?}", error));
154
- Err(ItsiError::Pass())
155
- }
156
- }
157
- }
158
- }
159
- }
160
-
161
- async fn accept_unix(listener: &TokioUnixListener) -> Result<IoStream> {
162
- let unix_stream = listener.accept().await?;
163
- Self::to_tokio_io(Stream::UnixStream(unix_stream), None).await
164
- }
165
-
166
- async fn accept_unix_tls(
167
- listener: &TokioUnixListener,
168
- acceptor: &ItsiTlsAcceptor,
169
- ) -> Result<IoStream> {
170
- let unix_stream = listener.accept().await?;
171
- match acceptor {
172
- ItsiTlsAcceptor::Manual(tls_acceptor) => {
173
- Self::to_tokio_io(Stream::UnixStream(unix_stream), Some(tls_acceptor)).await
174
- }
175
- ItsiTlsAcceptor::Automatic(_, _, _) => {
176
- error!("Automatic TLS not supported on Unix sockets");
177
- Err(ItsiError::UnsupportedProtocol(
178
- "Automatic TLS on Unix Sockets".to_owned(),
179
- ))
180
- }
181
- }
182
- }
183
-
184
- async fn to_tokio_io(
185
- input_stream: Stream,
186
- tls_acceptor: Option<&TlsAcceptor>,
187
- ) -> Result<IoStream> {
188
- match tls_acceptor {
189
- Some(acceptor) => match input_stream {
190
- Stream::TcpStream((tcp_stream, socket_address)) => {
191
- match acceptor.accept(tcp_stream).await {
192
- Ok(tls_stream) => Ok(IoStream::TcpTls {
193
- stream: tls_stream,
194
- addr: SockAddr::Tcp(Arc::new(socket_address)),
195
- }),
196
- Err(err) => Err(err.into()),
197
- }
198
- }
199
- Stream::UnixStream((unix_stream, socket_address)) => {
200
- match acceptor.accept(unix_stream).await {
201
- Ok(tls_stream) => Ok(IoStream::UnixTls {
202
- stream: tls_stream,
203
- addr: SockAddr::Unix(Arc::new(socket_address)),
204
- }),
205
- Err(err) => Err(err.into()),
206
- }
207
- }
208
- },
209
- None => match input_stream {
210
- Stream::TcpStream((tcp_stream, socket_address)) => Ok(IoStream::Tcp {
211
- stream: tcp_stream,
212
- addr: SockAddr::Tcp(Arc::new(socket_address)),
213
- }),
214
- Stream::UnixStream((unix_stream, socket_address)) => Ok(IoStream::Unix {
215
- stream: unix_stream,
216
- addr: SockAddr::Unix(Arc::new(socket_address)),
217
- }),
218
- },
219
- }
220
- }
221
- }
222
-
223
- enum Stream {
224
- TcpStream((TcpStream, SocketAddr)),
225
- UnixStream((UnixStream, unix::SocketAddr)),
226
- }
227
-
228
- #[derive(Clone, Debug)]
229
- pub enum SockAddr {
230
- Tcp(Arc<SocketAddr>),
231
- Unix(Arc<unix::SocketAddr>),
232
- }
233
- impl std::fmt::Display for SockAddr {
234
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235
- match self {
236
- SockAddr::Tcp(socket_addr) => write!(f, "{}", socket_addr.ip().to_canonical()),
237
- SockAddr::Unix(socket_addr) => match socket_addr.as_pathname() {
238
- Some(path) => write!(f, "{:?}", path),
239
- None => write!(f, ""),
240
- },
241
- }
242
- }
243
- }
244
-
245
- impl Listener {
246
- pub fn to_tokio_listener(&self) -> TokioListener {
247
- match self {
248
- Listener::Tcp(listener) => TokioListener::Tcp(
249
- TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap()).unwrap(),
250
- ),
251
- Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls(
252
- TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap()).unwrap(),
253
- acceptor.clone(),
254
- ),
255
- Listener::Unix(listener) => TokioListener::Unix(
256
- TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap()).unwrap(),
257
- ),
258
- Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls(
259
- TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap()).unwrap(),
260
- acceptor.clone(),
261
- ),
262
- }
263
- }
264
- }
265
-
266
- impl TryFrom<Bind> for Listener {
267
- type Error = itsi_error::ItsiError;
268
-
269
- fn try_from(bind: Bind) -> std::result::Result<Self, Self::Error> {
270
- let bound = match bind.address {
271
- BindAddress::Ip(addr) => match bind.protocol {
272
- BindProtocol::Http => Listener::Tcp(connect_tcp_socket(addr, bind.port.unwrap())?),
273
- BindProtocol::Https => {
274
- let tcp_listener = connect_tcp_socket(addr, bind.port.unwrap())?;
275
- Listener::TcpTls((tcp_listener, bind.tls_config.unwrap()))
276
- }
277
- _ => unreachable!(),
278
- },
279
- BindAddress::UnixSocket(path) => match bind.tls_config {
280
- Some(tls_config) => Listener::UnixTls((connect_unix_socket(&path)?, tls_config)),
281
- None => Listener::Unix(connect_unix_socket(&path)?),
282
- },
283
- };
284
- Ok(bound)
285
- }
286
- }
287
-
288
- fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
289
- let domain = match addr {
290
- IpAddr::V4(_) => Domain::IPV4,
291
- IpAddr::V6(_) => Domain::IPV6,
292
- };
293
- let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
294
- let socket_address: SocketAddr = SocketAddr::new(addr, port);
295
- socket.set_reuse_port(true).ok();
296
- socket.set_reuse_address(true).ok();
297
- socket.set_nonblocking(true).ok();
298
- socket.set_nodelay(true).ok();
299
- socket.set_recv_buffer_size(262_144).ok();
300
- info!("Binding to {:?}", socket_address);
301
- socket.bind(&socket_address.into())?;
302
- socket.listen(1024)?;
303
- Ok(socket.into())
304
- }
305
-
306
- fn connect_unix_socket(path: &PathBuf) -> Result<UnixListener> {
307
- let _ = std::fs::remove_file(path);
308
- let socket = Socket::new(Domain::UNIX, Type::STREAM, None)?;
309
- socket.set_nonblocking(true).ok();
310
-
311
- let socket_address = socket2::SockAddr::unix(path)?;
312
-
313
- info!("Binding to {:?}", path);
314
- socket.bind(&socket_address)?;
315
- socket.listen(1024)?;
316
-
317
- Ok(socket.into())
318
- }
@@ -1,11 +0,0 @@
1
- pub mod bind;
2
- pub mod bind_protocol;
3
- pub mod io_stream;
4
- pub mod itsi_server;
5
- pub mod lifecycle_event;
6
- pub mod listener;
7
- pub mod process_worker;
8
- pub mod serve_strategy;
9
- pub mod signal;
10
- pub mod thread_worker;
11
- pub mod tls;