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,25 +1,24 @@
1
1
  # frozen_string_literal: true
2
-
3
- env = ENV.fetch('APP_ENV') { ENV.fetch('RACK_ENV', 'development') }
4
-
5
2
  # This is the default Itsi configuration file, installed when you run `itsi init`
6
3
  # It contains a sane starting point for configuring your Itsi server.
7
4
  # You can use this file in both development and production environments.
8
5
  # Most of the options in this file can be overridden by command line options.
9
6
  # Check out itsi -h to learn more about the command line options available to you.
10
7
 
8
+ env = ENV.fetch("APP_ENV") { ENV.fetch("RACK_ENV", "development") }
9
+
11
10
  # Number of worker processes to spawn
12
11
  # If more than 1, Itsi will be booted in Cluster mode
13
- workers ENV.fetch('ITSI_WORKERS') {
14
- require 'etc'
15
- env == 'development' ? 1 : Etc.nprocessors
12
+ workers ENV.fetch("ITSI_WORKERS") {
13
+ require "etc"
14
+ env == "development" ? 1 : Etc.nprocessors
16
15
  }
17
16
 
18
17
  # Number of threads to spawn per worker process
19
18
  # For pure CPU bound applicationss, you'll get the best results keeping this number low
20
19
  # Setting a value of 1 is great for superficial benchmarks, but in reality
21
20
  # 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)
21
+ threads ENV.fetch("ITSI_THREADS", 1)
23
22
 
24
23
  # If your application is IO bound (e.g. performing a lot of proxied HTTP requests, or heavy queries etc)
25
24
  # you can see *substantial* benefits from enabling this option.
@@ -37,10 +36,17 @@ fiber_scheduler nil
37
36
  # require 'rack'
38
37
  # run(Rack::Builder.app do
39
38
  # use Rack::CommonLogger
40
- # run ->(_env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
39
+ # run ->(env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
41
40
  # end)
42
- rackup_file 'config.ru'
41
+ # rackup_file "config.ru"
43
42
 
43
+ watch "*.rb", [%w[bundle exec itsi reload]]
44
+ location "/*" do
45
+ get "" do |req|
46
+ req.respond("Hello")
47
+ end
48
+ end
49
+ # run ->(env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
44
50
  # If you bind to https, without specifying a certificate, Itsi will use a self-signed certificate.
45
51
  # The self-signed certificate will use a CA generated for your host and stored inside `ITSI_LOCAL_CA_DIR` (Defaults to ~/.itsi)
46
52
  # bind "https://localhost:3000"
@@ -58,10 +64,10 @@ rackup_file 'config.ru'
58
64
  # bind "unix:///tmp/itsi.sock"
59
65
  # bind "tls:///tmp/itsi.secure.sock"
60
66
 
61
- if env == 'development'
62
- bind 'http://localhost:3000'
67
+ if env == "development"
68
+ bind "http://127.0.0.1:3001"
63
69
  else
64
- bind "https://0.0.0.0?domains=#{ENV['PRODUCTION_DOMAINS']}&cert=acme&acme_email=admin@itsi.fyi"
70
+ bind "https://0.0.0.0?domains=#{ENV["PRODUCTION_DOMAINS"]}&cert=acme&acme_email=admin@itsi.fyi"
65
71
  end
66
72
 
67
73
  # If you want to preload the application, set preload to true
@@ -81,7 +87,7 @@ preload true
81
87
  # When this limit is reached, the worker will be gracefully restarted.
82
88
  # Only one worker is restarted at a time to ensure we don't take down
83
89
  # all of them at once, if they reach the threshold simultaneously.
84
- worker_memory_limit 48 * 1024 * 1024
90
+ worker_memory_limit 1024 * 1024 * 1024
85
91
 
86
92
  # You can provide an optional block of code to run, when a worker hits its memory threshold (Use this to send yourself an alert,
87
93
  # write metrics to disk etc. etc.)
data/Rakefile CHANGED
@@ -34,6 +34,7 @@ GEMS.each do |gem|
34
34
 
35
35
  SHARED_TASKS.each do |task|
36
36
  task task do
37
+ Rake::Task[:sync_crates].invoke
37
38
  sh "cd #{gem[:dir]} && rake #{task}"
38
39
  end
39
40
  end
@@ -57,6 +58,8 @@ task :sync_crates do
57
58
  GEMS.each do |gem_info|
58
59
  Dir.chdir('crates') do
59
60
  to_sync = Dir['*'].each do |to_sync|
61
+ next unless File.directory?(to_sync)
62
+
60
63
  system("rsync -q -av #{to_sync}/ ../#{gem_info[:dir]}/ext/#{to_sync} --delete")
61
64
  system("cp ../Cargo.lock ../#{gem_info[:dir]}/Cargo.lock")
62
65
  end
@@ -77,22 +80,20 @@ task :build_all do
77
80
  end
78
81
 
79
82
  task :test_env_up do
80
- system("terraform -chdir=sandbox/deploy apply")
83
+ system('terraform -chdir=sandbox/deploy apply')
81
84
  end
82
85
 
83
86
  task :test_env_down do
84
- system("terraform -chdir=sandbox/deploy destroy")
87
+ system('terraform -chdir=sandbox/deploy destroy')
85
88
  end
86
89
  %i[itsi puma iodine falcon unicorn].each do |server|
87
90
  namespace server do
88
91
  %i[hanami roda async rack rack_lint rails sinatra].each do |sandbox|
89
92
  namespace sandbox do
90
93
  task :serve do |args|
91
- begin
92
- system("(cd sandbox/itsi_sandbox_#{sandbox} && bundle exec #{server} #{ARGV[2..]&.join(" ")} )")
93
- rescue Interrupt
94
- # Suppress the stacktrace and message for Interrupt
95
- end
94
+ system("(cd sandbox/itsi_sandbox_#{sandbox} && bundle exec #{server} #{ARGV[2..]&.join(' ')} )")
95
+ rescue Interrupt
96
+ # Suppress the stacktrace and message for Interrupt
96
97
  end
97
98
  end
98
99
  end
@@ -22,3 +22,12 @@ pub enum ItsiError {
22
22
  #[error("Pass")]
23
23
  Pass(),
24
24
  }
25
+
26
+ impl ItsiError {
27
+ pub fn default(error: impl Send + Sync + 'static + std::fmt::Display) -> Self {
28
+ ItsiError::InvalidInput(format!("{}", error))
29
+ }
30
+ }
31
+
32
+ unsafe impl Send for ItsiError {}
33
+ unsafe impl Sync for ItsiError {}
@@ -8,3 +8,4 @@ cfg-if = "1.0.0"
8
8
  magnus = { version = "0.7.1", features = ["rb-sys", "bytes"] }
9
9
  nix = "0.29.0"
10
10
  rb-sys = "0.9.105"
11
+ serde = "1.0.219"
@@ -23,6 +23,24 @@ where
23
23
  }
