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
@@ -0,0 +1,213 @@
1
+ module Itsi
2
+ class Server
3
+ class GrpcActiveCall
4
+ attr_reader :stream, :method_rpc, :output_metadata, :method_name
5
+
6
+ def initialize(stream, method_rpc, service_class, method_name)
7
+ @stream = stream
8
+ @method_rpc = method_rpc
9
+ @service_class = service_class
10
+ @output_metadata = {}
11
+ @method_name = method_name
12
+ end
13
+ end
14
+
15
+ class GrpcInterface
16
+ def self.for(services)
17
+ interface = new(services)
18
+ lambda do |request|
19
+ interface.handle_request(request)
20
+ end
21
+ end
22
+
23
+ def initialize(services = [])
24
+ @services = {}
25
+ register_services(services)
26
+ end
27
+
28
+ def register_services(services)
29
+ services.each do |service|
30
+ service_class = service.class
31
+ @services[service_class.service_name] = {
32
+ implementation: service,
33
+ class: service_class
34
+ }
35
+ end
36
+ end
37
+
38
+ def handle_request(request)
39
+ service_info = @services[request.service_name]
40
+ raise "Unknown service: #{request.service_name}" unless service_info
41
+
42
+ service_impl = service_info[:implementation]
43
+ service_class = service_info[:class]
44
+
45
+ method_rpc = RpcDescWrapper.new(service_class, request.content_type, request.method_name)
46
+
47
+ active_call = GrpcActiveCall.new(request.stream, method_rpc, service_class, request.method_name)
48
+
49
+ if method_rpc.bidi_streamer?
50
+ puts "Calling bidirectional streaming handler"
51
+ handle_bidi_streaming(active_call, service_impl)
52
+ elsif method_rpc.client_streamer?
53
+ puts "Calling client streaming handler"
54
+ handle_client_streaming(active_call, service_impl)
55
+ elsif method_rpc.server_streamer?
56
+ puts "Calling server streaming handler"
57
+ handle_server_streaming(active_call, service_impl)
58
+ elsif method_rpc.request_response?
59
+ handle_unary(active_call, service_impl)
60
+ end
61
+ active_call.stream.send_trailers({ "grpc-status" => "0" })
62
+ rescue StandardError => e
63
+ active_call.stream.send_trailers({ "grpc-status" => "13", "grpc-message" => e.message })
64
+ end
65
+
66
+ private
67
+
68
+ # Read a framed message from the stream
69
+ def read_message(stream)
70
+ # Read the gRPC frame header (5 bytes)
71
+ header = stream.read(5)
72
+ return nil if header.nil? || header.bytesize < 5
73
+
74
+ compressed = header.bytes[0] == 1
75
+ length = header[1..4].unpack1("N")
76
+
77
+ # Read the message body
78
+ stream.read(length)
79
+ end
80
+
81
+ # Send a response
82
+ def send_response(active_call, response)
83
+ response_data = active_call.method_rpc.marshal_response(response)
84
+ send_framed_message(active_call.stream, response_data)
85
+ end
86
+
87
+ # Send a framed message
88
+ def send_framed_message(stream, message_data, compressed = false)
89
+ compressed_flag = compressed ? 1 : 0
90
+ header = [compressed_flag, message_data.bytesize].pack("CN")
91
+
92
+ stream.write(header)
93
+ stream.write(message_data)
94
+ stream.flush
95
+ end
96
+
97
+ # Create an enumerator for client streaming requests
98
+ def create_request_enum(active_call)
99
+ Enumerator.new do |yielder|
100
+ loop do
101
+ message_data = read_message(active_call.stream)
102
+ break if message_data.nil?
103
+
104
+ request = active_call.method_rpc.unmarshal_request(message_data)
105
+ yielder << request
106
+ end
107
+ end
108
+ end
109
+
110
+ # Handlers for different RPC types
111
+
112
+ def handle_unary(active_call, service)
113
+ # Read the request message
114
+ message_data = read_message(active_call.stream)
115
+ request = active_call.method_rpc.unmarshal_request(message_data)
116
+
117
+ # Call the service implementation
118
+ underscore_method = GRPC::GenericService.underscore(active_call.method_name)
119
+ response = service.send(underscore_method, request, active_call)
120
+
121
+ # Send response
122
+ send_response(active_call, response)
123
+ end
124
+
125
+ def handle_client_streaming(active_call, service)
126
+ # Create an enumerable to read the incoming stream
127
+ request_enum = create_request_enum(active_call)
128
+
129
+ # Call the service implementation
130
+ underscore_method = GRPC::GenericService.underscore(active_call.method_name)
131
+ response = service.send(underscore_method, request_enum, active_call)
132
+
133
+ # Send response
134
+ send_response(active_call, response)
135
+ end
136
+
137
+ def handle_server_streaming(active_call, service)
138
+ # Read the request message
139
+ message_data = read_message(active_call.stream)
140
+ request = active_call.method_rpc.unmarshal_request(message_data)
141
+
142
+ # Call the service implementation with a block to handle streaming
143
+ underscore_method = GRPC::GenericService.underscore(active_call.method_name)
144
+ service.send(underscore_method, request, active_call) do |response|
145
+ send_response(active_call, response)
146
+ end
147
+ end
148
+
149
+ def handle_bidi_streaming(active_call, service)
150
+ # Create an enumerable to read the incoming stream
151
+ request_enum = create_request_enum(active_call)
152
+
153
+ # Call the service implementation with a block
154
+ underscore_method = GRPC::GenericService.underscore(active_call.method_name)
155
+ service.send(underscore_method, request_enum, active_call) do |response|
156
+ send_response(active_call, response)
157
+ end
158
+ end
159
+ end
160
+
161
+ class RpcDescWrapper
162
+ def initialize(service_class, content_type, method_name)
163
+ rpc_descs = service_class.rpc_descs
164
+ @rpc_desc = rpc_descs[method_name.to_sym]
165
+ raise "Method not found: #{method_name}" unless @rpc_desc
166
+
167
+ @input_type = @rpc_desc.input
168
+ @content_type = content_type
169
+ @input_is_stream = @input_type.is_a?(GRPC::RpcDesc::Stream)
170
+ @input_type = @input_type.type if @input_is_stream
171
+
172
+ @output_type = @rpc_desc.output
173
+ @output_is_stream = @output_type.is_a?(GRPC::RpcDesc::Stream)
174
+ @output_type = @output_type.type if @output_is_stream
175
+
176
+ @client_streamer = @input_is_stream
177
+ @server_streamer = @output_is_stream
178
+ end
179
+
180
+ def client_streamer?
181
+ @client_streamer
182
+ end
183
+
184
+ def server_streamer?
185
+ @server_streamer
186
+ end
187
+
188
+ def bidi_streamer?
189
+ @client_streamer && @server_streamer
190
+ end
191
+
192
+ def request_response?
193
+ !@client_streamer && !@server_streamer
194
+ end
195
+
196
+ def unmarshal_request(data)
197
+ if @content_type == "application/json"
198
+ @input_type.decode_json(data)
199
+ else
200
+ @input_type.decode(data)
201
+ end
202
+ end
203
+
204
+ def marshal_response(response)
205
+ if @content_type == "application/json"
206
+ response.to_json
207
+ else
208
+ response.to_proto
209
+ end
210
+ end
211
+ end
212
+ end
213
+ end
@@ -4,23 +4,14 @@ module Rack
4
4
  module Handler
