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,58 +1,229 @@
1
- use std::env;
2
-
3
1
  use atty::{Stream, is};
4
- use tracing::level_filters::LevelFilter;
5
- pub use tracing::{debug, error, info, trace, warn};
6
- pub use tracing_attributes::instrument; // Explicitly export from tracing-attributes
7
- use tracing_subscriber::{
8
- EnvFilter, Layer,
9
- fmt::{self, format},
10
- layer::SubscriberExt,
2
+ use std::{
3
+ env,
4
+ sync::{Mutex, OnceLock},
11
5
  };
6
+ pub use tracing::{debug, error, info, trace, warn};
7
+ use tracing_appender::rolling;
8
+ use tracing_subscriber::Layer;
9
+ use tracing_subscriber::fmt::writer::BoxMakeWriter;
10
+ use tracing_subscriber::{EnvFilter, fmt, prelude::*, reload};
11
+
12
+ // Global reload handle for changing the level at runtime.
13
+ static RELOAD_HANDLE: OnceLock<
14
+ Mutex<Option<reload::Handle<EnvFilter, tracing_subscriber::Registry>>>,
15
+ > = OnceLock::new();
16
+
17
+ /// Log format: Plain or JSON.
18
+ #[derive(Debug, Clone)]
19
+ pub enum LogFormat {
20
+ Plain,
21
+ Json,
22
+ }
23
+
24
+ /// Log target: STDOUT, File, or Both.
25
+ #[derive(Debug, Clone)]
26
+ pub enum LogTarget {
27
+ Stdout,
28
+ File(String), // file name (rotated daily)
29
+ Both(String), // file name (rotated daily) plus STDOUT
30
+ }
31
+
32
+ /// Logger configuration.
33
+ #[derive(Debug, Clone)]
34
+ pub struct LogConfig {
35
+ /// Log level as a string (e.g. "info", "debug").
36
+ pub level: String,
37
+ /// Format: Plain (with optional ANSI) or JSON.
38
+ pub format: LogFormat,
39
+ /// Target: STDOUT, File, or Both.
40
+ pub target: LogTarget,
41
+ /// Whether to enable ANSI coloring (for plain text).
42
+ pub use_ansi: bool,
43
+ }
12
44
 
13
- #[instrument]
45
+ impl Default for LogConfig {
46
+ fn default() -> Self {
47
+ let level = env::var("ITSI_LOG").unwrap_or_else(|_| "info".into());
48
+ let format = match env::var("ITSI_LOG_FORMAT").as_deref() {
49
+ Ok("json") => LogFormat::Json,
50
+ _ => LogFormat::Plain,
51
+ };
52
+ let target = match env::var("ITSI_LOG_TARGET").as_deref() {
53
+ Ok("file") => {
54
+ let file = env::var("ITSI_LOG_FILE").unwrap_or_else(|_| "app.log".into());
55
+ LogTarget::File(file)
56
+ }
57
+ Ok("both") => {
58
+ let file = env::var("ITSI_LOG_FILE").unwrap_or_else(|_| "app.log".into());
59
+ LogTarget::Both(file)
60
+ }
61
+ _ => LogTarget::Stdout,
62
+ };
63
+ // If ITSI_LOG_ANSI is set, use that; otherwise, use ANSI if stdout is a TTY.
64
+ let use_ansi = env::var("ITSI_LOG_ANSI")
65
+ .map(|s| s == "true")
66
+ .unwrap_or_else(|_| is(Stream::Stdout));
67
+ Self {
68
+ level,
69
+ format,
70
+ target,
71
+ use_ansi,
72
+ }
73
+ }
74
+ }
75
+
76
+ /// Initialize the global tracing subscriber with the default configuration.
14
77
  pub fn init() {
15
- let env_filter = EnvFilter::builder()
16
- .with_env_var("ITSI_LOG")
17
- .try_from_env()
18
- .unwrap_or_else(|_| EnvFilter::new("info"));
19
-
20
- let format = fmt::format()
21
- .compact()
22
- .with_file(false)
23
- .with_level(true)
24
- .with_line_number(false)
25
- .with_source_location(false)
26
- .with_target(false)
27
- .with_thread_ids(false);
28
-
29
- let is_tty = is(Stream::Stdout);
30
-
31
- let subscriber = tracing_subscriber::fmt()
32
- .event_format(format)
33
- .with_env_filter(env_filter);
34
-
35
- if (is_tty && env::var("ITSI_LOG_PLAIN").is_err()) || env::var("ITSI_LOG_ANSI").is_ok() {
36
- subscriber.with_ansi(true).init();
78
+ init_with_config(LogConfig::default());
79
+ }
80
+
81
+ /// Initialize the global tracing subscriber with a given configuration.
82
+ pub fn init_with_config(config: LogConfig) {
83
+ // Build an EnvFilter from the configured level.
84
+ let env_filter = EnvFilter::new(config.level);
85
+
86
+ // Build the formatting layer based on target and format.
87
+ let fmt_layer = match config.target {
88
+ LogTarget::Stdout => match config.format {
89
+ LogFormat::Plain => fmt::layer()
90
+ .compact()
91
+ .with_file(false)
92
+ .with_line_number(false)
93
+ .with_target(false)
94
+ .with_thread_ids(false)
95
+ .with_writer(BoxMakeWriter::new(std::io::stdout))
96
+ .with_ansi(config.use_ansi)
97
+ .boxed(),
98
+ LogFormat::Json => fmt::layer()
99
+ .compact()
100
+ .with_file(false)
101
+ .with_line_number(false)
102
+ .with_target(false)
103
+ .with_thread_ids(false)
104
+ .with_writer(BoxMakeWriter::new(std::io::stdout))
105
+ .with_ansi(config.use_ansi)
106
+ .json()
107
+ .boxed(),
108
+ },
109
+ LogTarget::File(file) => match config.format {
110
+ LogFormat::Plain => fmt::layer()
111
+ .compact()
112
+ .with_file(false)
113
+ .with_line_number(false)
114
+ .with_target(false)
115
+ .with_thread_ids(false)
116
+ .with_writer(BoxMakeWriter::new({
117
+ let file = file.clone();
118
+ move || rolling::daily(".", file.clone())
119
+ }))
120
+ .with_ansi(false)
121
+ .boxed(),
122
+ LogFormat::Json => fmt::layer()
123
+ .compact()
124
+ .with_file(false)
125
+ .with_line_number(false)
126
+ .with_target(false)
127
+ .with_thread_ids(false)
128
+ .with_writer(BoxMakeWriter::new({
129
+ let file = file.clone();
130
+ move || rolling::daily(".", file.clone())
131
+ }))
132
+ .with_ansi(false)
133
+ .json()
134
+ .boxed(),
135
+ },
136
+ LogTarget::Both(file) => {
137
+ // For "Both" target, handle each format separately to avoid type mismatches
138
+ match config.format {
139
+ LogFormat::Plain => {
140
+ let stdout_layer = fmt::layer()
141
+ .compact()
142
+ .with_file(false)
143
+ .with_line_number(false)
144
+ .with_target(false)
145
+ .with_thread_ids(false)
146
+ .with_writer(BoxMakeWriter::new(std::io::stdout))
147
+ .with_ansi(config.use_ansi);
148
+
149
+ let file_layer = fmt::layer()
150
+ .compact()
151
+ .with_file(false)
152
+ .with_line_number(false)
153
+ .with_target(false)
154
+ .with_thread_ids(false)
155
+ .with_writer(BoxMakeWriter::new({
156
+ let file = file.clone();
157
+ move || rolling::daily(".", file.clone())
158
+ }))
159
+ .with_ansi(false);
160
+
161
+ stdout_layer.and_then(file_layer).boxed()
162
+ }
163
+ LogFormat::Json => {
164
+ let stdout_layer = fmt::layer()
165
+ .compact()
166
+ .with_file(false)
167
+ .with_line_number(false)
168
+ .with_target(false)
169
+ .with_thread_ids(false)
170
+ .with_writer(BoxMakeWriter::new(std::io::stdout))
171
+ .with_ansi(config.use_ansi)
172
+ .json();
173
+
174
+ let file_layer = fmt::layer()
175
+ .compact()
176
+ .with_file(false)
177
+ .with_line_number(false)
178
+ .with_target(false)
179
+ .with_thread_ids(false)
180
+ .with_writer(BoxMakeWriter::new({
181
+ let file = file.clone();
182
+ move || rolling::daily(".", file.clone())
183
+ }))
184
+ .with_ansi(false)
185
+ .json();
186
+
187
+ stdout_layer.and_then(file_layer).boxed()
188
+ }
189
+ }
190
+ }
191
+ };
192
+
193
+ // Create a reloadable filter layer so we can update the level at runtime.
194
+ let (filter_layer, handle) = reload::Layer::new(env_filter);
195
+
196
+ // Build the subscriber registry
197
+ let subscriber = tracing_subscriber::registry()
198
+ .with(filter_layer)
199
+ .with(fmt_layer);
200
+
201
+ tracing::subscriber::set_global_default(subscriber)
202
+ .expect("Unable to set global tracing subscriber");
203
+
204
+ RELOAD_HANDLE.set(Mutex::new(Some(handle))).unwrap();
205
+ }
206
+
207
+ /// Change the log level at runtime.
208
+ pub fn set_level(new_level: &str) {
209
+ if let Some(handle) = RELOAD_HANDLE.get().unwrap().lock().unwrap().as_ref() {
210
+ handle
211
+ .modify(|filter| *filter = EnvFilter::new(new_level))
212
+ .expect("Failed to update log level");
37
213
  } else {
38
- subscriber
39
- .fmt_fields(format::JsonFields::default())
40
- .event_format(fmt::format().json())
41
- .init();
214
+ eprintln!("Reload handle not initialized; call init() first.");
42
215
  }
43
216
  }
44
217
 
218
+ /// Run a function silently by temporarily setting a no-op subscriber.
45
219
  pub fn run_silently<F, R>(f: F) -> R
46
220
  where
47
221
  F: FnOnce() -> R,
48
222
  {
49
- // Build a minimal subscriber that filters *everything* out
50
- let no_op_subscriber =
51
- tracing_subscriber::registry().with(fmt::layer().with_filter(LevelFilter::OFF));
52
-
53
- // Turn that subscriber into a `Dispatch`
54
- let no_op_dispatch = tracing::dispatcher::Dispatch::new(no_op_subscriber);
55
-
56
- // Temporarily set `no_op_dispatch` as the *default* within this closure
57
- tracing::dispatcher::with_default(&no_op_dispatch, f)
223
+ let no_op_subscriber = tracing_subscriber::fmt()
224
+ .with_writer(std::io::sink)
225
+ .with_max_level(tracing_subscriber::filter::LevelFilter::OFF)
226
+ .finish();
227
+ let dispatch = tracing::Dispatch::new(no_op_subscriber);
228
+ tracing::dispatcher::with_default(&dispatch, f)
58
229
  }
data/docs/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ # Hugo output
2
+ public/
3
+ resources/
4
+ .hugo_build.lock
5
+
6
+ # Editor
7
+ .vscode/
data/docs/.gitpod.yml ADDED
@@ -0,0 +1,15 @@
1
+ # This configuration file was automatically generated by Gitpod.
2
+ # Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
3
+ # and commit this file to your remote git repository to share the goodness with others.
4
+
5
+ # Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart
6
+
7
+ tasks:
8
+ - name: Install Hugo
9
+ before: brew install hugo
10
+ init: echo "Your version of Hugo is `hugo version`" && hugo mod tidy
11
+ command: hugo server -D -F --baseURL $(gp url 1313) --liveReloadPort=443 --appendPort=false --bind=0.0.0.0 --disableFastRender
12
+
13
+ ports:
14
+ - port: 1313
15
+ onOpen: open-preview
data/docs/Itsi.rb ADDED
@@ -0,0 +1,17 @@
1
+ bind 'http://0.0.0.0:3000'
2
+
3
+ workers 1
4
+
5
+ watch 'Itsi.rb', [%w[bundle exec itsi restart]]
6
+ watch '**/**.md', [%w[hugo build]]
7
+
8
+ location '/' do
9
+ static_assets \
10
+ root_dir: 'public',
11
+ not_found_behavior: { index: '404.html' },
12
+ auto_index: false,
13
+ try_html_extension: true,
14
+ max_file_size_in_memory: 10 * 1024 * 1024,
15
+ max_files_in_memory: 100,
16
+ file_check_interval: 1
17
+ end
@@ -0,0 +1,17 @@
1
+ ---
2
+ title: My Site
3
+ toc: false
4
+ ---
5
+
6
+ This is the landing page.
7
+
8
+ ## Explore
9
+
10
+ {{< cards >}}
11
+ {{< card link="docs" title="Docs" icon="book-open" >}}
12
+ {{< card link="about" title="About" icon="user" >}}
13
+ {{< /cards >}}
14
+
15
+ ## Documentation
16
+
17
+ For more information, visit [Hextra](https://imfing.github.io/hextra).
@@ -0,0 +1,6 @@
1
+ ---
2
+ title: About
3
+ type: about
4
+ ---
5
+
6
+ This is the about page.
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: Documentation
3
+ next: first-page
4
+ ---
5
+
6
+ This is a demo of the theme's documentation layout.
7
+
8
+ ## Hello, World!
9
+
10
+ ```go {filename="main.go"}
11
+ package main
12
+
13
+ import "fmt"
14
+
15
+ func main() {
16
+ fmt.Println("Hello, World!")
17
+ }
18
+ ```
@@ -0,0 +1,9 @@
1
+ ---
2
+ title: Demo Page
3
+ type: docs
4
+ prev: /
5
+ next: docs/folder/
6
+ ---
7
+
8
+ A simple demo page.
9
+
@@ -0,0 +1,10 @@
1
+ ---
2
+ title: Folder
3
+ type: docs
4
+ prev: docs/first-page
5
+ next: docs/folder/leaf
6
+ sidebar:
7
+ open: true
8
+ ---
9
+
10
+ Pages can be organized into folders.
@@ -0,0 +1,7 @@
1
+ ---
2
+ title: Leaf Page
3
+ type: docs
4
+ prev: docs/folder/
5
+ ---
6
+
7
+ This page is under a folder.
data/docs/go.mod ADDED
@@ -0,0 +1,5 @@
1
+ module github.com/imfing/hextra-starter-template
2
+
3
+ go 1.21
4
+
5
+ require github.com/imfing/hextra v0.9.7 // indirect
data/docs/go.sum ADDED
@@ -0,0 +1,2 @@
1
+ github.com/imfing/hextra v0.9.7 h1:Zg5n24us36Bn/S/5mEUPkRW6uwE6vHHEqWSgN0bPXaM=
2
+ github.com/imfing/hextra v0.9.7/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
data/docs/hugo.yaml ADDED
@@ -0,0 +1,77 @@
1
+ # Hugo configuration file
2
+ title: My Site
3
+
4
+ # import hextra as module
5
+ module:
6
+ imports:
7
+ - path: github.com/imfing/hextra
8
+ mounts:
9
+ - source: "../crates"
10
+ target: "content/crates"
11
+ includeFiles: ["*.md", "*/**.md", "**/**.md"]
12
+ - source: "../gems/scheduler/README.md"
13
+ target: "content/gems/_index.md"
14
+ - source: "../gems"
15
+ target: "content/gems"
16
+ includeFiles: ["*.md", "*/*.md"]
17
+ excludeFiles: ["*/tmp/**.md"]
18
+ - source: "content"
19
+ target: "content"
20
+ - source: "static"
21
+ target: "static"
22
+
23
+ markup:
24
+ # allow raw html
25
+ goldmark:
26
+ renderer:
27
+ unsafe: true
28
+
29
+ # enable hextra syntax highlight
30
+ highlight:
31
+ noClasses: false
32
+
33
+ menu:
34
+ main:
35
+ - name: Docs
36
+ pageRef: /docs
37
+ weight: 1
38
+ - name: About
39
+ pageRef: /about
40
+ weight: 2
41
+ - name: Crates
42
+ pageRef: /crates
43
+ weight: 2
44
+ - name: Contact ↗
45
+ url: "https://github.com/imfing"
46
+ weight: 3
47
+ - name: Search
48
+ weight: 4
49
+ params:
50
+ type: search
51
+ - name: GitHub
52
+ weight: 5
53
+ url: "https://github.com/imfing/hextra-starter-template"
54
+ params:
55
+ icon: github
56
+ - name: Twitter
57
+ weight: 6
58
+ url: "https://twitter.com/"
59
+ params:
60
+ icon: x-twitter
61
+
62
+ params:
63
+ navbar:
64
+ displayTitle: true
65
+ displayLogo: false
66
+
67
+ footer:
68
+ displayCopyright: false
69
+ displayPoweredBy: true
70
+
71
+ editURL:
72
+ enable: true
73
+ base: "https://github.com/imfing/hextra-starter-template/edit/main/content"
74
+
75
+ ignoreFiles:
76
+ - "\\.rs$"
77
+ - "\\.rb$"
@@ -0,0 +1,83 @@
1
+ # Example of how to use the Static Assets middleware in Itsi.rb
2
+
3
+ workers 1
4
+ threads 1
5
+ bind 'http://localhost:3000'
6
+
7
+ # Example 1: Using the "alias" behavior (default)
8
+ # With alias behavior, if you access /assets/image.png, it looks for the file at public/assets/image.png
9
+ location '/assets' do
10
+ # Serve static files from the "public/assets" directory
11
+ static_assets root_dir: "public/assets",
12
+ # Default behavior is "alias" - the location pattern is stripped from the path
13
+ # root_is_prefix: false, # This is the default, so we don't need to specify it
14
+ # Only allow certain file extensions
15
+ allowed_extensions: %w[css js jpg jpeg png gif svg ico woff woff2 ttf otf html],
16
+ # Return a 404 error if file is not found
17
+ not_found: 'error',
18
+ # Enable auto-indexing of directories
19
+ auto_index: true,
20
+ # Try adding .html extension to extensionless URLs
21
+ try_html_extension: true,
22
+ # Files under this size are cached in memory
23
+ max_file_size_in_memory: 1024 * 1024, # 1MB
24
+ # Maximum number of files to keep in memory cache
25
+ max_files_in_memory: 1000,
26
+ # Check for file modifications every 5 seconds
27
+ file_check_interval: 5,
28
+ # Add custom headers to all responses
29
+ headers: {
30
+ 'Cache-Control' => 'public, max-age=86400',
31
+ 'X-Content-Type-Options' => 'nosniff'
32
+ }
33
+ end
34
+
35
+ # Example 2: Using the "root" behavior
36
+ # With root behavior, if you access /static/image.png, it looks for the file at public/static/image.png
37
+ location '/static' do
38
+ # Serve static files from the "public" directory
39
+ static_assets root_dir: "public",
40
+ # Use "root" behavior - keep the location pattern as part of the path
41
+ root_is_prefix: true,
42
+ not_found: 'error',
43
+ auto_index: true
44
+ end
45
+
46
+ # Example 3: Serving a Single Page Application (SPA)
47
+ location '/app' do
48
+ static_assets root_dir: "public/app",
49
+ # If file is not found, serve index.html (typical SPA behavior)
50
+ not_found: "index", # equivalent to not_found: { index: "index.html" }
51
+ headers: {
52
+ 'Cache-Control' => 'public, max-age=3600'
53
+ }
54
+ end
55
+
56
+ # Example 4: Using file_server as an alias for static_assets
57
+ location '/public' do
58
+ file_server root_dir: "public",
59
+ auto_index: true,
60
+ not_found: "fallthrough"
61
+ end
62
+
63
+ # Example of a restricted files area
64
+ location '/downloads' do
65
+ # Basic authentication before serving files
66
+ auth_basic realm: 'Downloads Area', credential_pairs: { 'user' => 'password' }
67
+
68
+ # Serve files after authentication
69
+ static_assets root_dir: 'private/downloads',
70
+ # Only allow PDF files
71
+ allowed_extensions: ['pdf'],
72
+ # If file is not found, fall through to the next middleware
73
+ not_found: 'fallthrough'
74
+ end
75
+
76
+ # Example of redirecting to another location if file is not found
77
+ location '/docs' do
78
+ static_assets root_dir: 'documentation',
79
+ # Redirect to documentation homepage if file not found
80
+ not_found: 'redirect', # equivalent to not_found: { redirect: "/docs/index.html" }
81
+ # Don't cache these files in memory
82
+ max_file_size_in_memory: 0
83
+ end
data/gems/_index.md ADDED
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: Gems
3
+ next: first-page
4
+ ---
5
+
6
+ Gems
7
+
8
+ ## Hello, World!
9
+
10
+ ```go {filename="main.go"}
11
+ package main
12
+
13
+ import "fmt"
14
+
15
+ func main() {
16
+ fmt.Println("Hello, World!")
17
+ }
18
+ ```
@@ -1,3 +1,10 @@
1
+ ---
2
+ title: Code of Conduct
3
+ type: docs
4
+ next: docs/
5
+ prev: docs/folder/
6
+ ---
7
+
1
8
  # Contributor Covenant Code of Conduct
2
9
 
3
10
  ## Our Pledge