24
24
  }
25
25
 
26
+ impl<T> HeapValue<T>
27
+ where
28
+ T: ReprValue,
29
+ {
30
+ pub fn into_inner(self) -> T {
31
+ *self.0
32
+ }
33
+ }
34
+
35
+ impl<T> HeapValue<T>
36
+ where
37
+ T: ReprValue,
38
+ {
39
+ pub fn cloned(&self) -> T {
40
+ *self.0
41
+ }
42
+ }
43
+
26
44
  impl<T> Deref for HeapValue<T>
27
45
  where
28
46
  T: ReprValue,
@@ -1,14 +1,14 @@
1
- use std::{os::raw::c_void, ptr::null_mut};
1
+ use std::{ffi::c_int, os::raw::c_void, ptr::null_mut};
2
2
 
3
3
  use magnus::{
4
- RArray, Ruby, Thread, Value,
4
+ ArgList, RArray, Ruby, Thread, Value,
5
5
  block::Proc,
6
- rb_sys::FromRawValue,
7
- value::{LazyId, ReprValue},
6
+ rb_sys::{AsRawId, FromRawValue, protect},
7
+ value::{IntoId, LazyId, ReprValue},
8
8
  };
9
9
  use rb_sys::{
10
- rb_thread_call_with_gvl, rb_thread_call_without_gvl, rb_thread_create, rb_thread_schedule,
11
- rb_thread_wakeup,
10
+ VALUE, rb_funcallv, rb_thread_call_with_gvl, rb_thread_call_without_gvl, rb_thread_create,
11
+ rb_thread_schedule, rb_thread_wakeup,
12
12
  };
13
13
 
14
14
  mod heap_value;