5
5
  module Itsi
6
6
  def self.run(app, options = {})
7
- ::Itsi::Server.start(
8
- **Itsi::Server::Config.load(
9
- {
10
- app: app,
11
- binds: [
12
- "http://#{
13
- options.fetch(
14
- :host,
15
- "127.0.0.1"
16
- )}:#{
17
- options.fetch(
18
- :Port,
19
- 3001
20
- )}"
21
- ]
22
- }
23
- )
7
+ host = options.fetch(:host, "127.0.0.1")
8
+ port = options.fetch(:Port, 3001)
9
+ Itsi::Server.start(
10
+ {
11
+ app: app,
12
+ binds: ["http://#{host}:#{port}"]
13
+ },
14
+ Itsi::Server::Config.config_file_path
24
15
  )
25
16
  end
26
17
  end
@@ -1,6 +1,22 @@
1
1
  module Itsi
2
2
  class Server
3
3
  module RackInterface
4
+
5
+ # Builds a handler proc that is compatible with Rack applications.
6
+ def self.for(app)
7
+ require "rack"
8
+ if app.is_a?(String)
9
+ dir = File.expand_path(File.dirname(app))
10
+ Dir.chdir(dir) do
11
+ loaded_app = ::Rack::Builder.parse_file(app)
12
+ app = loaded_app.is_a?(Array) ? loaded_app.first : loaded_app
13
+ end
14
+ end
15
+ lambda do |request|
16
+ Server.respond(request, app.call(request.to_rack_env))
17
+ end
18
+ end
19
+
4
20
  # Interface to Rack applications.
