itsi-server 0.1.1 → 0.2.2

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 (457) 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 +7 -4
  6. data/exe/itsi +152 -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 +141 -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 +314 -0
  65. data/ext/itsi_scheduler/src/lib.rs +39 -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 +133 -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 +362 -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 +233 -0
  99. data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +565 -0
  100. data/ext/itsi_server/src/ruby_types/itsi_server.rs +86 -0
  101. data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
  102. data/ext/itsi_server/src/server/binds/bind.rs +204 -0
  103. data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
  104. data/ext/itsi_server/src/server/binds/listener.rs +444 -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 +278 -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 +63 -0
  114. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
  115. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +94 -0
  116. data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
  117. data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
  118. data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +316 -0
  119. data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +301 -0
  120. data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
  121. data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
  122. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +192 -0
  123. data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +171 -0
  124. data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +198 -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 +209 -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 +116 -0
  130. data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +411 -0
  131. data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +142 -0
  132. data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +55 -0
  133. data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
  134. data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -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 +187 -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 +173 -0
  139. data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
  140. data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
  141. data/ext/itsi_server/src/server/mod.rs +13 -5
  142. data/ext/itsi_server/src/server/process_worker.rs +247 -0
  143. data/ext/itsi_server/src/server/redirect_type.rs +26 -0
  144. data/ext/itsi_server/src/server/request_job.rs +11 -0
  145. data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +354 -0
  146. data/ext/itsi_server/src/server/serve_strategy/mod.rs +30 -0
  147. data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +481 -0
  148. data/ext/itsi_server/src/server/signal.rs +77 -0
  149. data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
  150. data/ext/itsi_server/src/server/thread_worker.rs +479 -0
  151. data/ext/itsi_server/src/services/cache_store.rs +74 -0
  152. data/ext/itsi_server/src/services/itsi_http_service.rs +257 -0
  153. data/ext/itsi_server/src/services/mime_types.rs +1416 -0
  154. data/ext/itsi_server/src/services/mod.rs +6 -0
  155. data/ext/itsi_server/src/services/password_hasher.rs +83 -0
  156. data/ext/itsi_server/src/services/rate_limiter.rs +580 -0
  157. data/ext/itsi_server/src/services/static_file_server.rs +1340 -0
  158. data/ext/itsi_tracing/Cargo.toml +5 -0
  159. data/ext/itsi_tracing/src/lib.rs +366 -7
  160. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
  161. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
  162. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
  163. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
  164. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
  165. data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
  166. data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
  167. data/lib/itsi/http_request.rb +218 -0
  168. data/lib/itsi/http_response.rb +42 -0
  169. data/lib/itsi/passfile.rb +108 -0
  170. data/lib/itsi/server/config/config_helpers.rb +105 -0
  171. data/lib/itsi/server/config/dsl.rb +211 -0
  172. data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
  173. data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
  174. data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
  175. data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
  176. data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
  177. data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
  178. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
  179. data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
  180. data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
  181. data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
  182. data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
  183. data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
  184. data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
  185. data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
  186. data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
  187. data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
  188. data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
  189. data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
  190. data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
  191. data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
  192. data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
  193. data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
  194. data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
  195. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
  196. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
  197. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
  198. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
  199. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
  200. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
  201. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
  202. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
  203. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
  204. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
  205. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
  206. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
  207. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
  208. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
  209. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
  210. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
  211. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
  212. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
  213. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
  214. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
  215. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
  216. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
  217. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
  218. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
  219. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
  220. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
  221. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
  222. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
  223. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
  224. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
  225. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
  226. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
  227. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
  228. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
  229. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
  230. data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
  231. data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
  232. data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
  233. data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
  234. data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
  235. data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
  236. data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
  237. data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
  238. data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
  239. data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
  240. data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
  241. data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
  242. data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
  243. data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
  244. data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
  245. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
  246. data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
  247. data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
  248. data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
  249. data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
  250. data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
  251. data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
  252. data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
  253. data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
  254. data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
  255. data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
  256. data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
  257. data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
  258. data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
  259. data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
  260. data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
  261. data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
  262. data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
  263. data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
  264. data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
  265. data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
  266. data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
  267. data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
  268. data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
  269. data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
  270. data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
  271. data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
  272. data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
  273. data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
  274. data/lib/itsi/server/config/known_paths.rb +20 -0
  275. data/lib/itsi/server/config/middleware/_index.md +56 -0
  276. data/lib/itsi/server/config/middleware/allow_list.md +46 -0
  277. data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
  278. data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
  279. data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
  280. data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
  281. data/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
  282. data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
  283. data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
  284. data/lib/itsi/server/config/middleware/cache_control.md +78 -0
  285. data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
  286. data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
  287. data/lib/itsi/server/config/middleware/compression.md +50 -0
  288. data/lib/itsi/server/config/middleware/compression.rb +37 -0
  289. data/lib/itsi/server/config/middleware/cors.md +93 -0
  290. data/lib/itsi/server/config/middleware/cors.rb +32 -0
  291. data/lib/itsi/server/config/middleware/csp.md +37 -0
  292. data/lib/itsi/server/config/middleware/csp.rb +44 -0
  293. data/lib/itsi/server/config/middleware/deny_list.md +45 -0
  294. data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
  295. data/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
  296. data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
  297. data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
  298. data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
  299. data/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
  300. data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
  301. data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
  302. data/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
  303. data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
  304. data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
  305. data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
  306. data/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
  307. data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
  308. data/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
  309. data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
  310. data/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
  311. data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
  312. data/lib/itsi/server/config/middleware/error_response.md +61 -0
  313. data/lib/itsi/server/config/middleware/error_response.rb +36 -0
  314. data/lib/itsi/server/config/middleware/etag.md +59 -0
  315. data/lib/itsi/server/config/middleware/etag.rb +27 -0
  316. data/lib/itsi/server/config/middleware/grpc.md +172 -0
  317. data/lib/itsi/server/config/middleware/grpc.rb +54 -0
  318. data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
  319. data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
  320. data/lib/itsi/server/config/middleware/location.md +107 -0
  321. data/lib/itsi/server/config/middleware/location.rb +99 -0
  322. data/lib/itsi/server/config/middleware/log_requests.md +65 -0
  323. data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
  324. data/lib/itsi/server/config/middleware/max_body.md +18 -0
  325. data/lib/itsi/server/config/middleware/max_body.rb +21 -0
  326. data/lib/itsi/server/config/middleware/proxy.md +62 -0
  327. data/lib/itsi/server/config/middleware/proxy.rb +41 -0
  328. data/lib/itsi/server/config/middleware/rackup_file.md +54 -0
  329. data/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
  330. data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
  331. data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
  332. data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
  333. data/lib/itsi/server/config/middleware/redirect.md +55 -0
  334. data/lib/itsi/server/config/middleware/redirect.rb +25 -0
  335. data/lib/itsi/server/config/middleware/request_headers.md +34 -0
  336. data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
  337. data/lib/itsi/server/config/middleware/response_headers.md +33 -0
  338. data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
  339. data/lib/itsi/server/config/middleware/run.md +60 -0
  340. data/lib/itsi/server/config/middleware/run.rb +43 -0
  341. data/lib/itsi/server/config/middleware/static_assets.md +73 -0
  342. data/lib/itsi/server/config/middleware/static_assets.rb +87 -0
  343. data/lib/itsi/server/config/middleware/static_response.md +44 -0
  344. data/lib/itsi/server/config/middleware/static_response.rb +29 -0
  345. data/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
  346. data/lib/itsi/server/config/middleware/token_source.rb +32 -0
  347. data/lib/itsi/server/config/middleware.rb +13 -0
  348. data/lib/itsi/server/config/option.rb +14 -0
  349. data/lib/itsi/server/config/options/_index.md +37 -0
  350. data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
  351. data/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
  352. data/lib/itsi/server/config/options/bind.md +71 -0
  353. data/lib/itsi/server/config/options/bind.rb +26 -0
  354. data/lib/itsi/server/config/options/certificates.md +65 -0
  355. data/lib/itsi/server/config/options/daemonize.md +14 -0
  356. data/lib/itsi/server/config/options/daemonize.rb +19 -0
  357. data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
  358. data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
  359. data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
  360. data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
  361. data/lib/itsi/server/config/options/hooks/_index.md +11 -0
  362. data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
  363. data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
  364. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
  365. data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
  366. data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
  367. data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
  368. data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
  369. data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
  370. data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
  371. data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
  372. data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
  373. data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
  374. data/lib/itsi/server/config/options/include.md +20 -0
  375. data/lib/itsi/server/config/options/include.rb +36 -0
  376. data/lib/itsi/server/config/options/listen_backlog.md +11 -0
  377. data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
  378. data/lib/itsi/server/config/options/log_format.md +18 -0
  379. data/lib/itsi/server/config/options/log_format.rb +19 -0
  380. data/lib/itsi/server/config/options/log_level.md +34 -0
  381. data/lib/itsi/server/config/options/log_level.rb +20 -0
  382. data/lib/itsi/server/config/options/log_target.md +38 -0
  383. data/lib/itsi/server/config/options/log_target.rb +19 -0
  384. data/lib/itsi/server/config/options/log_target_filters.md +17 -0
  385. data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
  386. data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
  387. data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
  388. data/lib/itsi/server/config/options/nodelay.md +16 -0
  389. data/lib/itsi/server/config/options/nodelay.rb +19 -0
  390. data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
  391. data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
  392. data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
  393. data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
  394. data/lib/itsi/server/config/options/preload.md +21 -0
  395. data/lib/itsi/server/config/options/preload.rb +18 -0
  396. data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
  397. data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
  398. data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
  399. data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
  400. data/lib/itsi/server/config/options/request_timeout.md +23 -0
  401. data/lib/itsi/server/config/options/request_timeout.rb +19 -0
  402. data/lib/itsi/server/config/options/reuse_address.md +16 -0
  403. data/lib/itsi/server/config/options/reuse_address.rb +19 -0
  404. data/lib/itsi/server/config/options/reuse_port.md +16 -0
  405. data/lib/itsi/server/config/options/reuse_port.rb +19 -0
  406. data/lib/itsi/server/config/options/scheduler_threads.md +34 -0
  407. data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
  408. data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
  409. data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
  410. data/lib/itsi/server/config/options/stream_body.md +32 -0
  411. data/lib/itsi/server/config/options/stream_body.rb +18 -0
  412. data/lib/itsi/server/config/options/threads.md +44 -0
  413. data/lib/itsi/server/config/options/threads.rb +17 -0
  414. data/lib/itsi/server/config/options/watch.md +16 -0
  415. data/lib/itsi/server/config/options/watch.rb +28 -0
  416. data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
  417. data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
  418. data/lib/itsi/server/config/options/workers.md +42 -0
  419. data/lib/itsi/server/config/options/workers.rb +17 -0
  420. data/lib/itsi/server/config/typed_struct.rb +242 -0
  421. data/lib/itsi/server/config.rb +289 -0
  422. data/lib/itsi/server/default_app/default_app.rb +34 -0
  423. data/lib/itsi/server/default_app/index.html +115 -0
  424. data/lib/itsi/server/default_config/Itsi.rb +107 -0
  425. data/lib/itsi/server/grpc/grpc_call.rb +246 -0
  426. data/lib/itsi/server/grpc/grpc_interface.rb +107 -0
  427. data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
  428. data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
  429. data/lib/itsi/server/rack/handler/itsi.rb +27 -0
  430. data/lib/itsi/server/rack_interface.rb +94 -0
  431. data/lib/itsi/server/route_tester.rb +157 -0
  432. data/lib/itsi/server/scheduler_interface.rb +21 -0
  433. data/lib/itsi/server/scheduler_mode.rb +10 -0
  434. data/lib/itsi/server/signal_trap.rb +33 -0
  435. data/lib/itsi/server/typed_handlers/param_parser.rb +196 -0
  436. data/lib/itsi/server/typed_handlers/source_parser.rb +56 -0
  437. data/lib/itsi/server/typed_handlers.rb +25 -0
  438. data/lib/itsi/server/version.rb +1 -1
  439. data/lib/itsi/server.rb +265 -9
  440. data/lib/itsi/standard_headers.rb +86 -0
  441. data/lib/ruby_lsp/itsi/addon.rb +129 -0
  442. data/lib/shell_completions/completions.rb +26 -0
  443. metadata +454 -28
  444. data/CHANGELOG.md +0 -5
  445. data/CODE_OF_CONDUCT.md +0 -132
  446. data/LICENSE.txt +0 -21
  447. data/ext/itsi_server/src/request/itsi_request.rs +0 -143
  448. data/ext/itsi_server/src/request/mod.rs +0 -1
  449. data/ext/itsi_server/src/server/bind.rs +0 -138
  450. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -32
  451. data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -52
  452. data/ext/itsi_server/src/server/itsi_server.rs +0 -182
  453. data/ext/itsi_server/src/server/listener.rs +0 -218
  454. data/ext/itsi_server/src/server/tls.rs +0 -138
  455. data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
  456. data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
  457. data/lib/itsi/request.rb +0 -39