@@ -193,9 +193,36 @@ pub fn print_rb_backtrace(rb_err: Value) {
193
193
  let backtrace = rb_err
194
194
  .funcall::<_, _, Vec<String>>(*ID_BACKTRACE, ())
195
195
  .unwrap_or_default();
196
-
196
+ let rust_backtrace = std::backtrace::Backtrace::capture().to_string();
197
197
  eprintln!("Ruby exception {:?}", rb_err);
198
198
  for line in backtrace {
199
199
  eprintln!("{}", line);
200
200
  }
201
+ for line in rust_backtrace.lines() {
202
+ eprintln!("{}", line);
203
+ }
204
+ }
205
+
206
+ pub fn funcall_no_ret<T, M, A>(target: T, method: M, args: A) -> magnus::error::Result<()>
207
+ where
208
+ T: ReprValue,
209
+ M: IntoId,
210
+ A: ArgList,
211
+ {
212
+ protect(|| {
213
+ let handle = Ruby::get().unwrap();
214
+ let method = method.into_id_with(&handle);
215
+ let args = args.into_arg_list_with(&handle);
216
+ let slice = args.as_ref();
217
+ unsafe {
218
+ rb_funcallv(
219
+ target.as_rb_value(),
220
+ method.as_raw(),
221
+ slice.len() as c_int,
222
+ slice.as_ptr() as *const VALUE,
223
+ );
224
+ }
225
+ 0
226
+ })?;
227
+ Ok(())
201
228
  }
@@ -10,41 +10,80 @@ publish = false
10
10
  crate-type = ["cdylib"]
11
11
 
12
12
  [dependencies]
13
- magnus = { version = "0.7.1", features = ["bytes", "rb-sys"] }
14
- itsi_tracing = { path = "../itsi_tracing" }
15
- itsi_rb_helpers = { path = "../itsi_rb_helpers" }
16
- itsi_error = { path = "../itsi_error" }
17
- socket2 = "0.5.8"
18
- parking_lot = "0.12.3"
19
- rustls-pemfile = "2.2.0"
20
- tokio-rustls = "0.26.2"
21
- bytes = "1.3"
22
- tokio-rustls-acme = "0.6.0"
23
- rcgen = { version = "0.13.2", features = ["x509-parser", "pem"] }
13
+ async-compression = { version = "0.4.21", features = [
14
+ "tokio",
15
+ "zstd",
16
+ "brotli",
17
+ "deflate",
18
+ "gzip",
19
+ ] }
20
+ async-channel = "2.3.1"
21
+ async-trait = "0.1.87"
24
22
  base64 = "0.22.1"
23
+ bytes = "1.3"
24
+ chrono = "0.4.35"
25
+ crossbeam = "0.8.4"
26
+ dashmap = "6.1.0"
27
+ derive_more = { version = "2.0.1", features = ["debug"] }
28
+ dirs = "6.0.0"
29
+ either = "1.15.0"
30
+ fnv = "1.0.7"
31
+ fs2 = "0.4.3"
32
+ futures = "0.3.31"
33
+ globset = "0.4.16"
34
+ hmac = "0.12.1"
35
+ http = "1.3.1"
25
36
  http-body-util = "0.1.2"
37
+ httpdate = "1.0.3"
38
+ httparse = "1.10.1"
26
39
  hyper = { version = "1.5.0", features = ["full", "server", "http1", "http2"] }
27
- tokio = { version = "1.44.1", features = ["full"] }
40
+ hyper-staticfile = "0.10.1"
28
41
  hyper-util = { version = "0.1.10", features = ["full"] }
29
- derive_more = { version = "2.0.1", features = ["debug"] }
30
- http = "1.3.1"
31
- crossbeam = "0.8.4"
32
- futures = "0.3.31"
33
- nix = { version = "0.29.0", features = ["socket", "uio", "signal"] }
42
+ itsi_error = { path = "../itsi_error" }
43
+ itsi_rb_helpers = { path = "../itsi_rb_helpers" }
44
+ itsi_tracing = { path = "../itsi_tracing" }
45
+ jwt-simple = "0.12.12"
46
+ magnus = { version = "0.7.1", features = ["bytes", "rb-sys"] }
47
+ moka = { version = "0.12.10", features = ["sync"] }
48
+ notify = { version = "8.0.0" }
49
+ nix = { version = "0.29.0", features = [
50
+ "socket",
51
+ "uio",
52
+ "signal",
53
+ "fs",
54
+ "process",
55
+ ] }
56
+ num_cpus = "1.16.0"
57
+ parking_lot = "0.12.3"
34
58
  pin-project = "1.1.9"