5
21
  # Here we build the env, and invoke the Rack app's call method.
6
22
  # We then turn the Rack response into something Itsi server understands.
@@ -25,10 +41,13 @@ module Itsi
25
41
  # 2. Set Headers
26
42
  body_streamer = streaming_body?(body) ? body : headers.delete("rack.hijack")
27
43
  headers.each do |key, value|
28
- next response.add_header(key, value) unless value.is_a?(Array)
44
+ unless value.is_a?(Array)
45
+ response[key] = value
46
+ next
47
+ end
29
48
 
30
49
  value.each do |v|
31
- response.add_header(key, v)
50
+ response[key] = v
32
51
  end
33
52
  end
34
53
 
@@ -40,7 +59,7 @@ module Itsi
40
59
  # stream this response.
41
60
 
42
61
  if body_streamer
43
- body_streamer.call(StreamIO.new(response))
62
+ body_streamer.call(response)
44
63
 
45
64
  # If we're enumerable with more than one chunk
46
65
  # also stream, otherwise write in a single chunk
@@ -53,7 +72,7 @@ module Itsi
53
72
  # to optimize for the case where there's only one chunk.
54
73
  buffer = nil
55
74
  body.each do |part|
56
- response.send_frame(buffer.to_s) if buffer
75
+ response << buffer.to_s if buffer
57
76
  buffer = part
58
77
  end
59
78
 
@@ -13,7 +13,7 @@ module Itsi
13
13
  # each request is wrapped in a Fiber.
14
14
  def schedule(app, request)
15
15
  Fiber.schedule do
16
- call(app, request)
16
+ app.call(request)
17
17
  end
18
18
  end
19
19
  end
@@ -1,3 +1,7 @@
1
+ # Running with a Fiber scheduler enabled but with an ActiveSupport isolation_level set to Thread
2
+ # can be dangerous. A thread isolation level means that all fibers sharing a thread can content
3
+ # for the same resources, which can lead to race conditions.
4
+ # This hook should *only* be disabled if you know there are no such shared resources.
1
5
  if defined?(ActiveSupport::IsolatedExecutionState) && !ENV["ITSI_DISABLE_AS_AUTO_FIBER_ISOLATION_LEVEL"]
2
6
  Itsi.log_info \
3
7
  "ActiveSupport Isolated Execution state detected. Automatically switching to :fiber mode. "\
@@ -1,6 +1,11 @@
1
1
  module Itsi
2
+ # This trap is necessary for debuggers and similar which intercept certain signals
3
+ # then attempt to restore these to the previous signal when finished.
4
+ # If the previous signal handler was registered in native code, this restoration doesn't
5
+ # work as expected and the native signal handler is lost.
6
+ # We intercept restored signals here and reinstate the Itsi server signal handlers
7
+ # (if the server is still running).
2
8
  module SignalTrap
3
-
4
9
  DEFAULT_SIGNALS = ["DEFAULT", "", nil].freeze
5
10
  INTERCEPTED_SIGNALS = ["INT"].freeze
6
11
 
@@ -8,6 +13,7 @@ module Itsi
8
13
  unless INTERCEPTED_SIGNALS.include?(signal.to_s) && block.nil? && Itsi::Server.running?
9
14
  return super(signal, *args, &block)
10
15
  end
16
+
11
17
  Itsi::Server.reset_signal_handlers
12
18
  nil
13
19
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Itsi
4
4
  class Server
5
- VERSION = "0.1.11"
5
+ VERSION = "0.1.12"
6
6
  end