@@ -0,0 +1,355 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ use std::cell::RefCell;
4
+ use std::collections::HashMap;
5
+ use std::env;
6
+ use std::path::{Path, PathBuf};
7
+ use std::process::Command;
8
+
9
+ use glob::{MatchOptions, Pattern};
10
+
11
+ //================================================
12
+ // Commands
13
+ //================================================
14
+
15
+ thread_local! {
16
+ /// The errors encountered by the build script while executing commands.
17
+ static COMMAND_ERRORS: RefCell<HashMap<String, Vec<String>>> = RefCell::default();
18
+ }
19
+
20
+ /// Adds an error encountered by the build script while executing a command.
21
+ fn add_command_error(name: &str, path: &str, arguments: &[&str], message: String) {
22
+ COMMAND_ERRORS.with(|e| {
23
+ e.borrow_mut()
24
+ .entry(name.into())
25
+ .or_default()
26
+ .push(format!(
27
+ "couldn't execute `{} {}` (path={}) ({})",
28
+ name,
29
+ arguments.join(" "),
30
+ path,
31
+ message,
32
+ ))
33
+ });
34
+ }
35
+
36
+ /// A struct that prints the errors encountered by the build script while
37
+ /// executing commands when dropped (unless explictly discarded).
38
+ ///
39
+ /// This is handy because we only want to print these errors when the build
40
+ /// script fails to link to an instance of `libclang`. For example, if
41
+ /// `llvm-config` couldn't be executed but an instance of `libclang` was found
42
+ /// anyway we don't want to pollute the build output with irrelevant errors.
43
+ #[derive(Default)]
44
+ pub struct CommandErrorPrinter {
45
+ discard: bool,
46
+ }
47
+
48
+ impl CommandErrorPrinter {
49
+ pub fn discard(mut self) {
50
+ self.discard = true;
51
+ }
52
+ }
53
+
54
+ impl Drop for CommandErrorPrinter {
55
+ fn drop(&mut self) {
56
+ if self.discard {
57
+ return;
58
+ }
59
+
60
+ let errors = COMMAND_ERRORS.with(|e| e.borrow().clone());
61
+
62
+ if let Some(errors) = errors.get("llvm-config") {
63
+ println!(
64
+ "cargo:warning=could not execute `llvm-config` one or more \
65
+ times, if the LLVM_CONFIG_PATH environment variable is set to \
66
+ a full path to valid `llvm-config` executable it will be used \
67
+ to try to find an instance of `libclang` on your system: {}",
68
+ errors
69
+ .iter()
70
+ .map(|e| format!("\"{}\"", e))
71
+ .collect::<Vec<_>>()
72
+ .join("\n "),
73
+ )
74
+ }
75
+
76
+ if let Some(errors) = errors.get("xcode-select") {
77
+ println!(
78
+ "cargo:warning=could not execute `xcode-select` one or more \
79
+ times, if a valid instance of this executable is on your PATH \
80
+ it will be used to try to find an instance of `libclang` on \
81
+ your system: {}",
82
+ errors
83
+ .iter()
84
+ .map(|e| format!("\"{}\"", e))
85
+ .collect::<Vec<_>>()
86
+ .join("\n "),
87
+ )
88
+ }
89
+ }
90
+ }
91
+
92
+ #[cfg(test)]
93
+ lazy_static::lazy_static! {
94
+ pub static ref RUN_COMMAND_MOCK: std::sync::Mutex<
95
+ Option<Box<dyn Fn(&str, &str, &[&str]) -> Option<String> + Send + Sync + 'static>>,
96
+ > = std::sync::Mutex::new(None);
97
+ }
98
+
99
+ /// Executes a command and returns the `stdout` output if the command was
100
+ /// successfully executed (errors are added to `COMMAND_ERRORS`).
101
+ fn run_command(name: &str, path: &str, arguments: &[&str]) -> Option<String> {
102
+ #[cfg(test)]
103
+ if let Some(command) = &*RUN_COMMAND_MOCK.lock().unwrap() {
104
+ return command(name, path, arguments);
105
+ }
106
+
107
+ let output = match Command::new(path).args(arguments).output() {
108
+ Ok(output) => output,
109
+ Err(error) => {
110
+ let message = format!("error: {}", error);
111
+ add_command_error(name, path, arguments, message);
112
+ return None;
113
+ }
114
+ };
115
+
116
+ if output.status.success() {
117
+ Some(String::from_utf8_lossy(&output.stdout).into_owned())
118
+ } else {
119
+ let message = format!("exit code: {}", output.status);
120
+ add_command_error(name, path, arguments, message);
121
+ None
122
+ }
123
+ }
124
+
125
+ /// Executes the `llvm-config` command and returns the `stdout` output if the
126
+ /// command was successfully executed (errors are added to `COMMAND_ERRORS`).
127
+ pub fn run_llvm_config(arguments: &[&str]) -> Option<String> {
128
+ let path = env::var("LLVM_CONFIG_PATH").unwrap_or_else(|_| "llvm-config".into());
129
+ run_command("llvm-config", &path, arguments)
130
+ }
131
+
132
+ /// Executes the `xcode-select` command and returns the `stdout` output if the
133
+ /// command was successfully executed (errors are added to `COMMAND_ERRORS`).
134
+ pub fn run_xcode_select(arguments: &[&str]) -> Option<String> {
135
+ run_command("xcode-select", "xcode-select", arguments)
136
+ }
137
+
138
+ //================================================
139
+ // Search Directories
140
+ //================================================
141
+ // These search directories are listed in order of
142
+ // preference, so if multiple `libclang` instances
143
+ // are found when searching matching directories,
144
+ // the `libclang` instances from earlier
145
+ // directories will be preferred (though version
146
+ // takes precedence over location).
147
+ //================================================
148
+
149
+ /// `libclang` directory patterns for Haiku.
150
+ const DIRECTORIES_HAIKU: &[&str] = &[
151
+ "/boot/home/config/non-packaged/develop/lib",
152
+ "/boot/home/config/non-packaged/lib",
153
+ "/boot/system/non-packaged/develop/lib",
154
+ "/boot/system/non-packaged/lib",
155
+ "/boot/system/develop/lib",
156
+ "/boot/system/lib",
157
+ ];
158
+
159
+ /// `libclang` directory patterns for Linux (and FreeBSD).
160
+ const DIRECTORIES_LINUX: &[&str] = &[
161
+ "/usr/local/llvm*/lib*",
162
+ "/usr/local/lib*/*/*",
163
+ "/usr/local/lib*/*",
164
+ "/usr/local/lib*",
165
+ "/usr/lib*/*/*",
166
+ "/usr/lib*/*",
167
+ "/usr/lib*",
168
+ ];
169
+
170
+ /// `libclang` directory patterns for macOS.
171
+ const DIRECTORIES_MACOS: &[&str] = &[
172
+ "/usr/local/opt/llvm*/lib/llvm*/lib",
173
+ "/Library/Developer/CommandLineTools/usr/lib",
174
+ "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
175
+ "/usr/local/opt/llvm*/lib",
176
+ ];
177
+
178
+ /// `libclang` directory patterns for Windows.
179
+ ///
180
+ /// The boolean indicates whether the directory pattern should be used when
181
+ /// compiling for an MSVC target environment.
182
+ const DIRECTORIES_WINDOWS: &[(&str, bool)] = &[
183
+ // LLVM + Clang can be installed using Scoop (https://scoop.sh).
184
+ // Other Windows package managers install LLVM + Clang to other listed
185
+ // system-wide directories.
186
+ ("C:\\Users\\*\\scoop\\apps\\llvm\\current\\lib", true),
187
+ ("C:\\MSYS*\\MinGW*\\lib", false),
188
+ ("C:\\Program Files*\\LLVM\\lib", true),
189
+ ("C:\\LLVM\\lib", true),
190
+ // LLVM + Clang can be installed as a component of Visual Studio.
191
+ // https://github.com/KyleMayes/clang-sys/issues/121
192
+ ("C:\\Program Files*\\Microsoft Visual Studio\\*\\VC\\Tools\\Llvm\\**\\lib", true),
193
+ ];
194
+
195
+ /// `libclang` directory patterns for illumos
196
+ const DIRECTORIES_ILLUMOS: &[&str] = &[
197
+ "/opt/ooce/llvm-*/lib",
198
+ "/opt/ooce/clang-*/lib",
199
+ ];
200
+
201
+ //================================================
202
+ // Searching
203
+ //================================================
204
+
205
+ /// Finds the files in a directory that match one or more filename glob patterns
206
+ /// and returns the paths to and filenames of those files.
207
+ fn search_directory(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
208
+ // Escape the specified directory in case it contains characters that have
209
+ // special meaning in glob patterns (e.g., `[` or `]`).
210
+ let directory = Pattern::escape(directory.to_str().unwrap());
211
+ let directory = Path::new(&directory);
212
+
213
+ // Join the escaped directory to the filename glob patterns to obtain
214
+ // complete glob patterns for the files being searched for.
215
+ let paths = filenames
216
+ .iter()
217
+ .map(|f| directory.join(f).to_str().unwrap().to_owned());
218
+
219
+ // Prevent wildcards from matching path separators to ensure that the search
220
+ // is limited to the specified directory.
221
+ let mut options = MatchOptions::new();
222
+ options.require_literal_separator = true;
223
+
224
+ paths
225
+ .map(|p| glob::glob_with(&p, options))
226
+ .filter_map(Result::ok)
227
+ .flatten()
228
+ .filter_map(|p| {
229
+ let path = p.ok()?;
230
+ let filename = path.file_name()?.to_str().unwrap();
231
+
232
+ // The `libclang_shared` library has been renamed to `libclang-cpp`
233
+ // in Clang 10. This can cause instances of this library (e.g.,
234
+ // `libclang-cpp.so.10`) to be matched by patterns looking for
235
+ // instances of `libclang`.
236
+ if filename.contains("-cpp.") {
237
+ return None;
238
+ }
239
+
240
+ Some((path.parent().unwrap().to_owned(), filename.into()))
241
+ })
242
+ .collect::<Vec<_>>()
243
+ }
244
+
245
+ /// Finds the files in a directory (and any relevant sibling directories) that
246
+ /// match one or more filename glob patterns and returns the paths to and
247
+ /// filenames of those files.
248
+ fn search_directories(directory: &Path, filenames: &[String]) -> Vec<(PathBuf, String)> {
249
+ let mut results = search_directory(directory, filenames);
250
+
251
+ // On Windows, `libclang.dll` is usually found in the LLVM `bin` directory
252
+ // while `libclang.lib` is usually found in the LLVM `lib` directory. To
253
+ // keep things consistent with other platforms, only LLVM `lib` directories
254
+ // are included in the backup search directory globs so we need to search
255
+ // the LLVM `bin` directory here.
256
+ if target_os!("windows") && directory.ends_with("lib") {
257
+ let sibling = directory.parent().unwrap().join("bin");
258
+ results.extend(search_directory(&sibling, filenames));
259
+ }
260
+
261
+ results
262
+ }
263
+
264
+ /// Finds the `libclang` static or dynamic libraries matching one or more
265
+ /// filename glob patterns and returns the paths to and filenames of those files.
266
+ pub fn search_libclang_directories(filenames: &[String], variable: &str) -> Vec<(PathBuf, String)> {
267
+ // Search only the path indicated by the relevant environment variable
268
+ // (e.g., `LIBCLANG_PATH`) if it is set.
269
+ if let Ok(path) = env::var(variable).map(|d| Path::new(&d).to_path_buf()) {
270
+ // Check if the path is a matching file.
271
+ if let Some(parent) = path.parent() {
272
+ let filename = path.file_name().unwrap().to_str().unwrap();
273
+ let libraries = search_directories(parent, filenames);
274
+ if libraries.iter().any(|(_, f)| f == filename) {
275
+ return vec![(parent.into(), filename.into())];
276
+ }
277
+ }
278
+
279
+ // Check if the path is directory containing a matching file.
280
+ return search_directories(&path, filenames);
281
+ }
282
+
283
+ let mut found = vec![];
284
+
285
+ // Search the `bin` and `lib` directories in the directory returned by
286
+ // `llvm-config --prefix`.
287
+ if let Some(output) = run_llvm_config(&["--prefix"]) {
288
+ let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
289
+ found.extend(search_directories(&directory.join("bin"), filenames));
290
+ found.extend(search_directories(&directory.join("lib"), filenames));
291
+ found.extend(search_directories(&directory.join("lib64"), filenames));
292
+ }
293
+
294
+ // Search the toolchain directory in the directory returned by
295
+ // `xcode-select --print-path`.
296
+ if target_os!("macos") {
297
+ if let Some(output) = run_xcode_select(&["--print-path"]) {
298
+ let directory = Path::new(output.lines().next().unwrap()).to_path_buf();
299
+ let directory = directory.join("Toolchains/XcodeDefault.xctoolchain/usr/lib");
300
+ found.extend(search_directories(&directory, filenames));
301
+ }
302
+ }
303
+
304
+ // Search the directories in the `LD_LIBRARY_PATH` environment variable.
305
+ if let Ok(path) = env::var("LD_LIBRARY_PATH") {
306
+ for directory in env::split_paths(&path) {
307
+ found.extend(search_directories(&directory, filenames));
308
+ }
309
+ }
310
+
311
+ // Determine the `libclang` directory patterns.
312
+ let directories: Vec<&str> = if target_os!("haiku") {
313
+ DIRECTORIES_HAIKU.into()
314
+ } else if target_os!("linux") || target_os!("freebsd") {
315
+ DIRECTORIES_LINUX.into()
316
+ } else if target_os!("macos") {
317
+ DIRECTORIES_MACOS.into()
318
+ } else if target_os!("windows") {
319
+ let msvc = target_env!("msvc");
320
+ DIRECTORIES_WINDOWS
321
+ .iter()
322
+ .filter(|d| d.1 || !msvc)
323
+ .map(|d| d.0)
324
+ .collect()
325
+ } else if target_os!("illumos") {
326
+ DIRECTORIES_ILLUMOS.into()
327
+ } else {
328
+ vec![]
329
+ };
330
+
331
+ // We use temporary directories when testing the build script so we'll
332
+ // remove the prefixes that make the directories absolute.
333
+ let directories = if test!() {
334
+ directories
335
+ .iter()
336
+ .map(|d| d.strip_prefix('/').or_else(|| d.strip_prefix("C:\\")).unwrap_or(d))
337
+ .collect::<Vec<_>>()
338
+ } else {
339
+ directories
340
+ };
341
+
342
+ // Search the directories provided by the `libclang` directory patterns.
343
+ let mut options = MatchOptions::new();
344
+ options.case_sensitive = false;
345
+ options.require_literal_separator = true;
346
+ for directory in directories.iter() {
347
+ if let Ok(directories) = glob::glob_with(directory, options) {
348
+ for directory in directories.filter_map(Result::ok).filter(|p| p.is_dir()) {
349
+ found.extend(search_directories(&directory, filenames));
350
+ }
351
+ }
352
+ }
353
+
354
+ found
355
+ }
@@ -0,0 +1,276 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ use std::env;
4
+ use std::fs::File;
5
+ use std::io::{self, Error, ErrorKind, Read, Seek, SeekFrom};
6
+ use std::path::{Path, PathBuf};
7
+
8
+ use super::common;
9
+
10
+ //================================================
11
+ // Validation
12
+ //================================================
13
+
14
+ /// Extracts the ELF class from the ELF header in a shared library.
15
+ fn parse_elf_header(path: &Path) -> io::Result<u8> {
16
+ let mut file = File::open(path)?;
17
+ let mut buffer = [0; 5];
18
+ file.read_exact(&mut buffer)?;
19
+ if buffer[..4] == [127, 69, 76, 70] {
20
+ Ok(buffer[4])
21
+ } else {
22
+ Err(Error::new(ErrorKind::InvalidData, "invalid ELF header"))
23
+ }
24
+ }
25
+
26
+ /// Extracts the magic number and machine type from the PE header in a shared library.
27
+ fn parse_pe_header(path: &Path) -> io::Result<(u16, u16)> {
28
+ let mut file = File::open(path)?;
29
+
30
+ // Extract the header offset.
31
+ let mut buffer = [0; 4];
32
+ let start = SeekFrom::Start(0x3C);
33
+ file.seek(start)?;
34
+ file.read_exact(&mut buffer)?;
35
+ let offset = i32::from_le_bytes(buffer);
36
+
37
+ // Check the validity of the header.
38
+ file.seek(SeekFrom::Start(offset as u64))?;
39
+ file.read_exact(&mut buffer)?;
40
+ if buffer != [80, 69, 0, 0] {
41
+ return Err(Error::new(ErrorKind::InvalidData, "invalid PE header"));
42
+ }
43
+
44
+ // Extract the magic number.
45
+ let mut buffer = [0; 2];
46
+ file.seek(SeekFrom::Current(20))?;
47
+ file.read_exact(&mut buffer)?;
48
+ let magic_number = u16::from_le_bytes(buffer);
49
+
50
+ // Extract the machine type.
51
+ let mut buffer = [0; 2];
52
+ file.seek(SeekFrom::Current(-22))?;
53
+ file.read_exact(&mut buffer)?;
54
+ let machine_type = u16::from_le_bytes(buffer);
55
+
56
+ return Ok((magic_number, machine_type));
57
+ }
58
+
59
+ /// Checks that a `libclang` shared library matches the target platform.
60
+ fn validate_library(path: &Path) -> Result<(), String> {
61
+ if target_os!("linux") || target_os!("freebsd") {
62
+ let class = parse_elf_header(path).map_err(|e| e.to_string())?;
63
+
64
+ if target_pointer_width!("32") && class != 1 {
65
+ return Err("invalid ELF class (64-bit)".into());
66
+ }
67
+
68
+ if target_pointer_width!("64") && class != 2 {
69
+ return Err("invalid ELF class (32-bit)".into());
70
+ }
71
+
72
+ Ok(())
73
+ } else if target_os!("windows") {
74
+ let (magic, machine_type) = parse_pe_header(path).map_err(|e| e.to_string())?;
75
+
76
+ if target_pointer_width!("32") && magic != 267 {
77
+ return Err("invalid DLL (64-bit)".into());
78
+ }
79
+
80
+ if target_pointer_width!("64") && magic != 523 {
81
+ return Err("invalid DLL (32-bit)".into());
82
+ }
83
+
84
+ let arch_mismatch = match machine_type {
85
+ 0x014C if !target_arch!("x86") => Some("x86"),
86
+ 0x8664 if !target_arch!("x86_64") => Some("x86-64"),
87
+ 0xAA64 if !target_arch!("aarch64") => Some("ARM64"),
88
+ _ => None,
89
+ };
90
+
91
+ if let Some(arch) = arch_mismatch {
92
+ Err(format!("invalid DLL ({arch})"))
93
+ } else {
94
+ Ok(())
95
+ }
96
+ } else {
97
+ Ok(())
98
+ }
99
+ }
100
+
101
+ //================================================
102
+ // Searching
103
+ //================================================
104
+
105
+ /// Extracts the version components in a `libclang` shared library filename.
106
+ fn parse_version(filename: &str) -> Vec<u32> {
107
+ let version = if let Some(version) = filename.strip_prefix("libclang.so.") {
108
+ version
109
+ } else if filename.starts_with("libclang-") {
110
+ &filename[9..filename.len() - 3]
111
+ } else {
112
+ return vec![];
113
+ };
114
+
115
+ version.split('.').map(|s| s.parse().unwrap_or(0)).collect()
116
+ }
117
+
118
+ /// Finds `libclang` shared libraries and returns the paths to, filenames of,
119
+ /// and versions of those shared libraries.
120
+ fn search_libclang_directories(runtime: bool) -> Result<Vec<(PathBuf, String, Vec<u32>)>, String> {
121
+ let mut files = vec![format!(
122
+ "{}clang{}",
123
+ env::consts::DLL_PREFIX,
124
+ env::consts::DLL_SUFFIX
125
+ )];
126
+
127
+ if target_os!("linux") {
128
+ // Some Linux distributions don't create a `libclang.so` symlink, so we
129
+ // need to look for versioned files (e.g., `libclang-3.9.so`).
130
+ files.push("libclang-*.so".into());
131
+
132
+ // Some Linux distributions don't create a `libclang.so` symlink and
133
+ // don't have versioned files as described above, so we need to look for
134
+ // suffix versioned files (e.g., `libclang.so.1`). However, `ld` cannot
135
+ // link to these files, so this will only be included when linking at
136
+ // runtime.
137
+ if runtime {
138
+ files.push("libclang.so.*".into());
139
+ files.push("libclang-*.so.*".into());
140
+ }
141
+ }
142
+
143
+ if target_os!("freebsd") || target_os!("haiku") || target_os!("netbsd") || target_os!("openbsd") {
144
+ // Some BSD distributions don't create a `libclang.so` symlink either,
145
+ // but use a different naming scheme for versioned files (e.g.,
146
+ // `libclang.so.7.0`).
147
+ files.push("libclang.so.*".into());
148
+ }
149
+
150
+ if target_os!("windows") {
151
+ // The official LLVM build uses `libclang.dll` on Windows instead of
152
+ // `clang.dll`. However, unofficial builds such as MinGW use `clang.dll`.
153
+ files.push("libclang.dll".into());
154
+ }
155
+
156
+ // Find and validate `libclang` shared libraries and collect the versions.
157
+ let mut valid = vec![];
158
+ let mut invalid = vec![];
159
+ for (directory, filename) in common::search_libclang_directories(&files, "LIBCLANG_PATH") {
160
+ let path = directory.join(&filename);
161
+ match validate_library(&path) {
162
+ Ok(()) => {
163
+ let version = parse_version(&filename);
164
+ valid.push((directory, filename, version))
165
+ }
166
+ Err(message) => invalid.push(format!("({}: {})", path.display(), message)),
167
+ }
168
+ }
169
+
170
+ if !valid.is_empty() {
171
+ return Ok(valid);
172
+ }
173
+
174
+ let message = format!(
175
+ "couldn't find any valid shared libraries matching: [{}], set the \
176
+ `LIBCLANG_PATH` environment variable to a path where one of these files \
177
+ can be found (invalid: [{}])",
178
+ files
179
+ .iter()
180
+ .map(|f| format!("'{}'", f))
181
+ .collect::<Vec<_>>()
182
+ .join(", "),
183
+ invalid.join(", "),
184
+ );
185
+
186
+ Err(message)
187
+ }
188
+
189
+ /// Finds the "best" `libclang` shared library and returns the directory and
190
+ /// filename of that library.
191
+ pub fn find(runtime: bool) -> Result<(PathBuf, String), String> {
192
+ search_libclang_directories(runtime)?
193
+ .iter()
194
+ // We want to find the `libclang` shared library with the highest
195
+ // version number, hence `max_by_key` below.
196
+ //
197
+ // However, in the case where there are multiple such `libclang` shared
198
+ // libraries, we want to use the order in which they appeared in the
199
+ // list returned by `search_libclang_directories` as a tiebreaker since
200
+ // that function returns `libclang` shared libraries in descending order
201
+ // of preference by how they were found.
202
+ //
203
+ // `max_by_key`, perhaps surprisingly, returns the *last* item with the
204
+ // maximum key rather than the first which results in the opposite of
205
+ // the tiebreaking behavior we want. This is easily fixed by reversing
206
+ // the list first.
207
+ .rev()
208
+ .max_by_key(|f| &f.2)
209
+ .cloned()
210
+ .map(|(path, filename, _)| (path, filename))
211
+ .ok_or_else(|| "unreachable".into())
212
+ }
213
+
214
+ //================================================
215
+ // Linking
216
+ //================================================
217
+
218
+ /// Finds and links to a `libclang` shared library.
219
+ #[cfg(not(feature = "runtime"))]
220
+ pub fn link() {
221
+ let cep = common::CommandErrorPrinter::default();
222
+
223
+ use std::fs;
224
+
225
+ let (directory, filename) = find(false).unwrap();
226
+ println!("cargo:rustc-link-search={}", directory.display());
227
+
228
+ if cfg!(all(target_os = "windows", target_env = "msvc")) {
229
+ // Find the `libclang` stub static library required for the MSVC
230
+ // toolchain.
231
+ let lib = if !directory.ends_with("bin") {
232
+ directory
233
+ } else {
234
+ directory.parent().unwrap().join("lib")
235
+ };
236
+
237
+ if lib.join("libclang.lib").exists() {
238
+ println!("cargo:rustc-link-search={}", lib.display());
239
+ } else if lib.join("libclang.dll.a").exists() {
240
+ // MSYS and MinGW use `libclang.dll.a` instead of `libclang.lib`.
241
+ // It is linkable with the MSVC linker, but Rust doesn't recognize
242
+ // the `.a` suffix, so we need to copy it with a different name.
243
+ //
244
+ // FIXME: Maybe we can just hardlink or symlink it?
245
+ let out = env::var("OUT_DIR").unwrap();
246
+ fs::copy(
247
+ lib.join("libclang.dll.a"),
248
+ Path::new(&out).join("libclang.lib"),
249
+ )
250
+ .unwrap();
251
+ println!("cargo:rustc-link-search=native={}", out);
252
+ } else {
253
+ panic!(
254
+ "using '{}', so 'libclang.lib' or 'libclang.dll.a' must be \
255
+ available in {}",
256
+ filename,
257
+ lib.display(),
258
+ );
259
+ }
260
+
261
+ println!("cargo:rustc-link-lib=dylib=libclang");
262
+ } else {
263
+ let name = filename.trim_start_matches("lib");
264
+
265
+ // Strip extensions and trailing version numbers (e.g., the `.so.7.0` in
266
+ // `libclang.so.7.0`).
267
+ let name = match name.find(".dylib").or_else(|| name.find(".so")) {
268
+ Some(index) => &name[0..index],
269
+ None => name,
270
+ };
271
+
272
+ println!("cargo:rustc-link-lib=dylib={}", name);
273
+ }
274
+
275
+ cep.discard();
276
+ }
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+
3
+ macro_rules! test {
4
+ () => (cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok());
5
+ }
6
+
7
+ macro_rules! target_os {
8
+ ($os:expr) => {
9
+ if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
10
+ let var = ::std::env::var("_CLANG_SYS_TEST_OS");
11
+ var.map_or(false, |v| v == $os)
12
+ } else {
13
+ cfg!(target_os = $os)
14
+ }
15
+ };
16
+ }
17
+
18
+ macro_rules! target_arch {
19
+ ($arch:expr) => {
20
+ if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
21
+ let var = ::std::env::var("_CLANG_SYS_TEST_ARCH");
22
+ var.map_or(false, |v| v == $arch)
23
+ } else {
24
+ cfg!(target_arch = $arch)
25
+ }
26
+ };
27
+ }
28
+
29
+ macro_rules! target_pointer_width {
30
+ ($pointer_width:expr) => {
31
+ if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
32
+ let var = ::std::env::var("_CLANG_SYS_TEST_POINTER_WIDTH");
33
+ var.map_or(false, |v| v == $pointer_width)
34
+ } else {
35
+ cfg!(target_pointer_width = $pointer_width)
36
+ }
37
+ };
38
+ }
39
+
40
+ macro_rules! target_env {
41
+ ($env:expr) => {
42
+ if cfg!(test) && ::std::env::var("_CLANG_SYS_TEST").is_ok() {
43
+ let var = ::std::env::var("_CLANG_SYS_TEST_ENV");
44
+ var.map_or(false, |v| v == $env)
45
+ } else {
46
+ cfg!(target_env = $env)
47
+ }
48
+ };
49
+ }