59
+ rand = "0.9.0"
35
60
  rb-sys = "0.9.111"
36
- tracing = "0.1.41"
37
- tokio-util = "0.7.13"
38
- tokio-stream = "0.1.17"
39
- httparse = "1.10.1"
40
- async-channel = "2.3.1"
41
- tempfile = "3.18.0"
42
- sysinfo = "0.33.1"
43
- rustls = "0.23.23"
44
- fs2 = "0.4.3"
45
- ring = "0.17.14"
46
- async-trait = "0.1.87"
47
- dirs = "6.0.0"
61
+ rcgen = { version = "0.13.2", features = ["x509-parser", "pem"] }
48
62
  regex = "1.11.1"
63
+ reqwest = { version = "0.12.15", features = ["stream"] }
64
+ ring = "0.17.14"
49
65
  route-recognizer = "0.3.1"
50
- fnv = "1.0.7"
66
+ redis = { version = "0.29.2", features = [
67
+ "tokio-comp",
68
+ "r2d2",
69
+ "tokio-rustls-comp",
70
+ "connection-manager",
71
+ ] }
72
+ rustls = "0.23.23"
73
+ rustls-pemfile = "2.2.0"
74
+ serde = "1.0.219"
75
+ serde_json = "1.0.140"
76
+ serde_magnus = "0.9.0"
77
+ sha2 = "0.10.8"
78
+ socket2 = "0.5.8"
79
+ sysinfo = "0.33.1"
80
+ tempfile = "3.18.0"
81
+ tokio = { version = "1.44.1", features = ["full"] }
82
+ tokio-rustls = "0.26.2"
83
+ tokio-rustls-acme = "0.6.0"
84
+ tokio-stream = "0.1.17"
85
+ tokio-util = "0.7.13"
86
+ tracing = "0.1.41"
87
+ url = "2.5.4"
88
+ uuid = "1.16.0"
89
+ md5 = "0.7.0"
@@ -1,126 +1,17 @@
1
- use body_proxy::itsi_body_proxy::ItsiBodyProxy;
2
- use magnus::{
3
- error::Result, function, method, value::Lazy, Module, Object, RClass, RHash, RModule, Ruby,
1
+ use magnus::{error::Result, function, method, Module, Object, Ruby};
2
+ use ruby_types::{
3
+ itsi_body_proxy::ItsiBodyProxy, itsi_grpc_request::ItsiGrpcRequest,
4
+ itsi_grpc_stream::ItsiGrpcStream, itsi_http_request::ItsiHttpRequest,
5
+ itsi_http_response::ItsiHttpResponse, itsi_server::ItsiServer, ITSI_BODY_PROXY,
6
+ ITSI_GRPC_REQUEST, ITSI_GRPC_RESPONSE, ITSI_GRPC_STREAM, ITSI_MODULE, ITSI_REQUEST,
7
+ ITSI_RESPONSE, ITSI_SERVER,
4
8
  };
5
- use regex::{Regex, RegexSet};
6
- use request::itsi_request::ItsiRequest;
7
- use response::itsi_response::ItsiResponse;
8
- use server::{itsi_server::Server, signal::reset_signal_handlers};
9
+ use server::signal::reset_signal_handlers;
9
10
  use tracing::*;
10
-
11
- pub mod body_proxy;
12
11
  pub mod env;
13
- pub mod request;
14
- pub mod response;
12
+ pub mod ruby_types;
15
13
  pub mod server;
16
14
 
17
- pub static ITSI_MODULE: Lazy<RModule> = Lazy::new(|ruby| ruby.define_module("Itsi").unwrap());
18
- pub static ITSI_SERVER: Lazy<RClass> = Lazy::new(|ruby| {
19
- ruby.get_inner(&ITSI_MODULE)
20
- .define_class("Server", ruby.class_object())
21
- .unwrap()
22
- });
23
- pub static ITSI_REQUEST: Lazy<RClass> = Lazy::new(|ruby| {
24
- ruby.get_inner(&ITSI_MODULE)
25
- .define_class("Request", ruby.class_object())
26
- .unwrap()
27
- });
28
-
29
- pub static ITSI_RESPONSE: Lazy<RClass> = Lazy::new(|ruby| {
30
- ruby.get_inner(&ITSI_MODULE)
31
- .define_class("Response", ruby.class_object())
32
- .unwrap()
33
- });
34
-
35
- pub static ITSI_BODY_PROXY: Lazy<RClass> = Lazy::new(|ruby| {
36
- ruby.get_inner(&ITSI_MODULE)
37
- .define_class("BodyProxy", ruby.class_object())
38
- .unwrap()
39
- });
40
-
41
- pub static ITSI_SERVER_SCHEDULER_TASK: Lazy<RClass> = Lazy::new(|ruby| {
42
- ruby.get_inner(&ITSI_MODULE)
43
- .define_class("ServerSchedulerTask", ruby.class_object())
44
- .unwrap()
45
- });
46
-
47
- pub fn log_debug(msg: String) {
48
- debug!(msg);
49
- }
50
- pub fn log_info(msg: String) {
51
- info!(msg);
52
- }
53
- pub fn log_warn(msg: String) {
54
- warn!(msg);
55
- }
56
- pub fn log_error(msg: String) {
57
- error!(msg);
58
- }
59
-
60
- const ROUTES: [&str; 39] = [
61
- r"(?-u)^/organisations/(?<organisation_id>\d+)/users/(?<user_id>\d+)$",
62
- r"(?-u)^/projects/(?<project_id>\d+)/tasks/(?<task_id>\d+)$",
63
- r"(?-u)^/products/(?<product_id>\d+)(?:/reviews/(?<review_id>\d+))?$",
64
- r"(?-u)^/orders/(?<order_id>\d+)/items(?:/(?<item_id>\d+))?$",
65
- r"(?-u)^/posts/(?<post_id>\d+)/comments(?:/(?<comment_id>\d+))?$",
66
- r"(?-u)^/teams/(?<team_id>\d+)(?:/members/(?<member_id>\d+))?$",
67
- r"(?-u)^/categories/(?<category_id>\d+)/subcategories(?:/(?<subcategory_id>\d+))?$",
68
- r"(?-u)^/departments/(?<department_id>\d+)/employees/(?<employee_id>\d+)$",
69
- r"(?-u)^/events/(?<event_id>\d+)(?:/sessions/(?<session_id>\d+))?$",
70
- r"(?-u)^/invoices/(?<invoice_id>\d+)/payments(?:/(?<payment_id>\d+))?$",
71
- r"(?-u)^/tickets/(?<ticket_id>\d+)(?:/responses/(?<response_id>\d+))?$",
72
- r"(?-u)^/forums/(?<forum_id>\d+)(?:/threads/(?<thread_id>\d+))?$",
73
- r"(?-u)^/subscriptions/(?<subscription_id>\d+)/plans(?:/(?<plan_id>\d+))?$",
74
- r"(?-u)^/profiles/(?<profile_id>\d+)/settings$",
75
- r"(?-u)^/organizations/(?<organization_id>\d+)/billing(?:/(?<billing_id>\d+))?$",
76
- r"(?-u)^/vendors/(?<vendor_id>\d+)/products(?:/(?<product_id>\d+))?$",
77
- r"(?-u)^/courses/(?<course_id>\d+)/modules(?:/(?<module_id>\d+))?$",
78
- r"(?-u)^/accounts/(?<account_id>\d+)(?:/transactions/(?<transaction_id>\d+))?$",
79
- r"(?-u)^/warehouses/(?<warehouse_id>\d+)/inventory(?:/(?<inventory_id>\d+))?$",
80
- r"(?-u)^/campaigns/(?<campaign_id>\d+)/ads(?:/(?<ad_id>\d+))?$",
81
- r"(?-u)^/applications/(?<application_id>\d+)/stages(?:/(?<stage_id>\d+))?$",
82
- r"(?-u)^/notifications/(?<notification_id>\d+)$",
83
- r"(?-u)^/albums/(?<album_id>\d+)/photos(?:/(?<photo_id>\d+))?$",
84
- r"(?-u)^/news/(?<news_id>\d+)/articles(?:/(?<article_id>\d+))?$",
85
- r"(?-u)^/libraries/(?<library_id>\d+)/books(?:/(?<book_id>\d+))?$",
86
- r"(?-u)^/universities/(?<university_id>\d+)/students(?:/(?<student_id>\d+))?$",
87
- r"(?-u)^/banks/(?<bank_id>\d+)/branches(?:/(?<branch_id>\d+))?$",
88
- r"(?-u)^/vehicles/(?<vehicle_id>\d+)/services(?:/(?<service_id>\d+))?$",
89
- r"(?-u)^/hotels/(?<hotel_id>\d+)/rooms(?:/(?<room_id>\d+))?$",
90
- r"(?-u)^/doctors/(?<doctor_id>\d+)/appointments(?:/(?<appointment_id>\d+))?$",
91
- r"(?-u)^/gyms/(?<gym_id>\d+)/memberships(?:/(?<membership_id>\d+))?$",
92
- r"(?-u)^/restaurants/(?<restaurant_id>\d+)/menus(?:/(?<menu_id>\d+))?$",
93
- r"(?-u)^/parks/(?<park_id>\d+)/events(?:/(?<event_id>\d+))?$",
94
- r"(?-u)^/theaters/(?<theater_id>\d+)/shows(?:/(?<show_id>\d+))?$",
95
- r"(?-u)^/museums/(?<museum_id>\d+)/exhibits(?:/(?<exhibit_id>\d+))?$",
96
- r"(?-u)^/stadiums/(?<stadium_id>\d+)/games(?:/(?<game_id>\d+))?$",
97
- r"(?-u)^/schools/(?<school_id>\d+)/classes(?:/(?<class_id>\d+))?$",
98
- r"(?-u)^/clubs/(?<club_id>\d+)/events(?:/(?<event_id>\d+))?$",
99
- r"(?-u)^/festivals/(?<festival_id>\d+)/tickets(?:/(?<ticket_id>\d+))?$",
100
- ];
101
- use std::sync::LazyLock;
102
-
103
- static REGEX_SET: LazyLock<RegexSet> = LazyLock::new(|| RegexSet::new(ROUTES).unwrap());
104
- static REGEXES: LazyLock<Vec<Regex>> =
105
- LazyLock::new(|| ROUTES.iter().map(|&r| Regex::new(r).unwrap()).collect());
106
-
107
- fn match_route(input: String) -> Result<Option<(usize, Option<RHash>)>> {
108
- if let Some(index) = REGEX_SET.matches(&input).iter().next() {
109
- let regex = &REGEXES[index];
110
- if let Some(captures) = regex.captures(&input) {
111
- let params = RHash::with_capacity(captures.len());
112
- for name in regex.capture_names().flatten() {
113
- if let Some(value) = captures.name(name) {
114
- params.aset(name, value.as_str()).ok();
115
- }
116
- }
117
- return Ok(Some((index, Some(params))));
118
- }
119
- return Ok(Some((index, None)));
120
- }
121
- Ok(None)
122
- }
123
-
124
15
  #[magnus::init]
125
16
  fn init(ruby: &Ruby) -> Result<()> {
126
17
  itsi_tracing::init();
@@ -129,34 +20,35 @@ fn init(ruby: &Ruby) -> Result<()> {
129
20
  .ok();
130
21
 
131
22
  let itsi = ruby.get_inner(&ITSI_MODULE);
132
- itsi.define_singleton_method("match_route", function!(match_route, 1))?;
133
23
  itsi.define_singleton_method("log_debug", function!(log_debug, 1))?;
134
24
  itsi.define_singleton_method("log_info", function!(log_info, 1))?;
135
25
  itsi.define_singleton_method("log_warn", function!(log_warn, 1))?;
136
26
  itsi.define_singleton_method("log_error", function!(log_error, 1))?;
137
27
 
138
28
  let server = ruby.get_inner(&ITSI_SERVER);
139
- server.define_singleton_method("new", function!(Server::new, -1))?;
29
+ server.define_singleton_method("new", function!(ItsiServer::new, 3))?;
140
30
  server.define_singleton_method("reset_signal_handlers", function!(reset_signal_handlers, 0))?;
141
- server.define_method("start", method!(Server::start, 0))?;
142
- server.define_method("stop", method!(Server::stop, 0))?;
31
+ server.define_method("start", method!(ItsiServer::start, 0))?;
32
+ server.define_method("stop", method!(ItsiServer::stop, 0))?;
143
33
 
144
34
  let request = ruby.get_inner(&ITSI_REQUEST);
145
- request.define_method("path", method!(ItsiRequest::path, 0))?;
146
- request.define_method("script_name", method!(ItsiRequest::script_name, 0))?;
147
- request.define_method("query_string", method!(ItsiRequest::query_string, 0))?;
148
- request.define_method("method", method!(ItsiRequest::method, 0))?;
149
- request.define_method("version", method!(ItsiRequest::version, 0))?;
150
- request.define_method("rack_protocol", method!(ItsiRequest::rack_protocol, 0))?;
151
- request.define_method("host", method!(ItsiRequest::host, 0))?;
152
- request.define_method("headers", method!(ItsiRequest::headers, 0))?;
153
- request.define_method("scheme", method!(ItsiRequest::scheme, 0))?;
154
- request.define_method("remote_addr", method!(ItsiRequest::remote_addr, 0))?;
155
- request.define_method("port", method!(ItsiRequest::port, 0))?;
156
- request.define_method("body", method!(ItsiRequest::body, 0))?;
157
- request.define_method("response", method!(ItsiRequest::response, 0))?;
158
- request.define_method("json?", method!(ItsiRequest::is_json, 0))?;
159
- request.define_method("html?", method!(ItsiRequest::is_html, 0))?;
35
+ request.define_method("path", method!(ItsiHttpRequest::path, 0))?;
36
+ request.define_method("script_name", method!(ItsiHttpRequest::script_name, 0))?;
37
+ request.define_method("query_string", method!(ItsiHttpRequest::query_string, 0))?;
38
+ request.define_method("method", method!(ItsiHttpRequest::method, 0))?;
39
+ request.define_method("version", method!(ItsiHttpRequest::version, 0))?;
40
+ request.define_method("rack_protocol", method!(ItsiHttpRequest::rack_protocol, 0))?;
41
+ request.define_method("host", method!(ItsiHttpRequest::host, 0))?;
42
+ request.define_method("headers", method!(ItsiHttpRequest::headers, 0))?;
43
+ request.define_method("header", method!(ItsiHttpRequest::header, 1))?;
44
+ request.define_method("[]", method!(ItsiHttpRequest::header, 1))?;
45
+ request.define_method("scheme", method!(ItsiHttpRequest::scheme, 0))?;
46
+ request.define_method("remote_addr", method!(ItsiHttpRequest::remote_addr, 0))?;
47
+ request.define_method("port", method!(ItsiHttpRequest::port, 0))?;
48
+ request.define_method("body", method!(ItsiHttpRequest::body, 0))?;
49
+ request.define_method("response", method!(ItsiHttpRequest::response, 0))?;
50
+ request.define_method("json?", method!(ItsiHttpRequest::is_json, 0))?;
51
+ request.define_method("html?", method!(ItsiHttpRequest::is_html, 0))?;
160
52
 
161
53
  let body_proxy = ruby.get_inner(&ITSI_BODY_PROXY);
162
54
  body_proxy.define_method("gets", method!(ItsiBodyProxy::gets, 0))?;
@@ -165,16 +57,56 @@ fn init(ruby: &Ruby) -> Result<()> {
165
57
  body_proxy.define_method("close", method!(ItsiBodyProxy::close, 0))?;
166
58
 
167
59
  let response = ruby.get_inner(&ITSI_RESPONSE);
168
- response.define_method("add_header", method!(ItsiResponse::add_header, 2))?;
169
- response.define_method("status=", method!(ItsiResponse::set_status, 1))?;
170
- response.define_method("send_frame", method!(ItsiResponse::send_frame, 1))?;
171
- response.define_method("send_and_close", method!(ItsiResponse::send_and_close, 1))?;
172
- response.define_method("close_write", method!(ItsiResponse::close_write, 0))?;
173
- response.define_method("close_read", method!(ItsiResponse::close_read, 0))?;
174
- response.define_method("close", method!(ItsiResponse::close, 0))?;
175
- response.define_method("hijack", method!(ItsiResponse::hijack, 1))?;
176
- response.define_method("json?", method!(ItsiResponse::is_json, 0))?;
177
- response.define_method("html?", method!(ItsiResponse::is_html, 0))?;
60
+ response.define_method("[]=", method!(ItsiHttpResponse::add_header, 2))?;
61
+ response.define_method("add_header", method!(ItsiHttpResponse::add_header, 2))?;
62
+ response.define_method("add_headers", method!(ItsiHttpResponse::add_headers, 1))?;
63
+ response.define_method("status=", method!(ItsiHttpResponse::set_status, 1))?;
64
+ response.define_method("send_frame", method!(ItsiHttpResponse::send_frame, 1))?;
65
+ response.define_method("<<", method!(ItsiHttpResponse::send_frame, 1))?;
66
+ response.define_method("write", method!(ItsiHttpResponse::send_frame, 1))?;
67
+ response.define_method("read", method!(ItsiHttpResponse::recv_frame, 0))?;
68
+ response.define_method(
69
+ "send_and_close",
70
+ method!(ItsiHttpResponse::send_and_close, 1),
71
+ )?;
72
+ response.define_method("close_write", method!(ItsiHttpResponse::close_write, 0))?;
73
+ response.define_method("close_read", method!(ItsiHttpResponse::close_read, 0))?;
74
+ response.define_method("close", method!(ItsiHttpResponse::close, 0))?;
75
+ response.define_method("hijack", method!(ItsiHttpResponse::hijack, 1))?;
76
+ response.define_method("json?", method!(ItsiHttpResponse::is_json, 0))?;
77
+ response.define_method("html?", method!(ItsiHttpResponse::is_html, 0))?;
78
+
79
+ let grpc_request = ruby.get_inner(&ITSI_GRPC_REQUEST);
80
+
81
+ grpc_request.define_method("service_name", method!(ItsiGrpcRequest::service_name, 0))?;
82
+ grpc_request.define_method("method_name", method!(ItsiGrpcRequest::method_name, 0))?;
83
+ grpc_request.define_method("stream", method!(ItsiGrpcRequest::stream, 0))?;
84
+ grpc_request.define_method("json?", method!(ItsiGrpcRequest::is_json, 0))?;
85
+ grpc_request.define_method(
86
+ "content_type",
87
+ method!(ItsiGrpcRequest::content_type_str, 0),
88
+ )?;
89
+
90
+ let grpc_stream = ruby.get_inner(&ITSI_GRPC_STREAM);
91
+ grpc_stream.define_method("read", method!(ItsiGrpcStream::read, 1))?;
92
+ grpc_stream.define_method("write", method!(ItsiGrpcStream::write, 1))?;
93
+ grpc_stream.define_method("flush", method!(ItsiGrpcStream::flush, 0))?;
94
+ grpc_stream.define_method("send_trailers", method!(ItsiGrpcStream::send_trailers, 1))?;
95
+
96
+ let _grpc_response = ruby.get_inner(&ITSI_GRPC_RESPONSE);
178
97
 
179
98
  Ok(())
180
99
  }
100
+
101
+ pub fn log_debug(msg: String) {
102
+ debug!(msg);
103
+ }
104
+ pub fn log_info(msg: String) {
105
+ info!(msg);
106
+ }
107
+ pub fn log_warn(msg: String) {
108
+ warn!(msg);
109
+ }
110
+ pub fn log_error(msg: String) {
111
+ error!(msg);
112
+ }
@@ -6,7 +6,7 @@ use tempfile::NamedTempFile;
6
6
 
7
7
  const THRESHOLD: usize = 1024 * 1024; // 1 MB
8
8
 
9
- /// An container that holds data in memory if it’s small, or in a temporary file on disk if it exceeds THRESHOLD.
9
+ /// A container that will hold data in memory if it’s small, or in a temporary file on disk if it exceeds THRESHOLD.
10
10
  /// Used for providing Rack input data.
11
11
  pub enum BigBytes {
12
12
  InMemory(Vec<u8>),
@@ -27,7 +27,7 @@ impl BigBytes {
27
27
  BigBytes::InMemory(Vec::new())
28
28
  }
29
29
 
30
- /// Reads the entire contents that have been written.
30
+ /// Returns either the raw bytes, or the file path of the BigBytes
31
31
  ///
32
32
  /// - If stored in memory, returns a clone of the bytes.
33
33
  /// - If stored on disk, returns the file path of the temporary file.
@@ -42,17 +42,22 @@ impl BigBytes {
42
42
  }
43
43
  }
44
44
 
45
- pub fn as_value(&self) -> Value {
45
+ /// Turn this into a value that can be used in Ruby.
46
+ pub fn as_value(&self) -> Option<Value> {
46
47
  match self {
47
48
  BigBytes::InMemory(bytes) => {
48
49
  let bytes = Bytes::from(bytes.to_owned());
49
- bytes.into_value()
50
+ if bytes.is_empty() {
51
+ None
52
+ } else {
53
+ Some(bytes.into_value())
54
+ }
50
55
  }
51
56
  BigBytes::OnDisk(path) => {
52
57
  let ruby = Ruby::get().unwrap();
53
58
  let rarray = ruby.ary_new();
54
59
  rarray.push(path.path().to_str().unwrap().into_value()).ok();
55
- rarray.into_value()
60
+ Some(rarray.into_value())
56
61
  }
57
62
  }
58
63
  }