itsi-server 0.1.1 → 0.1.20

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.

Potentially problematic release.


This version of itsi-server might be problematic. Click here for more details.

Files changed (324) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +4487 -0
  3. data/Cargo.toml +7 -0
  4. data/README.md +6 -0
  5. data/Rakefile +8 -1
  6. data/exe/itsi +141 -46
  7. data/ext/itsi_acme/Cargo.toml +86 -0
  8. data/ext/itsi_acme/examples/high_level.rs +63 -0
  9. data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
  10. data/ext/itsi_acme/examples/low_level.rs +87 -0
  11. data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
  12. data/ext/itsi_acme/src/acceptor.rs +81 -0
  13. data/ext/itsi_acme/src/acme.rs +354 -0
  14. data/ext/itsi_acme/src/axum.rs +86 -0
  15. data/ext/itsi_acme/src/cache.rs +39 -0
  16. data/ext/itsi_acme/src/caches/boxed.rs +80 -0
  17. data/ext/itsi_acme/src/caches/composite.rs +69 -0
  18. data/ext/itsi_acme/src/caches/dir.rs +106 -0
  19. data/ext/itsi_acme/src/caches/mod.rs +11 -0
  20. data/ext/itsi_acme/src/caches/no.rs +78 -0
  21. data/ext/itsi_acme/src/caches/test.rs +136 -0
  22. data/ext/itsi_acme/src/config.rs +172 -0
  23. data/ext/itsi_acme/src/https_helper.rs +69 -0
  24. data/ext/itsi_acme/src/incoming.rs +142 -0
  25. data/ext/itsi_acme/src/jose.rs +161 -0
  26. data/ext/itsi_acme/src/lib.rs +142 -0
  27. data/ext/itsi_acme/src/resolver.rs +59 -0
  28. data/ext/itsi_acme/src/state.rs +424 -0
  29. data/ext/itsi_error/Cargo.toml +3 -0
  30. data/ext/itsi_error/src/lib.rs +98 -24
  31. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  32. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  33. data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  34. data/ext/itsi_error/target/debug/build/rb-sys-49f554618693db24/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  35. data/ext/itsi_error/target/debug/incremental/itsi_error-1mmt5sux7jb0i/s-h510z7m8v9-0bxu7yd.lock +0 -0
  36. data/ext/itsi_error/target/debug/incremental/itsi_error-2vn3jey74oiw0/s-h5113n0e7e-1v5qzs6.lock +0 -0
  37. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510ykifhe-0tbnep2.lock +0 -0
  38. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510yyocpj-0tz7ug7.lock +0 -0
  39. data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510z0xc8g-14ol18k.lock +0 -0
  40. data/ext/itsi_error/target/debug/incremental/itsi_error-3g5qf4y7d54uj/s-h5113n0e7d-1trk8on.lock +0 -0
  41. data/ext/itsi_error/target/debug/incremental/itsi_error-3lpfftm45d3e2/s-h510z7m8r3-1pxp20o.lock +0 -0
  42. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510ykifek-1uxasnk.lock +0 -0
  43. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510yyocki-11u37qm.lock +0 -0
  44. data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510z0xc93-0pmy0zm.lock +0 -0
  45. data/ext/itsi_instrument_entry/Cargo.toml +15 -0
  46. data/ext/itsi_instrument_entry/src/lib.rs +31 -0
  47. data/ext/itsi_rb_helpers/Cargo.toml +3 -0
  48. data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
  49. data/ext/itsi_rb_helpers/src/lib.rs +140 -10
  50. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
  51. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
  52. data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
  53. data/ext/itsi_rb_helpers/target/debug/build/rb-sys-eb9ed4ff3a60f995/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
  54. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-040pxg6yhb3g3/s-h5113n7a1b-03bwlt4.lock +0 -0
  55. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h51113xnh3-1eik1ip.lock +0 -0
  56. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h5111704jj-0g4rj8x.lock +0 -0
  57. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-1q2d3drtxrzs5/s-h5113n79yl-0bxcqc5.lock +0 -0
  58. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h51113xoox-10de2hp.lock +0 -0
  59. data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h5111704w7-0vdq7gq.lock +0 -0
  60. data/ext/itsi_scheduler/Cargo.toml +24 -0
  61. data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
  62. data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
  63. data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
  64. data/ext/itsi_scheduler/src/itsi_scheduler.rs +308 -0
  65. data/ext/itsi_scheduler/src/lib.rs +38 -0
  66. data/ext/itsi_server/Cargo.lock +2956 -0
  67. data/ext/itsi_server/Cargo.toml +75 -14
  68. data/ext/itsi_server/extconf.rb +1 -1
  69. data/ext/itsi_server/src/default_responses/html/401.html +68 -0
  70. data/ext/itsi_server/src/default_responses/html/403.html +68 -0
  71. data/ext/itsi_server/src/default_responses/html/404.html +68 -0
  72. data/ext/itsi_server/src/default_responses/html/413.html +71 -0
  73. data/ext/itsi_server/src/default_responses/html/429.html +68 -0
  74. data/ext/itsi_server/src/default_responses/html/500.html +71 -0
  75. data/ext/itsi_server/src/default_responses/html/502.html +71 -0
  76. data/ext/itsi_server/src/default_responses/html/503.html +68 -0
  77. data/ext/itsi_server/src/default_responses/html/504.html +69 -0
  78. data/ext/itsi_server/src/default_responses/html/index.html +238 -0
  79. data/ext/itsi_server/src/default_responses/json/401.json +6 -0
  80. data/ext/itsi_server/src/default_responses/json/403.json +6 -0
  81. data/ext/itsi_server/src/default_responses/json/404.json +6 -0
  82. data/ext/itsi_server/src/default_responses/json/413.json +6 -0
  83. data/ext/itsi_server/src/default_responses/json/429.json +6 -0
  84. data/ext/itsi_server/src/default_responses/json/500.json +6 -0
  85. data/ext/itsi_server/src/default_responses/json/502.json +6 -0
  86. data/ext/itsi_server/src/default_responses/json/503.json +6 -0
  87. data/ext/itsi_server/src/default_responses/json/504.json +6 -0
  88. data/ext/itsi_server/src/default_responses/mod.rs +11 -0
  89. data/ext/itsi_server/src/env.rs +43 -0
  90. data/ext/itsi_server/src/lib.rs +132 -40
  91. data/ext/itsi_server/src/prelude.rs +2 -0
  92. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +109 -0
  93. data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +143 -0
  94. data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +344 -0
  95. data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +264 -0
  96. data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +345 -0
  97. data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +391 -0
  98. data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
  99. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +506 -0
  100. data/ext/itsi_server/src/ruby_types/itsi_server.rs +84 -0
  101. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  102. data/ext/itsi_server/src/server/binds/bind.rs +201 -0
  103. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  104. data/ext/itsi_server/src/server/binds/listener.rs +437 -0
  105. data/ext/itsi_server/src/server/binds/mod.rs +4 -0
  106. data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
  107. data/ext/itsi_server/src/server/binds/tls.rs +270 -0
  108. data/ext/itsi_server/src/server/byte_frame.rs +32 -0
  109. data/ext/itsi_server/src/server/http_message_types.rs +97 -0
  110. data/ext/itsi_server/src/server/io_stream.rs +105 -0
  111. data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
  112. data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
  113. data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +56 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +87 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +86 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +338 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +142 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +289 -0
  119. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +292 -0
  120. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +179 -0
  121. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +55 -0
  122. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +190 -0
  123. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +157 -0
  124. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +195 -0
  125. data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
  126. data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +201 -0
  127. data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
  128. data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
  129. data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +110 -0
  130. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +414 -0
  131. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +131 -0
  132. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
  133. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +44 -0
  134. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +36 -0
  135. data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +126 -0
  136. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +181 -0
  137. data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +55 -0
  138. data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +163 -0
  139. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
  140. data/ext/itsi_server/src/server/middleware_stack/mod.rs +345 -0
  141. data/ext/itsi_server/src/server/mod.rs +12 -5
  142. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  143. data/ext/itsi_server/src/server/request_job.rs +11 -0
  144. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +348 -0
  145. data/ext/itsi_server/src/server/serve_strategy/mod.rs +30 -0
  146. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +444 -0
  147. data/ext/itsi_server/src/server/signal.rs +76 -0
  148. data/ext/itsi_server/src/server/size_limited_incoming.rs +101 -0
  149. data/ext/itsi_server/src/server/thread_worker.rs +475 -0
  150. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  151. data/ext/itsi_server/src/services/itsi_http_service.rs +239 -0
  152. data/ext/itsi_server/src/services/mime_types.rs +1416 -0
  153. data/ext/itsi_server/src/services/mod.rs +6 -0
  154. data/ext/itsi_server/src/services/password_hasher.rs +83 -0
  155. data/ext/itsi_server/src/services/rate_limiter.rs +569 -0
  156. data/ext/itsi_server/src/services/static_file_server.rs +1326 -0
  157. data/ext/itsi_tracing/Cargo.toml +5 -0
  158. data/ext/itsi_tracing/src/lib.rs +346 -7
  159. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
  160. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
  161. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
  162. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
  163. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
  164. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
  165. data/lib/itsi/http_request/response_status_shortcodes.rb +74 -0
  166. data/lib/itsi/http_request.rb +187 -0
  167. data/lib/itsi/http_response.rb +41 -0
  168. data/lib/itsi/passfile.rb +109 -0
  169. data/lib/itsi/server/config/config_helpers.rb +93 -0
  170. data/lib/itsi/server/config/dsl.rb +626 -0
  171. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  172. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  173. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  174. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  175. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  176. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  177. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  178. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  179. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  180. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  181. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  182. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  183. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  184. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  185. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  186. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  187. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  188. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  189. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  190. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  191. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  192. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  193. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  194. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  212. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  213. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  214. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  215. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  216. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  217. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  218. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  219. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  220. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  221. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  222. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  223. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  224. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  225. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  226. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  227. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  228. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  229. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  230. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  231. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  232. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  233. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  234. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  235. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  236. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  237. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  238. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  239. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  240. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  241. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  242. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  254. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  255. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  256. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  257. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  258. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  259. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  260. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  261. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  262. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  263. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  264. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  265. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  266. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  267. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  268. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  269. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  270. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  271. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  272. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  273. data/lib/itsi/server/config/known_paths.rb +17 -0
  274. data/lib/itsi/server/config/middleware/_index.md +54 -0
  275. data/lib/itsi/server/config/middleware/log_requests.md +63 -0
  276. data/lib/itsi/server/config/middleware/log_requests.rb +33 -0
  277. data/lib/itsi/server/config/middleware.rb +9 -0
  278. data/lib/itsi/server/config/option.rb +9 -0
  279. data/lib/itsi/server/config/options/_index.md +36 -0
  280. data/lib/itsi/server/config/options/fiber_scheduler.md +35 -0
  281. data/lib/itsi/server/config/options/fiber_scheduler.rb +18 -0
  282. data/lib/itsi/server/config/options/threads.md +39 -0
  283. data/lib/itsi/server/config/options/threads.rb +17 -0
  284. data/lib/itsi/server/config/options/workers.md +43 -0
  285. data/lib/itsi/server/config/options/workers.rb +17 -0
  286. data/lib/itsi/server/config/typed_struct.rb +203 -0
  287. data/lib/itsi/server/config.rb +260 -0
  288. data/lib/itsi/server/default_app/default_app.rb +34 -0
  289. data/lib/itsi/server/default_app/index.html +115 -0
  290. data/lib/itsi/server/default_config/Itsi-rackup.rb +119 -0
  291. data/lib/itsi/server/default_config/Itsi.rb +107 -0
  292. data/lib/itsi/server/grpc/grpc_call.rb +246 -0
  293. data/lib/itsi/server/grpc/grpc_interface.rb +100 -0
  294. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  295. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  296. data/lib/itsi/server/rack/handler/itsi.rb +27 -0
  297. data/lib/itsi/server/rack_interface.rb +94 -0
  298. data/lib/itsi/server/route_tester.rb +107 -0
  299. data/lib/itsi/server/scheduler_interface.rb +21 -0
  300. data/lib/itsi/server/scheduler_mode.rb +10 -0
  301. data/lib/itsi/server/signal_trap.rb +33 -0
  302. data/lib/itsi/server/typed_handlers/param_parser.rb +200 -0
  303. data/lib/itsi/server/typed_handlers/source_parser.rb +55 -0
  304. data/lib/itsi/server/typed_handlers.rb +17 -0
  305. data/lib/itsi/server/version.rb +1 -1
  306. data/lib/itsi/server.rb +181 -9
  307. data/lib/itsi/standard_headers.rb +86 -0
  308. data/lib/ruby_lsp/itsi/addon.rb +127 -0
  309. data/lib/shell_completions/completions.rb +26 -0
  310. metadata +321 -28
  311. data/CHANGELOG.md +0 -5
  312. data/CODE_OF_CONDUCT.md +0 -132
  313. data/LICENSE.txt +0 -21
  314. data/ext/itsi_server/src/request/itsi_request.rs +0 -143
  315. data/ext/itsi_server/src/request/mod.rs +0 -1
  316. data/ext/itsi_server/src/server/bind.rs +0 -138
  317. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -32
  318. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -52
  319. data/ext/itsi_server/src/server/itsi_server.rs +0 -182
  320. data/ext/itsi_server/src/server/listener.rs +0 -218
  321. data/ext/itsi_server/src/server/tls.rs +0 -138
  322. data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
  323. data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
  324. data/lib/itsi/request.rb +0 -39