7
7
  end
@@ -3,48 +3,14 @@
3
3
  require_relative "server/version"
4
4
  require_relative "server/itsi_server"
5
5
  require_relative "server/rack_interface"
6
- require_relative "server/signal_trap"
6
+ require_relative "server/grpc_interface"
7
7
  require_relative "server/scheduler_interface"
8
+ require_relative "server/signal_trap"
8
9
  require_relative "server/rack/handler/itsi"
9
10
  require_relative "server/config"
10
- require_relative "request"
11
- require_relative "stream_io"
12
-
13
- # When you Run Itsi without a Rack app,
14
- # we start a tiny little echo server, just so you can see it in action.
15
- DEFAULT_INDEX = IO.read("#{__dir__}/index.html").freeze
16
- DEFAULT_BINDS = ["http://0.0.0.0:3000"].freeze
17
- DEFAULT_APP = lambda {
18
- require "json"
19
- require "itsi/scheduler"
20
- Itsi.log_warn "No config.ru or Itsi.rb app detected. Running default app."
21
- lambda do |env|
22
- headers, body = \
23
- if env["itsi.response"].json?
24
- [
25
- { "Content-Type" => "application/json" },
26
- [{ "message" => "You're running on Itsi!", "rack_env" => env,
27
- "version" => Itsi::Server::VERSION }.to_json]
28
- ]
29
- else
30
- [
31
- { "Content-Type" => "text/html" },
32
- [
33
- format(
34
- DEFAULT_INDEX,
35
- REQUEST_METHOD: env["REQUEST_METHOD"],
36
- PATH_INFO: env["PATH_INFO"],
37
- SERVER_NAME: env["SERVER_NAME"],
38
- SERVER_PORT: env["SERVER_PORT"],
39
- REMOTE_ADDR: env["REMOTE_ADDR"],
40
- HTTP_USER_AGENT: env["HTTP_USER_AGENT"]
41
- )
42
- ]
43
- ]
44
- end
45
- [200, headers, body]
46
- end
47
- }
11
+ require_relative "standard_headers"
12
+ require_relative "http_request"
13
+ require_relative "http_response"
48
14
 
49
15
  module Itsi
50
16
  class Server
@@ -56,35 +22,80 @@ module Itsi
56
22
  !!@running
57
23
  end
58
24
 
59
- def build(
60
- app: DEFAULT_APP[],
61
- loader: nil,
62
- binds: DEFAULT_BINDS,
63
- **opts
64
- )
65
- new(app: loader || -> { app }, binds: binds, **opts)
25
+ def start_in_background_thread(cli_params={}, itsi_file = Itsi::Server::Config.config_file_path, &blk)
26
+ @background_thread = start(cli_params, itsi_file, background: true, &blk)
27
+ end
28
+
29
+ def start(cli_params, itsi_file = Itsi::Server::Config.config_file_path, background: false, &blk)
30
+ server = new(cli_params, itsi_file, blk)
31
+ previous_handler = Signal.trap(:INT, :DEFAULT)
32
+ run = lambda do
33
+ write_pid
34
+ @running = server
35
+ server.start
36
+ Signal.trap(:INT, previous_handler)
37
+ server
38
+ end
39
+ background ? Thread.new(&run) : run[]
40
+ end
41
+
42
+ def stop_background_thread
43
+ @running&.stop
44
+ @running = nil
45
+ @background_thread&.join
66
46
  end
67
47
 
68
- def start_in_background_thread(silence: true, **opts)
69
- start(background: true, silence: silence, **opts)
48
+ def write_pid
49
+ File.write(Itsi::Server::Config.pid_file_path, Process.pid)
70
50
  end
71
51
 
72
- def start(background: false, silence: false, **opts)
73
- build(**opts).tap do |server|
74
- previous_handler = Signal.trap("INT", "DEFAULT")
75
- @running = true
76
- if background
77
- Thread.new do
78
- server.start
79
- @running = false
80
- Signal.trap("INT", previous_handler)
81
- end
82
- else
83
- server.start
84
- @running = false
85
- Signal.trap("INT", previous_handler)
86
- end
52
+ def get_pid
53
+ pid = File.read(Itsi::Server::Config.pid_file_path).to_i
54
+ if Process.kill(0, pid)
55
+ pid
56
+ else
57
+ nil
87
58
  end
