itsi 0.1.9 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1542 -43
  3. data/Itsi.rb +125 -0
  4. data/Rakefile +8 -4
  5. data/crates/itsi_error/src/lib.rs +9 -0
  6. data/crates/itsi_rb_helpers/Cargo.toml +1 -0
  7. data/crates/itsi_rb_helpers/src/heap_value.rs +18 -0
  8. data/crates/itsi_rb_helpers/src/lib.rs +59 -9
  9. data/crates/itsi_server/Cargo.toml +70 -28
  10. data/crates/itsi_server/src/lib.rs +80 -80
  11. data/crates/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
  12. data/{gems/server/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs → crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs} +22 -3
  13. data/crates/itsi_server/src/ruby_types/itsi_grpc_request.rs +147 -0
  14. data/crates/itsi_server/src/ruby_types/itsi_grpc_response.rs +19 -0
  15. data/crates/itsi_server/src/ruby_types/itsi_grpc_stream/mod.rs +216 -0
  16. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +282 -0
  17. data/crates/itsi_server/src/{response/itsi_response.rs → ruby_types/itsi_http_response.rs} +72 -41
  18. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
  19. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +355 -0
  20. data/crates/itsi_server/src/ruby_types/itsi_server.rs +82 -0
  21. data/crates/itsi_server/src/ruby_types/mod.rs +55 -0
  22. data/crates/itsi_server/src/server/bind.rs +29 -17
  23. data/crates/itsi_server/src/server/byte_frame.rs +32 -0
  24. data/crates/itsi_server/src/server/cache_store.rs +74 -0
  25. data/crates/itsi_server/src/server/itsi_service.rs +172 -0
  26. data/crates/itsi_server/src/server/lifecycle_event.rs +3 -0
  27. data/crates/itsi_server/src/server/listener.rs +111 -11
  28. data/crates/itsi_server/src/server/middleware_stack/middleware.rs +153 -0
  29. data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +47 -0
  30. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +58 -0
  31. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +82 -0
  32. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +321 -0
  33. data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +139 -0
  34. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +300 -0
  35. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +287 -0
  36. data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +48 -0
  37. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +127 -0
  38. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +191 -0
  39. data/crates/itsi_server/src/server/middleware_stack/middlewares/grpc_service.rs +72 -0
  40. data/crates/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +85 -0
  41. data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +195 -0
  42. data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
  43. data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +82 -0
  44. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +216 -0
  45. data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +124 -0
  46. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
  47. data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +43 -0
  48. data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +34 -0
  49. data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +93 -0
  50. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +162 -0
  51. data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +158 -0
  52. data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
  53. data/crates/itsi_server/src/server/middleware_stack/mod.rs +315 -0
  54. data/crates/itsi_server/src/server/mod.rs +8 -1
  55. data/crates/itsi_server/src/server/process_worker.rs +44 -11
  56. data/crates/itsi_server/src/server/rate_limiter.rs +565 -0
  57. data/crates/itsi_server/src/server/request_job.rs +11 -0
  58. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +129 -46
  59. data/crates/itsi_server/src/server/serve_strategy/mod.rs +9 -6
  60. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +325 -167
  61. data/crates/itsi_server/src/server/signal.rs +20 -4
  62. data/crates/itsi_server/src/server/static_file_server.rs +984 -0
  63. data/crates/itsi_server/src/server/thread_worker.rs +165 -88
  64. data/crates/itsi_server/src/server/tls.rs +1 -1
  65. data/crates/itsi_server/src/server/types.rs +43 -0
  66. data/crates/itsi_server/test.md +14 -0
  67. data/crates/itsi_tracing/Cargo.toml +1 -0
  68. data/crates/itsi_tracing/src/lib.rs +216 -45
  69. data/docs/.gitignore +7 -0
  70. data/docs/.gitpod.yml +15 -0
  71. data/docs/Itsi.rb +17 -0
  72. data/docs/content/_index.md +17 -0
  73. data/docs/content/about.md +6 -0
  74. data/docs/content/docs/_index.md +18 -0
  75. data/docs/content/docs/first-page.md +9 -0
  76. data/docs/content/docs/folder/_index.md +10 -0
  77. data/docs/content/docs/folder/leaf.md +7 -0
  78. data/docs/go.mod +5 -0
  79. data/docs/go.sum +2 -0
  80. data/docs/hugo.yaml +77 -0
  81. data/examples/static_assets_example.rb +83 -0
  82. data/gems/_index.md +18 -0
  83. data/gems/scheduler/CODE_OF_CONDUCT.md +7 -0
  84. data/gems/scheduler/Cargo.lock +75 -14
  85. data/gems/scheduler/README.md +5 -0
  86. data/gems/scheduler/_index.md +7 -0
  87. data/gems/scheduler/itsi-scheduler.gemspec +4 -1
  88. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  89. data/gems/scheduler/lib/itsi/scheduler.rb +2 -2
  90. data/gems/scheduler/test/test_file_io.rb +0 -1
  91. data/gems/scheduler/test/test_itsi_scheduler.rb +1 -1
  92. data/gems/server/CHANGELOG.md +5 -0
  93. data/gems/server/CODE_OF_CONDUCT.md +7 -0
  94. data/gems/server/Cargo.lock +1543 -43
  95. data/gems/server/README.md +4 -0
  96. data/gems/server/_index.md +6 -0
  97. data/gems/server/exe/itsi +46 -57
  98. data/gems/server/itsi-server.gemspec +3 -2
  99. data/gems/server/lib/itsi/{request.rb → http_request.rb} +29 -5
  100. data/gems/server/lib/itsi/http_response.rb +39 -0
  101. data/gems/server/lib/itsi/server/Itsi.rb +119 -0
  102. data/gems/server/lib/itsi/server/config/dsl.rb +506 -0
  103. data/gems/server/lib/itsi/server/config.rb +131 -0
  104. data/gems/server/lib/itsi/server/default_app/default_app.rb +38 -0
  105. data/gems/server/lib/itsi/server/grpc_interface.rb +213 -0
  106. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +9 -6
  107. data/gems/server/lib/itsi/server/rack_interface.rb +24 -9
  108. data/gems/server/lib/itsi/server/scheduler_interface.rb +1 -1
  109. data/gems/server/lib/itsi/server/scheduler_mode.rb +4 -0
  110. data/gems/server/lib/itsi/server/signal_trap.rb +6 -1
  111. data/gems/server/lib/itsi/server/version.rb +1 -1
  112. data/gems/server/lib/itsi/server.rb +75 -60
  113. data/gems/server/lib/itsi/standard_headers.rb +86 -0
  114. data/gems/server/test/helpers/test_helper.rb +14 -12
  115. data/gems/server/test/test_itsi_server.rb +21 -2
  116. data/lib/itsi/version.rb +1 -1
  117. data/sandbox/itsi_file/Gemfile +11 -0
  118. data/sandbox/itsi_file/Gemfile.lock +69 -0
  119. data/sandbox/itsi_file/Itsi.rb +276 -0
  120. data/sandbox/itsi_file/error.html +2 -0
  121. data/sandbox/itsi_file/organisations_controller.rb +20 -0
  122. data/sandbox/itsi_file/public/assets/image.png +0 -0
  123. data/sandbox/itsi_file/public/assets/index.html +1 -0
  124. data/sandbox/itsi_sandbox_async/Gemfile +1 -1
  125. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +2 -2
  126. data/sandbox/itsi_sandbox_rack/Gemfile.lock +2 -2
  127. data/sandbox/itsi_sandbox_rack/config.ru +2 -15
  128. data/sandbox/itsi_sandbox_rails/.dockerignore +2 -5
  129. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +1 -1
  130. data/sandbox/itsi_sandbox_rails/.gitignore +2 -1
  131. data/sandbox/itsi_sandbox_rails/Dockerfile +6 -9
  132. data/sandbox/itsi_sandbox_rails/Gemfile +16 -22
  133. data/sandbox/itsi_sandbox_rails/Gemfile.lock +100 -225
  134. data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +4 -0
  135. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +11 -6
  136. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +4 -0
  137. data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +4 -0
  138. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +7 -8
  139. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -3
  140. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +2 -7
  141. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +3 -4
  142. data/sandbox/itsi_sandbox_rails/bin/setup +8 -5
  143. data/sandbox/itsi_sandbox_rails/config/application.rb +1 -35
  144. data/sandbox/itsi_sandbox_rails/config/cable.yml +3 -10
  145. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -1
  146. data/sandbox/itsi_sandbox_rails/config/database.yml +9 -19
  147. data/sandbox/itsi_sandbox_rails/config/environment.rb +1 -1
  148. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +21 -12
  149. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +49 -34
  150. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +19 -5
  151. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +5 -0
  152. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +1 -1
  153. data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +13 -0
  154. data/sandbox/itsi_sandbox_rails/config/puma.rb +2 -9
  155. data/sandbox/itsi_sandbox_rails/config.ru +0 -1
  156. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +1 -1
  157. data/sandbox/itsi_sandbox_rails/db/schema.rb +2 -2
  158. data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
  159. data/sandbox/itsi_sandbox_rails/public/404.html +66 -113
  160. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +65 -113
  161. data/sandbox/itsi_sandbox_rails/public/422.html +66 -113
  162. data/sandbox/itsi_sandbox_rails/public/500.html +65 -113
  163. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  164. data/sandbox/itsi_sandbox_rails/public/icon.svg +2 -2
  165. data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +13 -0
  166. data/sandbox/itsi_sandbox_roda/Gemfile.lock +3 -10
  167. data/tasks.txt +72 -12
  168. metadata +94 -139
  169. data/crates/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  170. data/crates/itsi_server/src/body_proxy/mod.rs +0 -2
  171. data/crates/itsi_server/src/request/itsi_request.rs +0 -305
  172. data/crates/itsi_server/src/request/mod.rs +0 -1
  173. data/crates/itsi_server/src/response/mod.rs +0 -1
  174. data/crates/itsi_server/src/server/itsi_server.rs +0 -294
  175. data/gems/scheduler/ext/itsi_error/Cargo.lock +0 -368
  176. data/gems/scheduler/ext/itsi_error/Cargo.toml +0 -11
  177. data/gems/scheduler/ext/itsi_error/src/from.rs +0 -68
  178. data/gems/scheduler/ext/itsi_error/src/lib.rs +0 -24
  179. data/gems/scheduler/ext/itsi_instrument_entry/Cargo.toml +0 -15
  180. data/gems/scheduler/ext/itsi_instrument_entry/src/lib.rs +0 -31
  181. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.lock +0 -355
  182. data/gems/scheduler/ext/itsi_rb_helpers/Cargo.toml +0 -10
  183. data/gems/scheduler/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  184. data/gems/scheduler/ext/itsi_rb_helpers/src/lib.rs +0 -178
  185. data/gems/scheduler/ext/itsi_scheduler/Cargo.toml +0 -24
  186. data/gems/scheduler/ext/itsi_scheduler/extconf.rb +0 -6
  187. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  188. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  189. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  190. data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  191. data/gems/scheduler/ext/itsi_scheduler/src/lib.rs +0 -38
  192. data/gems/scheduler/ext/itsi_server/Cargo.lock +0 -2956
  193. data/gems/scheduler/ext/itsi_server/Cargo.toml +0 -47
  194. data/gems/scheduler/ext/itsi_server/extconf.rb +0 -6
  195. data/gems/scheduler/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  196. data/gems/scheduler/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
  197. data/gems/scheduler/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  198. data/gems/scheduler/ext/itsi_server/src/env.rs +0 -43
  199. data/gems/scheduler/ext/itsi_server/src/lib.rs +0 -112
  200. data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +0 -305
  201. data/gems/scheduler/ext/itsi_server/src/request/mod.rs +0 -1
  202. data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +0 -357
  203. data/gems/scheduler/ext/itsi_server/src/response/mod.rs +0 -1
  204. data/gems/scheduler/ext/itsi_server/src/server/bind.rs +0 -170
  205. data/gems/scheduler/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  206. data/gems/scheduler/ext/itsi_server/src/server/io_stream.rs +0 -104
  207. data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +0 -294
  208. data/gems/scheduler/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  209. data/gems/scheduler/ext/itsi_server/src/server/listener.rs +0 -318
  210. data/gems/scheduler/ext/itsi_server/src/server/mod.rs +0 -11
  211. data/gems/scheduler/ext/itsi_server/src/server/process_worker.rs +0 -196
  212. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -254
  213. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  214. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -263
  215. data/gems/scheduler/ext/itsi_server/src/server/signal.rs +0 -77
  216. data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +0 -367
  217. data/gems/scheduler/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  218. data/gems/scheduler/ext/itsi_server/src/server/tls.rs +0 -265
  219. data/gems/scheduler/ext/itsi_tracing/Cargo.lock +0 -274
  220. data/gems/scheduler/ext/itsi_tracing/Cargo.toml +0 -16
  221. data/gems/scheduler/ext/itsi_tracing/src/lib.rs +0 -58
  222. data/gems/server/ext/itsi_error/Cargo.lock +0 -368
  223. data/gems/server/ext/itsi_error/Cargo.toml +0 -11
  224. data/gems/server/ext/itsi_error/src/from.rs +0 -68
  225. data/gems/server/ext/itsi_error/src/lib.rs +0 -24
  226. data/gems/server/ext/itsi_instrument_entry/Cargo.toml +0 -15
  227. data/gems/server/ext/itsi_instrument_entry/src/lib.rs +0 -31
  228. data/gems/server/ext/itsi_rb_helpers/Cargo.lock +0 -355
  229. data/gems/server/ext/itsi_rb_helpers/Cargo.toml +0 -10
  230. data/gems/server/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
  231. data/gems/server/ext/itsi_rb_helpers/src/lib.rs +0 -178
  232. data/gems/server/ext/itsi_scheduler/Cargo.toml +0 -24
  233. data/gems/server/ext/itsi_scheduler/extconf.rb +0 -6
  234. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
  235. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
  236. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
  237. data/gems/server/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
  238. data/gems/server/ext/itsi_scheduler/src/lib.rs +0 -38
  239. data/gems/server/ext/itsi_server/Cargo.lock +0 -2956
  240. data/gems/server/ext/itsi_server/Cargo.toml +0 -47
  241. data/gems/server/ext/itsi_server/extconf.rb +0 -6
  242. data/gems/server/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
  243. data/gems/server/ext/itsi_server/src/body_proxy/mod.rs +0 -2
  244. data/gems/server/ext/itsi_server/src/env.rs +0 -43
  245. data/gems/server/ext/itsi_server/src/lib.rs +0 -112
  246. data/gems/server/ext/itsi_server/src/request/itsi_request.rs +0 -305
  247. data/gems/server/ext/itsi_server/src/request/mod.rs +0 -1
  248. data/gems/server/ext/itsi_server/src/response/itsi_response.rs +0 -357
  249. data/gems/server/ext/itsi_server/src/response/mod.rs +0 -1
  250. data/gems/server/ext/itsi_server/src/server/bind.rs +0 -170
  251. data/gems/server/ext/itsi_server/src/server/bind_protocol.rs +0 -37
  252. data/gems/server/ext/itsi_server/src/server/io_stream.rs +0 -104
  253. data/gems/server/ext/itsi_server/src/server/itsi_server.rs +0 -294
  254. data/gems/server/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
  255. data/gems/server/ext/itsi_server/src/server/listener.rs +0 -318
  256. data/gems/server/ext/itsi_server/src/server/mod.rs +0 -11
  257. data/gems/server/ext/itsi_server/src/server/process_worker.rs +0 -196
  258. data/gems/server/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -254
  259. data/gems/server/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
  260. data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -263
  261. data/gems/server/ext/itsi_server/src/server/signal.rs +0 -77
  262. data/gems/server/ext/itsi_server/src/server/thread_worker.rs +0 -367
  263. data/gems/server/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
  264. data/gems/server/ext/itsi_server/src/server/tls.rs +0 -265
  265. data/gems/server/ext/itsi_tracing/Cargo.lock +0 -274
  266. data/gems/server/ext/itsi_tracing/Cargo.toml +0 -16
  267. data/gems/server/ext/itsi_tracing/src/lib.rs +0 -58
  268. data/gems/server/lib/itsi/stream_io.rb +0 -38
  269. data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +0 -3
  270. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +0 -3
  271. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +0 -14
  272. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +0 -3
  273. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +0 -3
  274. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +0 -51
  275. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +0 -47
  276. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +0 -109
  277. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +0 -3
  278. data/sandbox/itsi_sandbox_rails/.kamal/secrets +0 -17
  279. data/sandbox/itsi_sandbox_rails/bin/dev +0 -2
  280. data/sandbox/itsi_sandbox_rails/bin/jobs +0 -6
  281. data/sandbox/itsi_sandbox_rails/bin/kamal +0 -27
  282. data/sandbox/itsi_sandbox_rails/bin/thrust +0 -5
  283. data/sandbox/itsi_sandbox_rails/config/cache.yml +0 -16
  284. data/sandbox/itsi_sandbox_rails/config/deploy.yml +0 -116
  285. data/sandbox/itsi_sandbox_rails/config/queue.yml +0 -18
  286. data/sandbox/itsi_sandbox_rails/config/recurring.yml +0 -10
  287. data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +0 -11
  288. data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +0 -14
  289. data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +0 -129
  290. data/sandbox/itsi_sandbox_rails/public/400.html +0 -114
  291. data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +0 -9
  292. data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +0 -7
  293. /data/{sandbox/itsi_sandbox_rails/script/.keep → crates/_index.md} +0 -0
  294. /data/gems/server/lib/itsi/{index.html → server/default_app/index.html} +0 -0
@@ -1,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