@@ -0,0 +1,444 @@
1
+ use crate::{
2
+ ruby_types::itsi_server::itsi_server_config::ItsiServerConfig,
3
+ server::{
4
+ binds::listener::ListenerInfo,
5
+ io_stream::IoStream,
6
+ lifecycle_event::LifecycleEvent,
7
+ request_job::RequestJob,
8
+ signal::{SHUTDOWN_REQUESTED, SIGNAL_HANDLER_CHANNEL},
9
+ thread_worker::{build_thread_workers, ThreadWorker},
10
+ },
11
+ services::itsi_http_service::{ItsiHttpService, ItsiHttpServiceInner},
12
+ };
13
+ use hyper_util::{
14
+ rt::{TokioExecutor, TokioIo, TokioTimer},
15
+ server::conn::auto::Builder,
16
+ };
17
+ use itsi_error::{ItsiError, Result};
18
+ use itsi_rb_helpers::{
19
+ call_with_gvl, call_without_gvl, create_ruby_thread, funcall_no_ret, print_rb_backtrace,
20
+ };
21
+ use itsi_tracing::{debug, error, info};
22
+ use magnus::value::ReprValue;
23
+ use nix::unistd::Pid;
24
+ use parking_lot::RwLock;
25
+ use std::{
26
+ collections::HashMap,
27
+ pin::Pin,
28
+ sync::{
29
+ atomic::{AtomicBool, Ordering},
30
+ Arc,
31
+ },
32
+ thread::sleep,
33
+ time::{Duration, Instant, SystemTime, UNIX_EPOCH},
34
+ };
35
+ use tokio::{
36
+ runtime::{Builder as RuntimeBuilder, Runtime},
37
+ sync::{
38
+ broadcast,
39
+ watch::{self},
40
+ },
41
+ task::JoinSet,
42
+ };
43
+ use tracing::instrument;
44
+
45
+ pub struct SingleMode {
46
+ pub executor: Builder<TokioExecutor>,
47
+ pub server_config: Arc<ItsiServerConfig>,
48
+ pub(crate) lifecycle_channel: broadcast::Sender<LifecycleEvent>,
49
+ pub restart_requested: AtomicBool,
50
+ pub status: RwLock<HashMap<u8, (u64, u64)>>,
51
+ }
52
+
53
+ pub enum RunningPhase {
54
+ Running,
55
+ ShutdownPending,
56
+ Shutdown,
57
+ }
58
+
59
+ impl SingleMode {
60
+ #[instrument(parent=None, skip_all)]
61
+ pub fn new(server_config: Arc<ItsiServerConfig>) -> Result<Self> {
62
+ server_config.server_params.read().preload_ruby()?;
63
+ Ok(Self {
64
+ executor: Builder::new(TokioExecutor::new()),
65
+ server_config,
66
+ lifecycle_channel: SIGNAL_HANDLER_CHANNEL.0.clone(),
67
+ restart_requested: AtomicBool::new(false),
68
+ status: RwLock::new(HashMap::new()),
69
+ })
70
+ }
71
+
72
+ pub fn build_runtime(&self) -> Runtime {
73
+ let mut builder: RuntimeBuilder = if self
74
+ .server_config
75
+ .server_params
76
+ .read()
77
+ .multithreaded_reactor
78
+ {
79
+ RuntimeBuilder::new_multi_thread()
80
+ } else {
81
+ RuntimeBuilder::new_current_thread()
82
+ };
83
+ builder
84
+ .thread_name("itsi-server-accept-loop")
85
+ .thread_stack_size(3 * 1024 * 1024)
86
+ .enable_io()
87
+ .enable_time()
88
+ .build()
89
+ .expect("Failed to build Tokio runtime")
90
+ }
91
+
92
+ pub fn stop(&self) -> Result<()> {
93
+ SHUTDOWN_REQUESTED.store(true, std::sync::atomic::Ordering::SeqCst);
94
+ self.lifecycle_channel.send(LifecycleEvent::Shutdown).ok();
95
+ Ok(())
96
+ }
97
+
98
+ pub async fn print_info(&self, thread_workers: Arc<Vec<Arc<ThreadWorker>>>) -> Result<()> {
99
+ println!(" └─ Worker");
100
+ println!(
101
+ " - binds: {:?}",
102
+ self.server_config.server_params.read().binds
103
+ );
104
+
105
+ println!(
106
+ " ─ streaming body: {:?}",
107
+ self.server_config.server_params.read().streamable_body
108
+ );
109
+ println!(
110
+ " ─ multithreaded runtime: {:?}",
111
+ self.server_config
112
+ .server_params
113
+ .read()
114
+ .multithreaded_reactor
115
+ );
116
+ println!(
117
+ " ─ scheduler: {:?}",
118
+ self.server_config.server_params.read().scheduler_class
119
+ );
120
+ println!(
121
+ " ─ OOB GC Response threadhold: {:?}",
122
+ self.server_config
123
+ .server_params
124
+ .read()
125
+ .oob_gc_responses_threshold
126
+ );
127
+ for worker in thread_workers.iter() {
128
+ println!(" └─ - Thread : {:?}", worker.id);
129
+ println!(" - # Requests Processed: {:?}", worker.request_id);
130
+ println!(
131
+ " - Last Request Started: {:?} ago",
132
+ if worker.current_request_start.load(Ordering::Relaxed) == 0 {
133
+ Duration::from_secs(0)
134
+ } else {
135
+ SystemTime::now()
136
+ .duration_since(
137
+ UNIX_EPOCH
138
+ + Duration::from_secs(
139
+ worker.current_request_start.load(Ordering::Relaxed),
140
+ ),
141
+ )
142
+ .unwrap_or(Duration::from_secs(0))
143
+ }
144
+ );
145
+ call_with_gvl(|_| {
146
+ if let Some(thread) = worker.thread.read().as_ref() {
147
+ if let Ok(backtrace) = thread.funcall::<_, _, Vec<String>>("backtrace", ()) {
148
+ println!(" - Backtrace:");
149
+ for line in backtrace {
150
+ println!(" - {}", line);
151
+ }
152
+ }
153
+ }
154
+ })
155
+ }
156
+
157
+ Ok(())
158
+ }
159
+
160
+ pub fn start_monitors(
161
+ self: Arc<Self>,
162
+ thread_workers: Arc<Vec<Arc<ThreadWorker>>>,
163
+ ) -> magnus::Thread {
164
+ call_with_gvl(move |_| {
165
+ create_ruby_thread(move || {
166
+ call_without_gvl(move || {
167
+ let monitor_runtime = RuntimeBuilder::new_current_thread()
168
+ .enable_time()
169
+ .build()
170
+ .unwrap();
171
+ let receiver = self.clone();
172
+ monitor_runtime.block_on({
173
+ let mut lifecycle_rx = receiver.lifecycle_channel.subscribe();
174
+ let receiver = receiver.clone();
175
+ let thread_workers = thread_workers.clone();
176
+ async move {
177
+ loop {
178
+ tokio::select! {
179
+ _ = tokio::time::sleep(Duration::from_secs(1)) => {
180
+ let mut status_lock = receiver.status.write();
181
+ thread_workers.iter().for_each(|worker| {
182
+ let worker_entry = status_lock.entry(worker.id);
183
+ let data = (
184
+ worker.request_id.load(Ordering::Relaxed),
185
+ worker.current_request_start.load(Ordering::Relaxed),
186
+ );
187
+ worker_entry.or_insert(data);
188
+ });
189
+ }
190
+ lifecycle_event = lifecycle_rx.recv() => {
191
+ match lifecycle_event {
192
+ Ok(LifecycleEvent::Restart) => {
193
+ receiver.restart().ok();
194
+ }
195
+ Ok(LifecycleEvent::Reload) => {
196
+ receiver.reload().ok();
197
+ }
198
+ Ok(LifecycleEvent::Shutdown) => {
199
+ break;
200
+ }
201
+ Ok(LifecycleEvent::PrintInfo) => {
202
+ receiver.print_info(thread_workers.clone()).await.ok();
203
+ }
204
+ _ => {}
205
+ }
206
+ }
207
+ }
208
+ }
209
+ }
210
+ })
211
+ })
212
+ })
213
+ })
214
+ }
215
+
216
+ #[instrument(name="worker", parent=None, skip(self), fields(pid=format!("{}", Pid::this())))]
217
+ pub fn run(self: Arc<Self>) -> Result<()> {
218
+ let mut listener_task_set = JoinSet::new();
219
+ let runtime = self.build_runtime();
220
+
221
+ let (thread_workers, job_sender, nonblocking_sender) =
222
+ build_thread_workers(self.server_config.server_params.read().clone(), Pid::this())
223
+ .inspect_err(|e| {
224
+ if let Some(err_val) = e.value() {
225
+ print_rb_backtrace(err_val);
226
+ }
227
+ })?;
228
+
229
+ info!(
230
+ threads = thread_workers.len(),
231
+ binds = format!("{:?}", self.server_config.server_params.read().binds)
232
+ );
233
+
234
+ let (shutdown_sender, _) = watch::channel(RunningPhase::Running);
235
+ let monitor_thread = self.clone().start_monitors(thread_workers.clone());
236
+ if SHUTDOWN_REQUESTED.load(Ordering::SeqCst) {
237
+ return Ok(());
238
+ }
239
+ let result = runtime.block_on(
240
+ async {
241
+ let server_params = self.server_config.server_params.read().clone();
242
+ if let Err(err) = server_params.initialize_middleware().await {
243
+ error!("Failed to initialize middleware: {}", err);
244
+ return Err(ItsiError::new("Failed to initialize middleware"))
245
+ }
246
+ let tokio_listeners = server_params.listeners.lock()
247
+ .drain(..)
248
+ .map(|list| {
249
+ Arc::new(list.into_tokio_listener())
250
+ })
251
+ .collect::<Vec<_>>();
252
+
253
+ for listener in tokio_listeners.iter() {
254
+ let mut lifecycle_rx = self.lifecycle_channel.subscribe();
255
+
256
+ let listener_info = Arc::new(listener.listener_info());
257
+ let self_ref = self.clone();
258
+ let listener = listener.clone();
259
+ let shutdown_sender = shutdown_sender.clone();
260
+ let job_sender = job_sender.clone();
261
+ let nonblocking_sender = nonblocking_sender.clone();
262
+ let workers_clone = thread_workers.clone();
263
+ let listener_clone = listener.clone();
264
+ let mut shutdown_receiver = shutdown_sender.subscribe();
265
+ let shutdown_receiver_clone = shutdown_receiver.clone();
266
+ listener_task_set.spawn(async move {
267
+ listener_clone.spawn_state_task(shutdown_receiver_clone).await;
268
+ });
269
+
270
+ listener_task_set.spawn(async move {
271
+ let strategy_clone = self_ref.clone();
272
+ let mut acceptor_task_set = JoinSet::new();
273
+ loop {
274
+ tokio::select! {
275
+ accept_result = listener.accept() => match accept_result {
276
+ Ok(accept_result) => {
277
+ let strategy = strategy_clone.clone();
278
+ let listener_info = listener_info.clone();
279
+ let shutdown_receiver = shutdown_receiver.clone();
280
+ let job_sender = job_sender.clone();
281
+ let nonblocking_sender = nonblocking_sender.clone();
282
+ acceptor_task_set.spawn(async move {
283
+ strategy.serve_connection(accept_result, job_sender, nonblocking_sender, listener_info, shutdown_receiver).await;
284
+ });
285
+ },
286
+ Err(e) => debug!("Listener.accept failed {:?}", e),
287
+ },
288
+ _ = shutdown_receiver.changed() => {
289
+ break;
290
+ }
291
+ lifecycle_event = lifecycle_rx.recv() => match lifecycle_event{
292
+ Ok(LifecycleEvent::Shutdown) => {
293
+ shutdown_sender.send(RunningPhase::ShutdownPending).unwrap();
294
+ tokio::time::sleep(Duration::from_millis(25)).await;
295
+ for _i in 0..workers_clone.len() {
296
+ job_sender.send(RequestJob::Shutdown).await.unwrap();
297
+ nonblocking_sender.send(RequestJob::Shutdown).await.unwrap();
298
+ }
299
+ break;
300
+ },
301
+ Err(e) => error!("Error receiving lifecycle_event: {:?}", e),
302
+ _ => {}
303
+ }
304
+ }
305
+ }
306
+ while let Some(_res) = acceptor_task_set.join_next().await {}
307
+ });
308
+
309
+ }
310
+
311
+ while let Some(_res) = listener_task_set.join_next().await {}
312
+
313
+ // Explicitly drop all listeners to ensure file descriptors are released
314
+ drop(tokio_listeners);
315
+
316
+ Ok::<(), ItsiError>(())
317
+ });
318
+
319
+ debug!("Single mode runtime exited.");
320
+
321
+ if result.is_err() {
322
+ for _i in 0..thread_workers.len() {
323
+ job_sender.send_blocking(RequestJob::Shutdown).unwrap();
324
+ nonblocking_sender
325
+ .send_blocking(RequestJob::Shutdown)
326
+ .unwrap();
327
+ }
328
+ self.lifecycle_channel.send(LifecycleEvent::Shutdown).ok();
329
+ }
330
+
331
+ shutdown_sender.send(RunningPhase::Shutdown).ok();
332
+ let deadline = Instant::now()
333
+ + Duration::from_secs_f64(self.server_config.server_params.read().shutdown_timeout);
334
+
335
+ runtime.shutdown_timeout(Duration::from_millis(100));
336
+
337
+ debug!("Shutdown timeout finished.");
338
+ loop {
339
+ if thread_workers
340
+ .iter()
341
+ .all(|worker| call_with_gvl(move |_| !worker.poll_shutdown(deadline)))
342
+ {
343
+ funcall_no_ret(monitor_thread, "join", ()).ok();
344
+ break;
345
+ }
346
+ sleep(Duration::from_millis(50));
347
+ }
348
+
349
+ if self.restart_requested.load(Ordering::SeqCst) {
350
+ self.restart_requested.store(false, Ordering::SeqCst);
351
+ info!("Worker restarting");
352
+ self.run()?;
353
+ }
354
+ debug!("Runtime has shut down");
355
+ result
356
+ }
357
+
358
+ pub(crate) async fn serve_connection(
359
+ &self,
360
+ stream: IoStream,
361
+ job_sender: async_channel::Sender<RequestJob>,
362
+ nonblocking_sender: async_channel::Sender<RequestJob>,
363
+ listener: Arc<ListenerInfo>,
364
+ shutdown_channel: watch::Receiver<RunningPhase>,
365
+ ) {
366
+ let addr = stream.addr();
367
+ let io: TokioIo<Pin<Box<IoStream>>> = TokioIo::new(Box::pin(stream));
368
+ let executor = self.executor.clone();
369
+ let mut shutdown_channel_clone = shutdown_channel.clone();
370
+ let mut executor = executor.clone();
371
+ let mut binding = executor.http1();
372
+ let shutdown_channel = shutdown_channel_clone.clone();
373
+
374
+ let service = ItsiHttpService {
375
+ inner: Arc::new(ItsiHttpServiceInner {
376
+ sender: job_sender.clone(),
377
+ nonblocking_sender: nonblocking_sender.clone(),
378
+ server_params: self.server_config.server_params.read().clone(),
379
+ listener,
380
+ addr: addr.to_string(),
381
+ shutdown_channel: shutdown_channel.clone(),
382
+ }),
383
+ };
384
+ let mut serve = Box::pin(
385
+ binding
386
+ .timer(TokioTimer::new())
387
+ .header_read_timeout(self.server_config.server_params.read().header_read_timeout)
388
+ .serve_connection_with_upgrades(io, service),
389
+ );
390
+
391
+ tokio::select! {
392
+ // Await the connection finishing naturally.
393
+ res = &mut serve => {
394
+ match res{
395
+ Ok(()) => {
396
+ debug!("Connection closed normally")
397
+ },
398
+ Err(res) => {
399
+ debug!("Connection closed abruptly: {:?}", res)
400
+ }
401
+ }
402
+ serve.as_mut().graceful_shutdown();
403
+ },
404
+ // A lifecycle event triggers shutdown.
405
+ _ = shutdown_channel_clone.changed() => {
406
+ // Initiate graceful shutdown.
407
+ serve.as_mut().graceful_shutdown();
408
+
409
+ // Now await the connection to finish shutting down.
410
+ if let Err(e) = serve.await {
411
+ debug!("Connection shutdown error: {:?}", e);
412
+ }
413
+ }
414
+ }
415
+ }
416
+
417
+ /// Attempts to reload the config "live"
418
+ /// Not that when running in single mode this will not unload
419
+ /// old code. If you need a clean restart, use the `restart` (SIGHUP) method instead
420
+ pub fn reload(&self) -> Result<()> {
421
+ if !self.server_config.check_config() {
422
+ return Ok(());
423
+ }
424
+ let should_reexec = self.server_config.clone().reload(false)?;
425
+ if should_reexec {
426
+ self.server_config.dup_fds()?;
427
+ self.server_config.reload_exec()?;
428
+ }
429
+ self.restart_requested.store(true, Ordering::SeqCst);
430
+ self.stop()?;
431
+ self.server_config.server_params.read().preload_ruby()?;
432
+ Ok(())
433
+ }
434
+
435
+ /// Restart the server while keeping connections open.
436
+ pub fn restart(&self) -> Result<()> {
437
+ if !self.server_config.check_config() {
438
+ return Ok(());
439
+ }
440
+ self.server_config.dup_fds()?;
441
+ self.server_config.reload_exec()?;
442
+ Ok(())
443
+ }
444
+ }
@@ -0,0 +1,76 @@
1
+ use std::sync::{
2
+ atomic::{AtomicBool, AtomicI8},
3
+ LazyLock,
4
+ };
5
+
6
+ use nix::libc::{self, sighandler_t};
7
+ use tokio::sync::{self, broadcast};
8
+
9
+ use super::lifecycle_event::LifecycleEvent;
10
+
11
+ pub static SIGINT_COUNT: AtomicI8 = AtomicI8::new(0);
12
+ pub static SHUTDOWN_REQUESTED: AtomicBool = AtomicBool::new(false);
13
+ pub static SIGNAL_HANDLER_CHANNEL: LazyLock<(
14
+ broadcast::Sender<LifecycleEvent>,
15
+ broadcast::Receiver<LifecycleEvent>,
16
+ )> = LazyLock::new(|| sync::broadcast::channel(5));
17
+
18
+ pub fn send_lifecycle_event(event: LifecycleEvent) {
19
+ SIGNAL_HANDLER_CHANNEL.0.send(event).ok();
20
+ }
21
+
22
+ fn receive_signal(signum: i32, _: sighandler_t) {
23
+ SIGINT_COUNT.fetch_add(-1, std::sync::atomic::Ordering::SeqCst);
24
+ let event = match signum {
25
+ libc::SIGTERM | libc::SIGINT => {
26
+ SHUTDOWN_REQUESTED.store(true, std::sync::atomic::Ordering::SeqCst);
27
+ SIGINT_COUNT.fetch_add(2, std::sync::atomic::Ordering::SeqCst);
28
+ if SIGINT_COUNT.load(std::sync::atomic::Ordering::SeqCst) < 2 {
29
+ Some(LifecycleEvent::Shutdown)
30
+ } else {
31
+ // Not messing about. Force shutdown.
32
+ Some(LifecycleEvent::ForceShutdown)
33
+ }
34
+ }
35
+ libc::SIGUSR2 => Some(LifecycleEvent::PrintInfo),
36
+ libc::SIGUSR1 => Some(LifecycleEvent::Restart),
37
+ libc::SIGHUP => Some(LifecycleEvent::Reload),
38
+ libc::SIGTTIN => Some(LifecycleEvent::IncreaseWorkers),
39
+ libc::SIGTTOU => Some(LifecycleEvent::DecreaseWorkers),
40
+ libc::SIGCHLD => Some(LifecycleEvent::ChildTerminated),
41
+ _ => None,
42
+ };
43
+
44
+ if let Some(event) = event {
45
+ send_lifecycle_event(event);
46
+ }
47
+ }
48
+
49
+ pub fn reset_signal_handlers() -> bool {
50
+ SIGINT_COUNT.store(0, std::sync::atomic::Ordering::SeqCst);
51
+ SHUTDOWN_REQUESTED.store(false, std::sync::atomic::Ordering::SeqCst);
52
+ unsafe {
53
+ libc::signal(libc::SIGTERM, receive_signal as usize);
54
+ libc::signal(libc::SIGINT, receive_signal as usize);
55
+ libc::signal(libc::SIGUSR2, receive_signal as usize);
56
+ libc::signal(libc::SIGUSR1, receive_signal as usize);
57
+ libc::signal(libc::SIGHUP, receive_signal as usize);
58
+ libc::signal(libc::SIGTTIN, receive_signal as usize);
59
+ libc::signal(libc::SIGTTOU, receive_signal as usize);
60
+ libc::signal(libc::SIGCHLD, receive_signal as usize);
61
+ }
62
+ true
63
+ }
64
+
65
+ pub fn clear_signal_handlers() {
66
+ unsafe {
67
+ libc::signal(libc::SIGTERM, libc::SIG_DFL);
68
+ libc::signal(libc::SIGINT, libc::SIG_DFL);
69
+ libc::signal(libc::SIGUSR2, libc::SIG_DFL);
70
+ libc::signal(libc::SIGUSR1, libc::SIG_DFL);
71
+ libc::signal(libc::SIGHUP, libc::SIG_DFL);
72
+ libc::signal(libc::SIGTTIN, libc::SIG_DFL);
73
+ libc::signal(libc::SIGTTOU, libc::SIG_DFL);
74
+ libc::signal(libc::SIGCHLD, libc::SIG_DFL);
75
+ }
76
+ }
@@ -0,0 +1,101 @@
1
+ use bytes::Buf;
2
+ use hyper::body::Body;
3
+ use hyper::body::Frame;
4
+ use hyper::body::SizeHint;
5
+ use std::error::Error;
6
+ use std::fmt;
7
+ use std::ops::Deref;
8
+ use std::pin::Pin;
9
+ use std::sync::atomic::AtomicUsize;
10
+ use std::sync::atomic::Ordering;
11
+ use std::task::Context;
12
+ use std::task::Poll;
13
+
14
+ /// Custom error to indicate that the maximum body size was exceeded.
15
+ #[derive(Debug)]
16
+ pub struct MaxBodySizeReached;
17
+ impl fmt::Display for MaxBodySizeReached {
18
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19
+ write!(f, "Maximum body size reached")
20
+ }
21
+ }
22
+
23
+ impl Error for MaxBodySizeReached {}
24
+
25
+ #[derive(Debug)]
26
+ pub struct SizeLimitedIncoming<B> {
27
+ pub inner: B,
28
+ pub limit: AtomicUsize,
29
+ current: usize,
30
+ }
31
+
32
+ impl<B> Deref for SizeLimitedIncoming<B> {
33
+ type Target = B;
34
+
35
+ fn deref(&self) -> &Self::Target {
36
+ &self.inner
37
+ }
38
+ }
39
+
40
+ impl<B> SizeLimitedIncoming<B> {
41
+ pub fn new(inner: B) -> Self {
42
+ Self {
43
+ inner,
44
+ limit: AtomicUsize::new(usize::MAX),
45
+ current: 0,
46
+ }
47
+ }
48
+ }
49
+
50
+ impl<B> Body for SizeLimitedIncoming<B>
51
+ where
52
+ B: Body + Unpin,
53
+ B::Data: Buf,
54
+ // Ensure that the inner error converts into our boxed error type.
55
+ B::Error: Into<Box<dyn Error + Send + Sync>>,
56
+ {
57
+ type Data = B::Data;
58
+ type Error = Box<dyn Error + Send + Sync>;
59
+
60
+ fn poll_frame(
61
+ mut self: Pin<&mut Self>,
62
+ cx: &mut Context<'_>,
63
+ ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
64
+ // Pin the inner body.
65
+ let inner = Pin::new(&mut self.inner);
66
+ match inner.poll_frame(cx) {
67
+ Poll::Ready(Some(Ok(frame))) => {
68
+ // Use public methods since we cannot match on the private enum.
69
+ if frame.is_data() {
70
+ match frame.into_data() {
71
+ Ok(data) => {
72
+ let len = data.remaining();
73
+ self.current += len;
74
+ if self.current > self.limit.load(Ordering::Relaxed) {
75
+ Poll::Ready(Some(Err(Box::new(MaxBodySizeReached))))
76
+ } else {
77
+ Poll::Ready(Some(Ok(Frame::data(data))))
78
+ }
79
+ }
80
+ // Should not occur if is_data() was true, but pass through if it does.
81
+ Err(frame) => Poll::Ready(Some(Ok(frame))),
82
+ }
83
+ } else {
84
+ // For non-data frames (e.g. trailers), just pass them along.
85
+ Poll::Ready(Some(Ok(frame)))
86
+ }
87
+ }
88
+ Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e.into()))),
89
+ Poll::Ready(None) => Poll::Ready(None),
90
+ Poll::Pending => Poll::Pending,
91
+ }
92
+ }
93
+
94
+ fn is_end_stream(&self) -> bool {
95
+ self.inner.is_end_stream()
96
+ }
97
+
98
+ fn size_hint(&self) -> SizeHint {
99
+ self.inner.size_hint()
100
+ }
101
+ }