59
+ rescue StandardError
60
+ nil
61
+ end
62
+
63
+ def reload
64
+ return unless pid = get_pid
65
+
66
+ Process.kill(:USR2, pid)
67
+ end
68
+
69
+ def restart
70
+ return unless pid = get_pid
71
+
72
+ Process.kill(:USR1, pid)
73
+ end
74
+
75
+ def down
76
+ puts :down
77
+ end
78
+
79
+ def up
80
+ puts :up
81
+ end
82
+
83
+ def add_worker
84
+ return unless pid = get_pid
85
+
86
+ Process.kill(:TTIN, pid)
87
+ end
88
+
89
+ def remove_worker
90
+ return unless pid = get_pid
91
+
92
+ Process.kill(:TTOU, pid)
93
+ end
94
+
95
+ def status
96
+ return unless pid = get_pid
97
+
98
+ Process.kill(:INFO, pid)
88
99
  end
89
100
  end
90
101
  end
@@ -0,0 +1,86 @@
1
+ module Itsi
2
+ module StandardHeaders
3
+ ALL = [
4
+ ACCEPT = "accept",
5
+ ACCEPT_CHARSET = "accept-charset",
6
+ ACCEPT_ENCODING = "accept-encoding",
7
+ ACCEPT_LANGUAGE = "accept-language",
8
+ ACCEPT_RANGES = "accept-ranges",
9
+ ACCESS_CONTROL_ALLOW_CREDENTIALS = "access-control-allow-credentials",
10
+ ACCESS_CONTROL_ALLOW_HEADERS = "access-control-allow-headers",
11
+ ACCESS_CONTROL_ALLOW_METHODS = "access-control-allow-methods",
12
+ ACCESS_CONTROL_ALLOW_ORIGIN = "access-control-allow-origin",
13
+ ACCESS_CONTROL_EXPOSE_HEADERS = "access-control-expose-headers",
14
+ ACCESS_CONTROL_MAX_AGE = "access-control-max-age",
15
+ ACCESS_CONTROL_REQUEST_HEADERS = "access-control-request-headers",
16
+ ACCESS_CONTROL_REQUEST_METHOD = "access-control-request-method",
17
+ AGE = "age",
18
+ ALLOW = "allow",
19
+ ALT_SVC = "alt-svc",
20
+ AUTHORIZATION = "authorization",
21
+ CACHE_CONTROL = "cache-control",
22
+ CACHE_STATUS = "cache-status",
23
+ CDN_CACHE_CONTROL = "cdn-cache-control",
24
+ CONNECTION = "connection",
25
+ CONTENT_DISPOSITION = "content-disposition",
26
+ CONTENT_ENCODING = "content-encoding",
27
+ CONTENT_LANGUAGE = "content-language",
28
+ CONTENT_LENGTH = "content-length",
29
+ CONTENT_LOCATION = "content-location",
30
+ CONTENT_RANGE = "content-range",
31
+ CONTENT_SECURITY_POLICY_REPORT_ONLY = "content-security-policy-report-only",
32
+ CONTENT_TYPE = "content-type",
33
+ COOKIE = "cookie",
34
+ DNT = "dnt",
35
+ DATE = "date",
36
+ ETAG = "etag",
37
+ EXPECT = "expect",
38
+ EXPIRES = "expires",
39
+ FORWARDED = "forwarded",
40
+ FROM = "from",
41
+ HOST = "host",
42
+ IF_MATCH = "if-match",
43
+ IF_MODIFIED_SINCE = "if-modified-since",
44
+ IF_NONE_MATCH = "if-none-match",
45
+ IF_RANGE = "if-range",
46
+ IF_UNMODIFIED_SINCE = "if-unmodified-since",
47
+ LAST_MODIFIED = "last-modified",
48
+ LINK = "link",
49
+ LOCATION = "location",
50
+ MAX_FORWARDS = "max-forwards",
51
+ ORIGIN = "origin",
52
+ PRAGMA = "pragma",
53
+ PROXY_AUTHENTICATE = "proxy-authenticate",
54
+ PROXY_AUTHORIZATION = "proxy-authorization",
55
+ PUBLIC_KEY_PINS = "public-key-pins",
56
+ PUBLIC_KEY_PINS_REPORT_ONLY = "public-key-pins-report-only",
57
+ RANGE = "range",
58
+ REFERER = "referer",
59
+ REFERRER_POLICY = "referrer-policy",
60
+ REFRESH = "refresh",
61
+ RETRY_AFTER = "retry-after",
62
+ SEC_WEBSOCKET_ACCEPT = "sec-websocket-accept",
63
+ SEC_WEBSOCKET_EXTENSIONS = "sec-websocket-extensions",
64
+ SEC_WEBSOCKET_KEY = "sec-websocket-key",
65
+ SEC_WEBSOCKET_PROTOCOL = "sec-websocket-protocol",
66
+ SEC_WEBSOCKET_VERSION = "sec-websocket-version",
67
+ SERVER = "server",
68
+ SET_COOKIE = "set-cookie",
69
+ STRICT_TRANSPORT_SECURITY = "strict-transport-security",
70
+ TE = "te",
71
+ TRAILER = "trailer",
72
+ TRANSFER_ENCODING = "transfer-encoding",
73
+ USER_AGENT = "user-agent",
74
+ UPGRADE = "upgrade",
75
+ UPGRADE_INSECURE_REQUESTS = "upgrade-insecure-requests",
76
+ VARY = "vary",
77
+ VIA = "via",
78
+ WARNING = "warning",
79
+ WWW_AUTHENTICATE = "www-authenticate",
80
+ X_CONTENT_TYPE_OPTIONS = "x-content-type-options",
81
+ X_DNS_PREFETCH_CONTROL = "x-dns-prefetch-control",
82
+ X_FRAME_OPTIONS = "x-frame-options",
83
+ X_XSS_PROTECTION = "x-xss-protection",
84
+ ]
85
+ end
86
+ end
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "minitest/reporters"
4
-
5
- ENV['ITSI_LOG'] = 'off'
6
-
7
4
  require "itsi/server"
