itsi 0.1.11 → 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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1535 -45
  3. data/{sandbox/itsi_itsi_file/Itsi.rb → Itsi.rb} +19 -13
  4. data/Rakefile +8 -7
  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 +34 -7
  9. data/crates/itsi_server/Cargo.toml +69 -30
  10. data/crates/itsi_server/src/lib.rs +79 -147
  11. data/crates/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
  12. data/crates/itsi_server/src/{body_proxy/itsi_body_proxy.rs → 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/{gems/server/ext/itsi_server/src/request/itsi_request.rs → crates/itsi_server/src/ruby_types/itsi_http_request.rs} +101 -117
  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 +13 -5
  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 +102 -2
  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 +38 -12
  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 +119 -42
  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 +256 -111
  61. data/crates/itsi_server/src/server/signal.rs +19 -0
  62. data/crates/itsi_server/src/server/static_file_server.rs +984 -0
  63. data/crates/itsi_server/src/server/thread_worker.rs +139 -94
  64. data/crates/itsi_server/src/server/types.rs +43 -0
  65. data/crates/itsi_server/test.md +14 -0
  66. data/crates/itsi_tracing/Cargo.toml +1 -0
  67. data/crates/itsi_tracing/src/lib.rs +216 -45
  68. data/docs/.gitignore +7 -0
  69. data/docs/.gitpod.yml +15 -0
  70. data/docs/Itsi.rb +17 -0
  71. data/docs/content/_index.md +17 -0
  72. data/docs/content/about.md +6 -0
  73. data/docs/content/docs/_index.md +18 -0
  74. data/docs/content/docs/first-page.md +9 -0
  75. data/docs/content/docs/folder/_index.md +10 -0
  76. data/docs/content/docs/folder/leaf.md +7 -0
  77. data/docs/go.mod +5 -0
  78. data/docs/go.sum +2 -0
  79. data/docs/hugo.yaml +77 -0
  80. data/examples/static_assets_example.rb +83 -0
  81. data/gems/_index.md +18 -0
  82. data/gems/scheduler/CODE_OF_CONDUCT.md +7 -0
  83. data/gems/scheduler/Cargo.lock +75 -14
  84. data/gems/scheduler/README.md +5 -0
  85. data/gems/scheduler/_index.md +7 -0
  86. data/gems/scheduler/itsi-scheduler.gemspec +4 -1
  87. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  88. data/gems/scheduler/lib/itsi/scheduler.rb +2 -2
  89. data/gems/scheduler/test/test_file_io.rb +0 -1
  90. data/gems/scheduler/test/test_itsi_scheduler.rb +1 -1
  91. data/gems/server/CHANGELOG.md +5 -0
  92. data/gems/server/CODE_OF_CONDUCT.md +7 -0
  93. data/gems/server/Cargo.lock +1536 -45
  94. data/gems/server/README.md +4 -0
  95. data/gems/server/_index.md +6 -0
  96. data/gems/server/exe/itsi +33 -74
  97. data/gems/server/itsi-server.gemspec +3 -2
  98. data/gems/server/lib/itsi/{request.rb → http_request.rb} +29 -5
  99. data/gems/server/lib/itsi/http_response.rb +39 -0
  100. data/gems/server/lib/itsi/server/Itsi.rb +11 -19
  101. data/gems/server/lib/itsi/server/config/dsl.rb +506 -0
  102. data/gems/server/lib/itsi/server/config.rb +103 -8
  103. data/gems/server/lib/itsi/server/default_app/default_app.rb +38 -0
  104. data/gems/server/lib/itsi/server/grpc_interface.rb +213 -0
  105. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +8 -17
  106. data/gems/server/lib/itsi/server/rack_interface.rb +23 -4
  107. data/gems/server/lib/itsi/server/scheduler_interface.rb +1 -1
  108. data/gems/server/lib/itsi/server/scheduler_mode.rb +4 -0
  109. data/gems/server/lib/itsi/server/signal_trap.rb +7 -1
  110. data/gems/server/lib/itsi/server/version.rb +1 -1
  111. data/gems/server/lib/itsi/server.rb +74 -63
  112. data/gems/server/lib/itsi/standard_headers.rb +86 -0
  113. data/gems/server/test/helpers/test_helper.rb +12 -12
  114. data/gems/server/test/test_itsi_server.rb +2 -2
  115. data/lib/itsi/version.rb +1 -1
  116. data/sandbox/itsi_file/Gemfile +11 -0
  117. data/sandbox/itsi_file/Gemfile.lock +69 -0
  118. data/sandbox/itsi_file/Itsi.rb +276 -0
  119. data/sandbox/itsi_file/error.html +2 -0
  120. data/sandbox/itsi_file/organisations_controller.rb +20 -0
  121. data/sandbox/itsi_file/public/assets/image.png +0 -0
  122. data/sandbox/itsi_file/public/assets/index.html +1 -0
  123. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +2 -2
  124. data/sandbox/itsi_sandbox_rack/Gemfile.lock +2 -2
  125. data/sandbox/itsi_sandbox_rack/config.ru +2 -15
  126. data/sandbox/itsi_sandbox_rails/.dockerignore +2 -5
  127. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +1 -1
  128. data/sandbox/itsi_sandbox_rails/.gitignore +2 -1
  129. data/sandbox/itsi_sandbox_rails/Dockerfile +6 -9
  130. data/sandbox/itsi_sandbox_rails/Gemfile +16 -22
  131. data/sandbox/itsi_sandbox_rails/Gemfile.lock +100 -225
  132. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +4 -0
  133. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +11 -6
  134. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +4 -0
  135. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +4 -0
  136. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +7 -8
  137. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -3
  138. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +2 -7
  139. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +3 -4
  140. data/sandbox/itsi_sandbox_rails/bin/setup +8 -5
  141. data/sandbox/itsi_sandbox_rails/config/application.rb +1 -35
  142. data/sandbox/itsi_sandbox_rails/config/cable.yml +3 -10
  143. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -1
  144. data/sandbox/itsi_sandbox_rails/config/database.yml +9 -19
  145. data/sandbox/itsi_sandbox_rails/config/environment.rb +1 -1
  146. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +21 -12
  147. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +49 -34
  148. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +19 -5
  149. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +5 -0
  150. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +1 -1
  151. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +13 -0
  152. data/sandbox/itsi_sandbox_rails/config/puma.rb +2 -9
  153. data/sandbox/itsi_sandbox_rails/config.ru +0 -1
  154. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +1 -1
  155. data/sandbox/itsi_sandbox_rails/db/schema.rb +2 -2
  156. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  157. data/sandbox/itsi_sandbox_rails/public/404.html +66 -113
  158. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +65 -113
  159. data/sandbox/itsi_sandbox_rails/public/422.html +66 -113
  160. data/sandbox/itsi_sandbox_rails/public/500.html +65 -113
  161. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  162. data/sandbox/itsi_sandbox_rails/public/icon.svg +2 -2
  163. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +13 -0
  164. data/sandbox/itsi_sandbox_roda/Gemfile.lock +3 -10
  165. data/tasks.txt +72 -35
  166. metadata +89 -139
  167. data/crates/itsi_server/src/body_proxy/mod.rs +0 -2
  168. data/crates/itsi_server/src/request/itsi_request.rs +0 -298
  169. data/crates/itsi_server/src/request/mod.rs +0 -1
  170. data/crates/itsi_server/src/response/mod.rs +0 -1
  171. data/crates/itsi_server/src/server/itsi_server.rs +0 -288
  172. data/gems/scheduler/ext/itsi_error/Cargo.lock +0 -368
  173. data/gems/scheduler/ext/itsi_error/Cargo.toml +0 -11
  174. data/gems/scheduler/ext/itsi_error/src/from.rs +0 -68
  175. data/gems/scheduler/ext/itsi_error/src/lib.rs +0 -24
  176. data/gems/scheduler/ext/itsi_instrument_entry/Cargo.toml +0 -15
  177. data/gems/scheduler/ext/itsi_instrument_entry/src/lib.rs +0 -31
  178. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.lock +0 -355
  179. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.toml +0 -10
  180. data/gems/scheduler/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  181. data/gems/scheduler/ext/itsi_rb_helpers/src/lib.rs +0 -201
  182. data/gems/scheduler/ext/itsi_scheduler/Cargo.toml +0 -24
  183. data/gems/scheduler/ext/itsi_scheduler/extconf.rb +0 -6
  184. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  185. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  186. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  187. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  188. data/gems/scheduler/ext/itsi_scheduler/src/lib.rs +0 -38
  189. data/gems/scheduler/ext/itsi_server/Cargo.lock +0 -2956
  190. data/gems/scheduler/ext/itsi_server/Cargo.toml +0 -50
  191. data/gems/scheduler/ext/itsi_server/extconf.rb +0 -6
  192. data/gems/scheduler/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  193. data/gems/scheduler/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  194. data/gems/scheduler/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  195. data/gems/scheduler/ext/itsi_server/src/env.rs +0 -43
  196. data/gems/scheduler/ext/itsi_server/src/lib.rs +0 -180
  197. data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +0 -298
  198. data/gems/scheduler/ext/itsi_server/src/request/mod.rs +0 -1
  199. data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +0 -357
  200. data/gems/scheduler/ext/itsi_server/src/response/mod.rs +0 -1
  201. data/gems/scheduler/ext/itsi_server/src/server/bind.rs +0 -174
  202. data/gems/scheduler/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  203. data/gems/scheduler/ext/itsi_server/src/server/io_stream.rs +0 -104
  204. data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +0 -288
  205. data/gems/scheduler/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  206. data/gems/scheduler/ext/itsi_server/src/server/listener.rs +0 -318
  207. data/gems/scheduler/ext/itsi_server/src/server/mod.rs +0 -11
  208. data/gems/scheduler/ext/itsi_server/src/server/process_worker.rs +0 -203
  209. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
  210. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  211. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
  212. data/gems/scheduler/ext/itsi_server/src/server/signal.rs +0 -74
  213. data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +0 -399
  214. data/gems/scheduler/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  215. data/gems/scheduler/ext/itsi_server/src/server/tls.rs +0 -265
  216. data/gems/scheduler/ext/itsi_tracing/Cargo.lock +0 -274
  217. data/gems/scheduler/ext/itsi_tracing/Cargo.toml +0 -16
  218. data/gems/scheduler/ext/itsi_tracing/src/lib.rs +0 -58
  219. data/gems/server/ext/itsi_error/Cargo.lock +0 -368
  220. data/gems/server/ext/itsi_error/Cargo.toml +0 -11
  221. data/gems/server/ext/itsi_error/src/from.rs +0 -68
  222. data/gems/server/ext/itsi_error/src/lib.rs +0 -24
  223. data/gems/server/ext/itsi_instrument_entry/Cargo.toml +0 -15
  224. data/gems/server/ext/itsi_instrument_entry/src/lib.rs +0 -31
  225. data/gems/server/ext/itsi_rb_helpers/Cargo.lock +0 -355
  226. data/gems/server/ext/itsi_rb_helpers/Cargo.toml +0 -10
  227. data/gems/server/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  228. data/gems/server/ext/itsi_rb_helpers/src/lib.rs +0 -201
  229. data/gems/server/ext/itsi_scheduler/Cargo.toml +0 -24
  230. data/gems/server/ext/itsi_scheduler/extconf.rb +0 -6
  231. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  232. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  233. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  234. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  235. data/gems/server/ext/itsi_scheduler/src/lib.rs +0 -38
  236. data/gems/server/ext/itsi_server/Cargo.lock +0 -2956
  237. data/gems/server/ext/itsi_server/Cargo.toml +0 -50
  238. data/gems/server/ext/itsi_server/extconf.rb +0 -6
  239. data/gems/server/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  240. data/gems/server/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  241. data/gems/server/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  242. data/gems/server/ext/itsi_server/src/env.rs +0 -43
  243. data/gems/server/ext/itsi_server/src/lib.rs +0 -180
  244. data/gems/server/ext/itsi_server/src/request/mod.rs +0 -1
  245. data/gems/server/ext/itsi_server/src/response/itsi_response.rs +0 -357
  246. data/gems/server/ext/itsi_server/src/response/mod.rs +0 -1
  247. data/gems/server/ext/itsi_server/src/server/bind.rs +0 -174
  248. data/gems/server/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  249. data/gems/server/ext/itsi_server/src/server/io_stream.rs +0 -104
  250. data/gems/server/ext/itsi_server/src/server/itsi_server.rs +0 -288
  251. data/gems/server/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  252. data/gems/server/ext/itsi_server/src/server/listener.rs +0 -318
  253. data/gems/server/ext/itsi_server/src/server/mod.rs +0 -11
  254. data/gems/server/ext/itsi_server/src/server/process_worker.rs +0 -203
  255. data/gems/server/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
  256. data/gems/server/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  257. data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
  258. data/gems/server/ext/itsi_server/src/server/signal.rs +0 -74
  259. data/gems/server/ext/itsi_server/src/server/thread_worker.rs +0 -399
  260. data/gems/server/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  261. data/gems/server/ext/itsi_server/src/server/tls.rs +0 -265
  262. data/gems/server/ext/itsi_tracing/Cargo.lock +0 -274
  263. data/gems/server/ext/itsi_tracing/Cargo.toml +0 -16
  264. data/gems/server/ext/itsi_tracing/src/lib.rs +0 -58
  265. data/gems/server/lib/itsi/server/options_dsl.rb +0 -401
  266. data/gems/server/lib/itsi/stream_io.rb +0 -38
  267. data/location_dsl.rb +0 -381
  268. data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +0 -3
  269. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +0 -3
  270. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +0 -14
  271. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +0 -3
  272. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +0 -3
  273. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +0 -51
  274. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +0 -47
  275. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +0 -109
  276. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +0 -3
  277. data/sandbox/itsi_sandbox_rails/.kamal/secrets +0 -17
  278. data/sandbox/itsi_sandbox_rails/bin/dev +0 -2
  279. data/sandbox/itsi_sandbox_rails/bin/jobs +0 -6
  280. data/sandbox/itsi_sandbox_rails/bin/kamal +0 -27
  281. data/sandbox/itsi_sandbox_rails/bin/thrust +0 -5
  282. data/sandbox/itsi_sandbox_rails/config/cache.yml +0 -16
  283. data/sandbox/itsi_sandbox_rails/config/deploy.yml +0 -116
  284. data/sandbox/itsi_sandbox_rails/config/queue.yml +0 -18
  285. data/sandbox/itsi_sandbox_rails/config/recurring.yml +0 -10
  286. data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +0 -11
  287. data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +0 -14
  288. data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +0 -129
  289. data/sandbox/itsi_sandbox_rails/public/400.html +0 -114
  290. data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +0 -9
  291. data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +0 -7
  292. /data/{sandbox/itsi_sandbox_rails/script/.keep → crates/_index.md} +0 -0
  293. /data/gems/server/lib/itsi/{index.html → server/default_app/index.html} +0 -0
@@ -1,288 +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, HeapValue};
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::ReprValue,
18
- ArgList, RArray, RHash, Ruby, Symbol, Value,
19
- };
20
- use parking_lot::{Mutex, RwLock};
21
- use std::{cmp::max, collections::HashMap, 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
-
40
- #[derive(Debug)]
41
- pub struct ServerConfig {
42
- #[debug(skip)]
43
- pub app: HeapVal,
44
- #[allow(unused)]
45
- pub workers: u8,
46
- #[allow(unused)]
47
- pub threads: u8,
48
- #[allow(unused)]
49
- pub shutdown_timeout: f64,
50
- pub script_name: String,
51
- pub(crate) binds: Mutex<Vec<Bind>>,
52
- #[debug(skip)]
53
- pub hooks: HashMap<String, HeapValue<Proc>>,
54
- pub scheduler_class: Option<String>,
55
- pub stream_body: Option<bool>,
56
- pub worker_memory_limit: Option<u64>,
57
- #[debug(skip)]
58
- pub(crate) strategy: RwLock<Option<ServeStrategy>>,
59
- pub silence: bool,
60
- pub oob_gc_responses_threshold: Option<u64>,
61
- }
62
-
63
- #[derive(Debug)]
64
- pub enum RequestJob {
65
- ProcessRequest(ItsiRequest),
66
- Shutdown,
67
- }
68
-
69
- fn extract_args<Req, Opt, Splat>(
70
- scan_args: &Args<(), (), (), (), RHash, ()>,
71
- primaries: &[&str],
72
- rest: &[&str],
73
- ) -> Result<KwArgs<Req, Opt, Splat>>
74
- where
75
- Req: ScanArgsRequired,
76
- Opt: ScanArgsOpt,
77
- Splat: ScanArgsKw,
78
- {
79
- let symbols: Vec<Symbol> = primaries
80
- .iter()
81
- .chain(rest.iter())
82
- .map(|&name| Symbol::new(name))
83
- .collect();
84
-
85
- let hash = scan_args
86
- .keywords
87
- .funcall::<_, _, RHash>("slice", symbols.into_arg_list_with(&Ruby::get().unwrap()))
88
- .unwrap();
89
-
90
- get_kwargs(hash, primaries, rest)
91
- }
92
-
93
- impl Server {
94
- #[instrument(
95
- name = "Itsi",
96
- parent=None,
97
- skip(args),
98
- fields(workers = 1, threads = 1, shutdown_timeout = 5)
99
- )]
100
- pub fn new(args: &[Value]) -> Result<Self> {
101
- let scan_args: Args<(), (), (), (), RHash, ()> = scan_args(args)?;
102
-
103
- type Args1 = KwArgs<
104
- (Value,),
105
- (
106
- // Workers
107
- Option<u8>,
108
- // Threads
109
- Option<u8>,
110
- // Shutdown Timeout
111
- Option<f64>,
112
- // Script Name
113
- Option<String>,
114
- // Binds
115
- Option<Vec<String>>,
116
- // Stream Body
117
- Option<bool>,
118
- ),
119
- (),
120
- >;
121
-
122
- type Args2 = KwArgs<
123
- (),
124
- (
125
- // Hooks
126
- Option<RHash>,
127
- // Scheduler Class
128
- Option<String>,
129
- // Worker Memory Limit
130
- Option<u64>,
131
- // Out-of-band GC Responses Threshold
132
- Option<u64>,
133
- // Silence
134
- Option<bool>,
135
- ),
136
- (),
137
- >;
138
-
139
- let args1: Args1 = extract_args(
140
- &scan_args,
141
- &["app"],
142
- &[
143
- "workers",
144
- "threads",
145
- "shutdown_timeout",
146
- "script_name",
147
- "binds",
148
- "stream_body",
149
- ],
150
- )?;
151
-
152
- let args2: Args2 = extract_args(
153
- &scan_args,
154
- &[],
155
- &[
156
- "hooks",
157
- "scheduler_class",
158
- "worker_memory_limit",
159
- "oob_gc_responses_threshold",
160
- "silence",
161
- ],
162
- )?;
163
-
164
- let hooks = args2
165
- .optional
166
- .0
167
- .map(|rhash| -> Result<HashMap<String, HeapValue<Proc>>> {
168
- let mut hook_map: HashMap<String, HeapValue<Proc>> = HashMap::new();
169
- for pair in rhash.enumeratorize::<_, ()>("each", ()) {
170
- if let Some(pair_value) = RArray::from_value(pair?) {
171
- if let (Ok(key), Ok(value)) =
172
- (pair_value.entry::<Value>(0), pair_value.entry::<Proc>(1))
173
- {
174
- hook_map.insert(key.to_string(), HeapValue::from(value));
175
- }
176
- }
177
- }
178
- Ok(hook_map)
179
- })
180
- .transpose()?
181
- .unwrap_or_default();
182
-
183
- let config = ServerConfig {
184
- app: HeapVal::from(args1.required.0),
185
- workers: max(args1.optional.0.unwrap_or(1), 1),
186
- threads: max(args1.optional.1.unwrap_or(1), 1),
187
- shutdown_timeout: args1.optional.2.unwrap_or(5.0),
188
- script_name: args1.optional.3.unwrap_or("".to_string()),
189
- binds: Mutex::new(
190
- args1
191
- .optional
192
- .4
193
- .unwrap_or_else(|| vec![DEFAULT_BIND.to_string()])
194
- .into_iter()
195
- .map(|s| s.parse())
196
- .collect::<itsi_error::Result<Vec<Bind>>>()?,
197
- ),
198
- stream_body: args1.optional.5,
199
- hooks,
200
- scheduler_class: args2.optional.1.clone(),
201
- worker_memory_limit: args2.optional.2,
202
- strategy: RwLock::new(None),
203
- oob_gc_responses_threshold: args2.optional.3,
204
- silence: args2.optional.4.is_some_and(|s| s),
205
- };
206
-
207
- if !config.silence {
208
- if let Some(scheduler_class) = args2.optional.1 {
209
- info!(scheduler_class, fiber_scheduler = true);
210
- } else {
211
- info!(fiber_scheduler = false);
212
- }
213
- }
214
-
215
- Ok(Server {
216
- config: Arc::new(config),
217
- })
218
- }
219
-
220
- #[instrument(name = "Bind", skip_all, fields(binds=format!("{:?}", self.config.binds.lock())))]
221
- pub(crate) fn build_listeners(&self) -> Result<Vec<Listener>> {
222
- let listeners = self
223
- .config
224
- .binds
225
- .lock()
226
- .iter()
227
- .cloned()
228
- .map(Listener::try_from)
229
- .collect::<std::result::Result<Vec<Listener>, _>>()?
230
- .into_iter()
231
- .collect::<Vec<_>>();
232
- info!("Bound {:?} listeners", listeners.len());
233
- Ok(listeners)
234
- }
235
-
236
- pub(crate) fn build_strategy(self) -> Result<()> {
237
- let listeners = self.build_listeners()?;
238
- let server = Arc::new(self);
239
- let server_clone = server.clone();
240
-
241
- let strategy = if server.config.workers == 1 {
242
- ServeStrategy::Single(Arc::new(SingleMode::new(
243
- server,
244
- listeners,
245
- SIGNAL_HANDLER_CHANNEL.0.clone(),
246
- )?))
247
- } else {
248
- ServeStrategy::Cluster(Arc::new(ClusterMode::new(
249
- server,
250
- listeners,
251
- SIGNAL_HANDLER_CHANNEL.0.clone(),
252
- )))
253
- };
254
-
255
- *server_clone.strategy.write() = Some(strategy);
256
- Ok(())
257
- }
258
-
259
- pub fn stop(&self) -> Result<()> {
260
- send_shutdown_event();
261
- Ok(())
262
- }
263
-
264
- pub fn start(&self) -> Result<()> {
265
- if self.silence {
266
- run_silently(|| self.build_and_run_strategy())
267
- } else {
268
- self.build_and_run_strategy()
269
- }
270
- }
271
-
272
- fn build_and_run_strategy(&self) -> Result<()> {
273
- reset_signal_handlers();
274
- let rself = self.clone();
275
- call_without_gvl(move || -> Result<()> {
276
- rself.clone().build_strategy()?;
277
- if let Err(e) = rself.strategy.read().as_ref().unwrap().run() {
278
- error!("Error running server: {}", e);
279
- rself.strategy.read().as_ref().unwrap().stop()?;
280
- }
281
- Ok(())
282
- })?;
283
- clear_signal_handlers();
284
- self.strategy.write().take();
285
- info!("Server stopped");
286
- Ok(())
287
- }
288
- }
@@ -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 into_tokio_listener(self) -> TokioListener {
247
- match self {
248
- Listener::Tcp(listener) => {
249
- TokioListener::Tcp(TokioTcpListener::from_std(listener).unwrap())
250
- }
251
- Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls(
252
- TokioTcpListener::from_std(listener).unwrap(),
253
- acceptor.clone(),
254
- ),
255
- Listener::Unix(listener) => {
256
- TokioListener::Unix(TokioUnixListener::from_std(listener).unwrap())
257
- }
258
- Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls(
259
- TokioUnixListener::from_std(listener).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;