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,47 +0,0 @@
1
- [package]
2
- name = "itsi-server"
3
- version = "0.1.0"
4
- edition = "2021"
5
- authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
- license = "MIT"
7
- publish = false
8
-
9
- [lib]
10
- crate-type = ["cdylib"]
11
-
12
- [dependencies]
13
- magnus = { version = "0.7.1", features = ["bytes", "rb-sys"] }
14
- itsi_tracing = { path = "../itsi_tracing" }
15
- itsi_rb_helpers = { path = "../itsi_rb_helpers" }
16
- itsi_error = { path = "../itsi_error" }
17
- socket2 = "0.5.8"
18
- parking_lot = "0.12.3"
19
- rustls-pemfile = "2.2.0"
20
- tokio-rustls = "0.26.2"
21
- bytes = "1.3"
22
- tokio-rustls-acme = "0.6.0"
23
- rcgen = { version = "0.13.2", features = ["x509-parser", "pem"] }
24
- base64 = "0.22.1"
25
- http-body-util = "0.1.2"
26
- hyper = { version = "1.5.0", features = ["full", "server", "http1", "http2"] }
27
- tokio = { version = "1", features = ["full"] }
28
- hyper-util = { version = "0.1.10", features = ["full"] }
29
- derive_more = { version = "2.0.1", features = ["debug"] }
30
- http = "1.3.1"
31
- crossbeam = "0.8.4"
32
- futures = "0.3.31"
33
- nix = { version = "0.29.0", features = ["socket", "uio", "signal"] }
34
- pin-project = "1.1.9"
35
- rb-sys = "0.9.111"
36
- tracing = "0.1.41"
37
- tokio-util = "0.7.13"
38
- tokio-stream = "0.1.17"
39
- httparse = "1.10.1"
40
- async-channel = "2.3.1"
41
- tempfile = "3.18.0"
42
- sysinfo = "0.33.1"
43
- rustls = "0.23.23"
44
- fs2 = "0.4.3"
45
- ring = "0.17.14"
46
- async-trait = "0.1.87"
47
- dirs = "6.0.0"
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "mkmf"
4
- require "rb_sys/mkmf"
5
-
6
- create_rust_makefile("itsi/server/itsi_server")
@@ -1,104 +0,0 @@
1
- use bytes::Bytes;
2
- use magnus::{IntoValue, Ruby, Value};
3
- use std::io::{Result as IoResult, Write};
4
- use std::path::PathBuf;
5
- use tempfile::NamedTempFile;
6
-
7
- const THRESHOLD: usize = 1024 * 1024; // 1 MB
8
-
9
- /// An container that holds data in memory if it’s small, or in a temporary file on disk if it exceeds THRESHOLD.
10
- /// Used for providing Rack input data.
11
- pub enum BigBytes {
12
- InMemory(Vec<u8>),
13
- OnDisk(NamedTempFile),
14
- }
15
-
16
- /// The result type for reading the contents of a `BigBytes` value.
17
- pub enum BigBytesReadResult {
18
- /// When the data is stored in memory, returns the cached bytes.
19
- InMemory(Vec<u8>),
20
- /// When the data is stored on disk, returns the path to the temporary file.
21
- OnDisk(PathBuf),
22
- }
23
-
24
- impl BigBytes {
25
- /// Creates a new, empty BigBytes instance (initially in memory).
26
- pub fn new() -> Self {
27
- BigBytes::InMemory(Vec::new())
28
- }
29
-
30
- /// Reads the entire contents that have been written.
31
- ///
32
- /// - If stored in memory, returns a clone of the bytes.
33
- /// - If stored on disk, returns the file path of the temporary file.
34
- pub fn read(&self) -> IoResult<BigBytesReadResult> {
35
- match self {
36
- BigBytes::InMemory(vec) => Ok(BigBytesReadResult::InMemory(vec.clone())),
37
- BigBytes::OnDisk(temp_file) => {
38
- // Flush to be safe, then return the file path.
39
- temp_file.as_file().sync_all()?;
40
- Ok(BigBytesReadResult::OnDisk(temp_file.path().to_path_buf()))
41
- }
42
- }
43
- }
44
-
45
- pub fn as_value(&self) -> Value {
46
- match self {
47
- BigBytes::InMemory(bytes) => {
48
- let bytes = Bytes::from(bytes.to_owned());
49
- bytes.into_value()
50
- }
51
- BigBytes::OnDisk(path) => {
52
- let ruby = Ruby::get().unwrap();
53
- let rarray = ruby.ary_new();
54
- rarray.push(path.path().to_str().unwrap().into_value()).ok();
55
- rarray.into_value()
56
- }
57
- }
58
- }
59
- }
60
-
61
- impl Drop for BigBytes {
62
- fn drop(&mut self) {
63
- match self {
64
- BigBytes::InMemory(_) => {}
65
- BigBytes::OnDisk(path) => {
66
- let _ = std::fs::remove_file(path);
67
- }
68
- }
69
- }
70
- }
71
-
72
- impl Default for BigBytes {
73
- fn default() -> Self {
74
- Self::new()
75
- }
76
- }
77
-
78
- impl Write for BigBytes {
79
- fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
80
- match self {
81
- BigBytes::InMemory(vec) => {
82
- // Check if writing the new bytes would exceed the threshold.
83
- if vec.len() + buf.len() > THRESHOLD {
84
- let mut tmp = NamedTempFile::new()?;
85
- tmp.write_all(vec)?;
86
- tmp.write_all(buf)?;
87
- *self = BigBytes::OnDisk(tmp);
88
- Ok(buf.len())
89
- } else {
90
- vec.extend_from_slice(buf);
91
- Ok(buf.len())
92
- }
93
- }
94
- BigBytes::OnDisk(tmp_file) => tmp_file.write(buf),
95
- }
96
- }
97
-
98
- fn flush(&mut self) -> IoResult<()> {
99
- match self {
100
- BigBytes::InMemory(_) => Ok(()),
101
- BigBytes::OnDisk(tmp_file) => tmp_file.flush(),
102
- }
103
- }
104
- }
@@ -1,2 +0,0 @@
1
- pub mod big_bytes;
2
- pub mod itsi_body_proxy;
@@ -1,43 +0,0 @@
1
- use std::{
2
- env::{var, VarError},
3
- path::PathBuf,
4
- sync::LazyLock,
5
- };
6
-
7
- type StringVar = LazyLock<String>;
8
- type MaybeStringVar = LazyLock<Result<String, VarError>>;
9
- type PathVar = LazyLock<PathBuf>;
10
-
11
- /// ACME Configuration for auto-generating production certificates
12
- /// *ITSI_ACME_CACHE_DIR* - Directory to store cached certificates
13
- /// so that these are not regenerated every time the server starts
14
- pub static ITSI_ACME_CACHE_DIR: StringVar = LazyLock::new(|| {
15
- var("ITSI_ACME_CACHE_DIR").unwrap_or_else(|_| "./.rustls_acme_cache".to_string())
16
- });
17
-
18
- /// *ITSI_ACME_CONTACT_EMAIL* - Contact Email address to provide to ACME server during certificate renewal
19
- pub static ITSI_ACME_CONTACT_EMAIL: MaybeStringVar =
20
- LazyLock::new(|| var("ITSI_ACME_CONTACT_EMAIL"));
21
-
22
- /// *ITSI_ACME_CA_PEM_PATH* - Optional CA Pem path, used for testing with non-trusted CAs for certifcate generation.
23
- pub static ITSI_ACME_CA_PEM_PATH: MaybeStringVar = LazyLock::new(|| var("ITSI_ACME_CA_PEM_PATH"));
24
-
25
- /// *ITSI_ACME_DIRECTORY_URL* - Directory URL to use for ACME certificate generation.
26
- pub static ITSI_ACME_DIRECTORY_URL: StringVar = LazyLock::new(|| {
27
- var("ITSI_ACME_DIRECTORY_URL")
28
- .unwrap_or_else(|_| "https://acme-v02.api.letsencrypt.org/directory".to_string())
29
- });
30
-
31
- /// *ITSI_ACME_LOCK_FILE_NAME* - Name of the lock file used to prevent concurrent certificate generation.
32
- pub static ITSI_ACME_LOCK_FILE_NAME: StringVar =
33
- LazyLock::new(|| var("ITSI_ACME_LOCK_FILE_NAME").unwrap_or(".acme.lock".to_string()));
34
-
35
- pub static ITSI_LOCAL_CA_DIR: PathVar = LazyLock::new(|| {
36
- var("ITSI_LOCAL_CA_DIR")
37
- .map(PathBuf::from)
38
- .unwrap_or_else(|_| {
39
- dirs::home_dir()
40
- .expect("Failed to find HOME directory when initializing ITSI_LOCAL_CA_DIR")
41
- .join(".itsi")
42
- })
43
- });
@@ -1,112 +0,0 @@
1
- use body_proxy::itsi_body_proxy::ItsiBodyProxy;
2
- use magnus::{error::Result, function, method, value::Lazy, Module, Object, RClass, RModule, Ruby};
3
- use request::itsi_request::ItsiRequest;
4
- use response::itsi_response::ItsiResponse;
5
- use server::{itsi_server::Server, signal::reset_signal_handlers};
6
- use tracing::*;
7
-
8
- pub mod body_proxy;
9
- pub mod env;
10
- pub mod request;
11
- pub mod response;
12
- pub mod server;
13
-
14
- pub static ITSI_MODULE: Lazy<RModule> = Lazy::new(|ruby| ruby.define_module("Itsi").unwrap());
15
- pub static ITSI_SERVER: Lazy<RClass> = Lazy::new(|ruby| {
16
- ruby.get_inner(&ITSI_MODULE)
17
- .define_class("Server", ruby.class_object())
18
- .unwrap()
19
- });
20
- pub static ITSI_REQUEST: Lazy<RClass> = Lazy::new(|ruby| {
21
- ruby.get_inner(&ITSI_MODULE)
22
- .define_class("Request", ruby.class_object())
23
- .unwrap()
24
- });
25
-
26
- pub static ITSI_RESPONSE: Lazy<RClass> = Lazy::new(|ruby| {
27
- ruby.get_inner(&ITSI_MODULE)
28
- .define_class("Response", ruby.class_object())
29
- .unwrap()
30
- });
31
-
32
- pub static ITSI_BODY_PROXY: Lazy<RClass> = Lazy::new(|ruby| {
33
- ruby.get_inner(&ITSI_MODULE)
34
- .define_class("BodyProxy", ruby.class_object())
35
- .unwrap()
36
- });
37
-
38
- pub static ITSI_SERVER_SCHEDULER_TASK: Lazy<RClass> = Lazy::new(|ruby| {
39
- ruby.get_inner(&ITSI_MODULE)
40
- .define_class("ServerSchedulerTask", ruby.class_object())
41
- .unwrap()
42
- });
43
-
44
- pub fn log_debug(msg: String) {
45
- debug!(msg);
46
- }
47
- pub fn log_info(msg: String) {
48
- info!(msg);
49
- }
50
- pub fn log_warn(msg: String) {
51
- warn!(msg);
52
- }
53
- pub fn log_error(msg: String) {
54
- error!(msg);
55
- }
56
-
57
- #[magnus::init]
58
- fn init(ruby: &Ruby) -> Result<()> {
59
- itsi_tracing::init();
60
- rustls::crypto::aws_lc_rs::default_provider()
61
- .install_default()
62
- .ok();
63
-
64
- let itsi = ruby.get_inner(&ITSI_MODULE);
65
- itsi.define_singleton_method("log_debug", function!(log_debug, 1))?;
66
- itsi.define_singleton_method("log_info", function!(log_info, 1))?;
67
- itsi.define_singleton_method("log_warn", function!(log_warn, 1))?;
68
- itsi.define_singleton_method("log_error", function!(log_error, 1))?;
69
-
70
- let server = ruby.get_inner(&ITSI_SERVER);
71
- server.define_singleton_method("new", function!(Server::new, -1))?;
72
- server.define_singleton_method("reset_signal_handlers", function!(reset_signal_handlers, 0))?;
73
- server.define_method("start", method!(Server::start, 0))?;
74
- server.define_method("stop", method!(Server::stop, 0))?;
75
-
76
- let request = ruby.get_inner(&ITSI_REQUEST);
77
- request.define_method("path", method!(ItsiRequest::path, 0))?;
78
- request.define_method("script_name", method!(ItsiRequest::script_name, 0))?;
79
- request.define_method("query_string", method!(ItsiRequest::query_string, 0))?;
80
- request.define_method("method", method!(ItsiRequest::method, 0))?;
81
- request.define_method("version", method!(ItsiRequest::version, 0))?;
82
- request.define_method("rack_protocol", method!(ItsiRequest::rack_protocol, 0))?;
83
- request.define_method("host", method!(ItsiRequest::host, 0))?;
84
- request.define_method("headers", method!(ItsiRequest::headers, 0))?;
85
- request.define_method("scheme", method!(ItsiRequest::scheme, 0))?;
86
- request.define_method("remote_addr", method!(ItsiRequest::remote_addr, 0))?;
87
- request.define_method("port", method!(ItsiRequest::port, 0))?;
88
- request.define_method("body", method!(ItsiRequest::body, 0))?;
89
- request.define_method("response", method!(ItsiRequest::response, 0))?;
90
- request.define_method("json?", method!(ItsiRequest::is_json, 0))?;
91
- request.define_method("html?", method!(ItsiRequest::is_html, 0))?;
92
-
93
- let body_proxy = ruby.get_inner(&ITSI_BODY_PROXY);
94
- body_proxy.define_method("gets", method!(ItsiBodyProxy::gets, 0))?;
95
- body_proxy.define_method("each", method!(ItsiBodyProxy::each, 0))?;
96
- body_proxy.define_method("read", method!(ItsiBodyProxy::read, -1))?;
97
- body_proxy.define_method("close", method!(ItsiBodyProxy::close, 0))?;
98
-
99
- let response = ruby.get_inner(&ITSI_RESPONSE);
100
- response.define_method("add_header", method!(ItsiResponse::add_header, 2))?;
101
- response.define_method("status=", method!(ItsiResponse::set_status, 1))?;
102
- response.define_method("send_frame", method!(ItsiResponse::send_frame, 1))?;
103
- response.define_method("send_and_close", method!(ItsiResponse::send_and_close, 1))?;
104
- response.define_method("close_write", method!(ItsiResponse::close_write, 0))?;
105
- response.define_method("close_read", method!(ItsiResponse::close_read, 0))?;
106
- response.define_method("close", method!(ItsiResponse::close, 0))?;
107
- response.define_method("hijack", method!(ItsiResponse::hijack, 1))?;
108
- response.define_method("json?", method!(ItsiResponse::is_json, 0))?;
109
- response.define_method("html?", method!(ItsiResponse::is_html, 0))?;
110
-
111
- Ok(())
112
- }
@@ -1,305 +0,0 @@
1
- use crate::{
2
- body_proxy::{
3
- big_bytes::BigBytes,
4
- itsi_body_proxy::{ItsiBody, ItsiBodyProxy},
5
- },
6
- response::itsi_response::ItsiResponse,
7
- server::{
8
- itsi_server::{RequestJob, Server},
9
- listener::{ListenerInfo, SockAddr},
10
- serve_strategy::single_mode::RunningPhase,
11
- },
12
- };
13
- use bytes::Bytes;
14
- use derive_more::Debug;
15
- use futures::StreamExt;
16
- use http::{request::Parts, HeaderValue, Response, StatusCode};
17
- use http_body_util::{combinators::BoxBody, BodyExt, Empty};
18
- use hyper::{body::Incoming, Request};
19
- use itsi_error::from::CLIENT_CONNECTION_CLOSED;
20
- use itsi_tracing::{debug, error};
21
- use magnus::{
22
- error::{ErrorType, Result as MagnusResult},
23
- Error,
24
- };
25
- use magnus::{
26
- value::{LazyId, Opaque, ReprValue},
27
- RClass, Ruby, Value,
28
- };
29
- use std::{convert::Infallible, fmt, io::Write, sync::Arc, time::Instant};
30
- use tokio::sync::{
31
- mpsc::{self},
32
- watch,
33
- };
34
- static ID_CALL: LazyId = LazyId::new("call");
35
- static ID_MESSAGE: LazyId = LazyId::new("message");
36
- static ID_BACKTRACE: LazyId = LazyId::new("backtrace");
37
-
38
- #[derive(Debug)]
39
- #[magnus::wrap(class = "Itsi::Request", free_immediately, size)]
40
- pub struct ItsiRequest {
41
- pub parts: Parts,
42
- #[debug(skip)]
43
- pub body: ItsiBody,
44
- pub remote_addr: String,
45
- pub version: String,
46
- #[debug(skip)]
47
- pub(crate) listener: Arc<ListenerInfo>,
48
- #[debug(skip)]
49
- pub server: Arc<Server>,
50
- pub response: ItsiResponse,
51
- pub start: Instant,
52
- pub content_type: String,
53
- }
54
-
55
- impl fmt::Display for ItsiRequest {
56
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57
- write!(
58
- f,
59
- "{} {} {}",
60
- self.version().unwrap(),
61
- self.method().unwrap(),
62
- self.path().unwrap()
63
- )
64
- }
65
- }
66
-
67
- impl ItsiRequest {
68
- pub fn is_connection_closed_err(ruby: &Ruby, err: &Error) -> bool {
69
- match err.error_type() {
70
- ErrorType::Jump(_) => false,
71
- ErrorType::Error(_, _) => false,
72
- ErrorType::Exception(exception) => {
73
- exception.is_kind_of(ruby.exception_eof_error())
74
- && err
75
- .value()
76
- .map(|v| {
77
- v.funcall::<_, _, String>(*ID_MESSAGE, ())
78
- .unwrap_or("".to_string())
79
- .eq(CLIENT_CONNECTION_CLOSED)
80
- })
81
- .unwrap_or(false)
82
- }
83
- }
84
- }
85
-
86
- pub fn is_json(&self) -> bool {
87
- self.content_type.eq("application/json")
88
- }
89
-
90
- pub fn is_html(&self) -> bool {
91
- self.content_type.eq("text/html")
92
- }
93
-
94
- pub fn process(
95
- self,
96
- ruby: &Ruby,
97
- server: RClass,
98
- app: Opaque<Value>,
99
- ) -> magnus::error::Result<()> {
100
- let req = format!("{}", self);
101
- let response = self.response.clone();
102
- let start = self.start;
103
- debug!("{} Started", req);
104
- let result = server.funcall::<_, _, Value>(*ID_CALL, (app, self));
105
- if let Err(err) = result {
106
- Self::internal_error(ruby, response, err);
107
- }
108
- debug!("{} Finished in {:?}", req, start.elapsed());
109
-
110
- Ok(())
111
- }
112
-
113
- pub fn internal_error(ruby: &Ruby, response: ItsiResponse, err: Error) {
114
- if Self::is_connection_closed_err(ruby, &err) {
115
- debug!("Connection closed by client");
116
- response.close();
117
- } else if let Some(rb_err) = err.value() {
118
- let backtrace = rb_err
119
- .funcall::<_, _, Vec<String>>(*ID_BACKTRACE, ())
120
- .unwrap_or_default();
121
-
122
- error!("Error occurred in Handler: {:?}", rb_err);
123
- for line in backtrace {
124
- error!("{}", line);
125
- }
126
- response.internal_server_error(err.to_string());
127
- } else {
128
- response.internal_server_error(err.to_string());
129
- }
130
- }
131
-
132
- pub fn error(self, message: String) {
133
- self.response.internal_server_error(message);
134
- }
135
-
136
- pub(crate) async fn process_request(
137
- hyper_request: Request<Incoming>,
138
- sender: async_channel::Sender<RequestJob>,
139
- server: Arc<Server>,
140
- listener: Arc<ListenerInfo>,
141
- addr: SockAddr,
142
- shutdown_rx: watch::Receiver<RunningPhase>,
143
- ) -> itsi_error::Result<Response<BoxBody<Bytes, Infallible>>> {
144
- let (request, mut receiver) = ItsiRequest::new(hyper_request, addr, server, listener).await;
145
-
146
- let response = request.response.clone();
147
- match sender.send(RequestJob::ProcessRequest(request)).await {
148
- Err(err) => {
149
- error!("Error occurred: {}", err);
150
- let mut response = Response::new(BoxBody::new(Empty::new()));
151
- *response.status_mut() = StatusCode::BAD_REQUEST;
152
- Ok(response)
153
- }
154
- _ => match receiver.recv().await {
155
- Some(first_frame) => Ok(response.build(first_frame, receiver, shutdown_rx).await),
156
- None => Ok(response.build(None, receiver, shutdown_rx).await),
157
- },
158
- }
159
- }
160
-
161
- pub(crate) async fn new(
162
- request: Request<Incoming>,
163
- sock_addr: SockAddr,
164
- server: Arc<Server>,
165
- listener: Arc<ListenerInfo>,
166
- ) -> (ItsiRequest, mpsc::Receiver<Option<Bytes>>) {
167
- let (parts, body) = request.into_parts();
168
- let body = if server.stream_body.is_some_and(|f| f) {
169
- ItsiBody::Stream(ItsiBodyProxy::new(body))
170
- } else {
171
- let mut body_bytes = BigBytes::new();
172
- let mut stream = body.into_data_stream();
173
- while let Some(chunk) = stream.next().await {
174
- let byte_array = chunk.unwrap().to_vec();
175
- body_bytes.write_all(&byte_array).unwrap();
176
- }
177
- ItsiBody::Buffered(body_bytes)
178
- };
179
- let response_channel = mpsc::channel::<Option<Bytes>>(100);
180
- (
181
- Self {
182
- remote_addr: sock_addr.to_string(),
183
- body,
184
- server,
185
- listener,
186
- version: format!("{:?}", &parts.version),
187
- response: ItsiResponse::new(
188
- parts.clone(),
189
- response_channel.0,
190
- parts
191
- .headers
192
- .get("Accept")
193
- .unwrap_or(&HeaderValue::from_static("text/html"))
194
- .to_str()
195
- .unwrap()
196
- .to_string(),
197
- ),
198
- start: Instant::now(),
199
- content_type: parts
200
- .headers
201
- .get("Content-Type")
202
- .unwrap_or(&HeaderValue::from_static(
203
- "application/x-www-form-urlencoded",
204
- ))
205
- .to_str()
206
- .unwrap()
207
- .to_string(),
208
- parts,
209
- },
210
- response_channel.1,
211
- )
212
- }
213
-
214
- pub(crate) fn path(&self) -> MagnusResult<&str> {
215
- Ok(self
216
- .parts
217
- .uri
218
- .path()
219
- .strip_prefix(&self.server.script_name)
220
- .unwrap_or(self.parts.uri.path()))
221
- }
222
-
223
- pub(crate) fn script_name(&self) -> MagnusResult<&str> {
224
- Ok(&self.server.script_name)
225
- }
226
-
227
- pub(crate) fn query_string(&self) -> MagnusResult<&str> {
228
- Ok(self.parts.uri.query().unwrap_or(""))
229
- }
230
-
231
- pub(crate) fn method(&self) -> MagnusResult<&str> {
232
- Ok(self.parts.method.as_str())
233
- }
234
-
235
- pub(crate) fn version(&self) -> MagnusResult<&str> {
236
- Ok(&self.version)
237
- }
238
-
239
- pub(crate) fn rack_protocol(&self) -> MagnusResult<Vec<&str>> {
240
- Ok(self
241
- .parts
242
- .headers
243
- .get("upgrade")
244
- .or_else(|| self.parts.headers.get("protocol"))
245
- .map(|value| {
246
- value
247
- .to_str()
248
- .unwrap_or("")
249
- .split(',')
250
- .map(|s| s.trim())
251
- .collect::<Vec<&str>>()
252
- })
253
- .unwrap_or_else(|| vec!["http"]))
254
- }
255
-
256
- pub(crate) fn host(&self) -> MagnusResult<String> {
257
- Ok(self
258
- .parts
259
- .uri
260
- .host()
261
- .map(|host| host.to_string())
262
- .unwrap_or_else(|| self.listener.host.clone()))
263
- }
264
-
265
- pub(crate) fn scheme(&self) -> MagnusResult<String> {
266
- Ok(self
267
- .parts
268
- .uri
269
- .scheme()
270
- .map(|scheme| scheme.to_string())
271
- .unwrap_or_else(|| self.listener.scheme.clone()))
272
- }
273
-
274
- pub(crate) fn headers(&self) -> MagnusResult<Vec<(String, &str)>> {
275
- Ok(self
276
- .parts
277
- .headers
278
- .iter()
279
- .map(|(hn, hv)| {
280
- let key = match hn.as_str() {
281
- "content-length" => "CONTENT_LENGTH".to_string(),
282
- "content-type" => "CONTENT_TYPE".to_string(),
283
- _ => format!("HTTP_{}", hn.as_str().to_uppercase().replace("-", "_")),
284
- };
285
- (key, hv.to_str().unwrap_or(""))
286
- })
287
- .collect())
288
- }
289
-
290
- pub(crate) fn remote_addr(&self) -> MagnusResult<&str> {
291
- Ok(&self.remote_addr)
292
- }
293
-
294
- pub(crate) fn port(&self) -> MagnusResult<u16> {
295
- Ok(self.parts.uri.port_u16().unwrap_or(self.listener.port))
296
- }
297
-
298
- pub(crate) fn body(&self) -> MagnusResult<Value> {
299
- Ok(self.body.into_value())
300
- }
301
-
302
- pub(crate) fn response(&self) -> MagnusResult<ItsiResponse> {
303
- Ok(self.response.clone())
304
- }
305
- }
@@ -1 +0,0 @@
1
- pub mod itsi_request;