8
5
  require "itsi/scheduler"
9
6
 
@@ -16,15 +13,18 @@ def free_bind(protocol)
16
13
  "#{protocol}://0.0.0.0:#{port}"
17
14
  end
18
15
 
19
- def run_app(app, protocol: "http", bind: free_bind(protocol), **opts)
20
- server = Itsi::Server.start_in_background_thread(
21
- app: app,
22
- binds: [bind],
23
- **opts
24
- )
16
+ def run_app(app, protocol: "http", bind: free_bind(protocol), scheduler_class: nil)
17
+ Itsi::Server.start_in_background_thread do
18
+ # Inline Itsi.rb
19
+ bind bind
20
+ workers 1
21
+ threads 1
22
+ fiber_scheduler scheduler_class
23
+ log_level :error
24
+ run app
25
+ end
25
26
 
26
- sleep 0.005
27
- yield URI(bind), server
27
+ yield URI(bind)
28
28
  ensure
29
- server&.stop
29
+ Itsi::Server.stop_background_thread
30
30
  end
@@ -76,7 +76,6 @@ class TestItsiServer < Minitest::Test
76
76
  end
77
77
  end
78
78
 
79
- require 'debug'
80
79
  def test_scheduler_non_blocking
81
80
  run_app(
82
81
  lambda do |env|
@@ -290,7 +289,8 @@ class TestItsiServer < Minitest::Test
290
289
  run_app(lambda do |env|
291
290
  [200, { "Content-Type" => "text/plain" }, ["Hello, HTTPS!"]]
292
291
  end, protocol: "https") do |uri|
293
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
292
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true,
293
+ verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
294
294
  http.request(Net::HTTP::Get.new(uri))
295
295
  end
296
296
  assert_equal "200", response.code
data/lib/itsi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Itsi
2
- VERSION = '0.1.11'
2
+ VERSION = '0.1.12'
3
3
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # gem "rails"
6
+
7
+ gem 'itsi-scheduler', path: '../../gems/scheduler'
8
+ gem 'itsi-server', path: '../../gems/server'
9
+
10
+ gem 'debug'
11
+ gem 'grpc'