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.
- checksums.yaml +4 -4
- data/Cargo.lock +4487 -0
- data/Cargo.toml +7 -0
- data/README.md +6 -0
- data/Rakefile +7 -4
- data/exe/itsi +152 -46
- data/ext/itsi_acme/Cargo.toml +86 -0
- data/ext/itsi_acme/examples/high_level.rs +63 -0
- data/ext/itsi_acme/examples/high_level_warp.rs +52 -0
- data/ext/itsi_acme/examples/low_level.rs +87 -0
- data/ext/itsi_acme/examples/low_level_axum.rs +66 -0
- data/ext/itsi_acme/src/acceptor.rs +81 -0
- data/ext/itsi_acme/src/acme.rs +354 -0
- data/ext/itsi_acme/src/axum.rs +86 -0
- data/ext/itsi_acme/src/cache.rs +39 -0
- data/ext/itsi_acme/src/caches/boxed.rs +80 -0
- data/ext/itsi_acme/src/caches/composite.rs +69 -0
- data/ext/itsi_acme/src/caches/dir.rs +106 -0
- data/ext/itsi_acme/src/caches/mod.rs +11 -0
- data/ext/itsi_acme/src/caches/no.rs +78 -0
- data/ext/itsi_acme/src/caches/test.rs +136 -0
- data/ext/itsi_acme/src/config.rs +172 -0
- data/ext/itsi_acme/src/https_helper.rs +69 -0
- data/ext/itsi_acme/src/incoming.rs +142 -0
- data/ext/itsi_acme/src/jose.rs +161 -0
- data/ext/itsi_acme/src/lib.rs +142 -0
- data/ext/itsi_acme/src/resolver.rs +59 -0
- data/ext/itsi_acme/src/state.rs +424 -0
- data/ext/itsi_error/Cargo.toml +3 -0
- data/ext/itsi_error/src/lib.rs +98 -24
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
- data/ext/itsi_error/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
- data/ext/itsi_error/target/debug/build/rb-sys-49f554618693db24/out/bindings-0.9.110-mri-arm64-darwin23-3.4.2.rs +8865 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-1mmt5sux7jb0i/s-h510z7m8v9-0bxu7yd.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-2vn3jey74oiw0/s-h5113n0e7e-1v5qzs6.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510ykifhe-0tbnep2.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510yyocpj-0tz7ug7.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-37uv9dicz7awp/s-h510z0xc8g-14ol18k.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3g5qf4y7d54uj/s-h5113n0e7d-1trk8on.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3lpfftm45d3e2/s-h510z7m8r3-1pxp20o.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510ykifek-1uxasnk.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510yyocki-11u37qm.lock +0 -0
- data/ext/itsi_error/target/debug/incremental/itsi_error-3o4qownhl3d7n/s-h510z0xc93-0pmy0zm.lock +0 -0
- data/ext/itsi_instrument_entry/Cargo.toml +15 -0
- data/ext/itsi_instrument_entry/src/lib.rs +31 -0
- data/ext/itsi_rb_helpers/Cargo.toml +3 -0
- data/ext/itsi_rb_helpers/src/heap_value.rs +139 -0
- data/ext/itsi_rb_helpers/src/lib.rs +141 -10
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/common.rs +355 -0
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/dynamic.rs +276 -0
- data/ext/itsi_rb_helpers/target/debug/build/clang-sys-da71b0344e568175/out/macros.rs +49 -0
- 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
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-040pxg6yhb3g3/s-h5113n7a1b-03bwlt4.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h51113xnh3-1eik1ip.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-131g1u4dzkt1a/s-h5111704jj-0g4rj8x.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-1q2d3drtxrzs5/s-h5113n79yl-0bxcqc5.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h51113xoox-10de2hp.lock +0 -0
- data/ext/itsi_rb_helpers/target/debug/incremental/itsi_rb_helpers-374a9h7ovycj0/s-h5111704w7-0vdq7gq.lock +0 -0
- data/ext/itsi_scheduler/Cargo.toml +24 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +56 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +44 -0
- data/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +44 -0
- data/ext/itsi_scheduler/src/itsi_scheduler.rs +314 -0
- data/ext/itsi_scheduler/src/lib.rs +39 -0
- data/ext/itsi_server/Cargo.lock +2956 -0
- data/ext/itsi_server/Cargo.toml +75 -14
- data/ext/itsi_server/extconf.rb +1 -1
- data/ext/itsi_server/src/default_responses/html/401.html +68 -0
- data/ext/itsi_server/src/default_responses/html/403.html +68 -0
- data/ext/itsi_server/src/default_responses/html/404.html +68 -0
- data/ext/itsi_server/src/default_responses/html/413.html +71 -0
- data/ext/itsi_server/src/default_responses/html/429.html +68 -0
- data/ext/itsi_server/src/default_responses/html/500.html +71 -0
- data/ext/itsi_server/src/default_responses/html/502.html +71 -0
- data/ext/itsi_server/src/default_responses/html/503.html +68 -0
- data/ext/itsi_server/src/default_responses/html/504.html +69 -0
- data/ext/itsi_server/src/default_responses/html/index.html +238 -0
- data/ext/itsi_server/src/default_responses/json/401.json +6 -0
- data/ext/itsi_server/src/default_responses/json/403.json +6 -0
- data/ext/itsi_server/src/default_responses/json/404.json +6 -0
- data/ext/itsi_server/src/default_responses/json/413.json +6 -0
- data/ext/itsi_server/src/default_responses/json/429.json +6 -0
- data/ext/itsi_server/src/default_responses/json/500.json +6 -0
- data/ext/itsi_server/src/default_responses/json/502.json +6 -0
- data/ext/itsi_server/src/default_responses/json/503.json +6 -0
- data/ext/itsi_server/src/default_responses/json/504.json +6 -0
- data/ext/itsi_server/src/default_responses/mod.rs +11 -0
- data/ext/itsi_server/src/env.rs +43 -0
- data/ext/itsi_server/src/lib.rs +133 -40
- data/ext/itsi_server/src/prelude.rs +2 -0
- data/ext/itsi_server/src/ruby_types/itsi_body_proxy/big_bytes.rs +109 -0
- data/ext/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +143 -0
- data/ext/itsi_server/src/ruby_types/itsi_grpc_call.rs +344 -0
- data/ext/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +264 -0
- data/ext/itsi_server/src/ruby_types/itsi_http_request.rs +362 -0
- data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +391 -0
- data/ext/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +233 -0
- data/ext/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +565 -0
- data/ext/itsi_server/src/ruby_types/itsi_server.rs +86 -0
- data/ext/itsi_server/src/ruby_types/mod.rs +48 -0
- data/ext/itsi_server/src/server/binds/bind.rs +204 -0
- data/ext/itsi_server/src/server/binds/bind_protocol.rs +37 -0
- data/ext/itsi_server/src/server/binds/listener.rs +444 -0
- data/ext/itsi_server/src/server/binds/mod.rs +4 -0
- data/ext/itsi_server/src/server/binds/tls/locked_dir_cache.rs +132 -0
- data/ext/itsi_server/src/server/binds/tls.rs +278 -0
- data/ext/itsi_server/src/server/byte_frame.rs +32 -0
- data/ext/itsi_server/src/server/http_message_types.rs +97 -0
- data/ext/itsi_server/src/server/io_stream.rs +105 -0
- data/ext/itsi_server/src/server/lifecycle_event.rs +12 -0
- data/ext/itsi_server/src/server/middleware_stack/middleware.rs +170 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +63 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +94 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +94 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +343 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +151 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/compression.rs +316 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/cors.rs +301 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/csp.rs +193 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +64 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +192 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +171 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/etag.rs +198 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +82 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +209 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +47 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/mod.rs +116 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +411 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +142 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +55 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +54 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +51 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +126 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +187 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +55 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +173 -0
- data/ext/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +31 -0
- data/ext/itsi_server/src/server/middleware_stack/mod.rs +381 -0
- data/ext/itsi_server/src/server/mod.rs +13 -5
- data/ext/itsi_server/src/server/process_worker.rs +247 -0
- data/ext/itsi_server/src/server/redirect_type.rs +26 -0
- data/ext/itsi_server/src/server/request_job.rs +11 -0
- data/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +354 -0
- data/ext/itsi_server/src/server/serve_strategy/mod.rs +30 -0
- data/ext/itsi_server/src/server/serve_strategy/single_mode.rs +481 -0
- data/ext/itsi_server/src/server/signal.rs +77 -0
- data/ext/itsi_server/src/server/size_limited_incoming.rs +107 -0
- data/ext/itsi_server/src/server/thread_worker.rs +479 -0
- data/ext/itsi_server/src/services/cache_store.rs +74 -0
- data/ext/itsi_server/src/services/itsi_http_service.rs +257 -0
- data/ext/itsi_server/src/services/mime_types.rs +1416 -0
- data/ext/itsi_server/src/services/mod.rs +6 -0
- data/ext/itsi_server/src/services/password_hasher.rs +83 -0
- data/ext/itsi_server/src/services/rate_limiter.rs +580 -0
- data/ext/itsi_server/src/services/static_file_server.rs +1340 -0
- data/ext/itsi_tracing/Cargo.toml +5 -0
- data/ext/itsi_tracing/src/lib.rs +366 -7
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0994n8rpvvt9m/s-h510hfz1f6-1kbycmq.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-0bob7bf4yq34i/s-h5113125h5-0lh4rag.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2fcodulrxbbxo/s-h510h2infk-0hp5kjw.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2iak63r1woi1l/s-h510h2in4q-0kxfzw1.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2kk4qj9gn5dg2/s-h5113124kv-0enwon2.lock +0 -0
- data/ext/itsi_tracing/target/debug/incremental/itsi_tracing-2mwo0yas7dtw4/s-h510hfz1ha-1udgpei.lock +0 -0
- data/lib/itsi/http_request/response_status_shortcodes.rb +76 -0
- data/lib/itsi/http_request.rb +218 -0
- data/lib/itsi/http_response.rb +42 -0
- data/lib/itsi/passfile.rb +108 -0
- data/lib/itsi/server/config/config_helpers.rb +105 -0
- data/lib/itsi/server/config/dsl.rb +211 -0
- data/lib/itsi/server/config/known_paths/KitchensinkDirectories.txt +2346 -0
- data/lib/itsi/server/config/known_paths/Randomfiles.txt +24 -0
- data/lib/itsi/server/config/known_paths/UnixDotfiles.txt +52 -0
- data/lib/itsi/server/config/known_paths/backdoors/ASP_CommonBackdoors.txt +29 -0
- data/lib/itsi/server/config/known_paths/backdoors/bot_control_panels.txt +1668 -0
- data/lib/itsi/server/config/known_paths/backdoors/shells.txt +1167 -0
- data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST.txt +7 -0
- data/lib/itsi/server/config/known_paths/cgi/CGI_HTTP_POST_Windows.txt +6 -0
- data/lib/itsi/server/config/known_paths/cgi/CGI_Microsoft.txt +79 -0
- data/lib/itsi/server/config/known_paths/cgi/CGI_XPlatform.txt +3948 -0
- data/lib/itsi/server/config/known_paths/cms/README.md +5 -0
- data/lib/itsi/server/config/known_paths/cms/drupal_plugins.txt +6320 -0
- data/lib/itsi/server/config/known_paths/cms/drupal_themes.txt +828 -0
- data/lib/itsi/server/config/known_paths/cms/joomla_plugins.txt +224 -0
- data/lib/itsi/server/config/known_paths/cms/joomla_themes.txt +30 -0
- data/lib/itsi/server/config/known_paths/cms/php-nuke.txt +2142 -0
- data/lib/itsi/server/config/known_paths/cms/wordpress.txt +1566 -0
- data/lib/itsi/server/config/known_paths/cms/wp_common_theme_files.txt +46 -0
- data/lib/itsi/server/config/known_paths/cms/wp_plugins.txt +13366 -0
- data/lib/itsi/server/config/known_paths/cms/wp_plugins_full.txt +68662 -0
- data/lib/itsi/server/config/known_paths/cms/wp_plugins_top225.txt +225 -0
- data/lib/itsi/server/config/known_paths/cms/wp_themes.readme +12 -0
- data/lib/itsi/server/config/known_paths/cms/wp_themes.txt +7336 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/3CharExtBrute.txt +17576 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/CommonWebExtensions.txt +80 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Backup.txt +14 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Common.txt +865 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Compressed.txt +186 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Mostcommon.txt +30 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/Extensions.Skipfish.txt +93 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/WordlistSkipfish.txt +1918 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/copy_of.txt +8 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories-lowercase.txt +56180 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-directories.txt +62290 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions-lowercase.txt +2367 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-extensions.txt +2450 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files-lowercase.txt +35323 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-files.txt +37037 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words-lowercase.txt +107982 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-large-words.txt +119600 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories-lowercase.txt +26593 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-directories.txt +30009 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions-lowercase.txt +1233 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-extensions.txt +1289 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files-lowercase.txt +16243 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-files.txt +17128 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words-lowercase.txt +56293 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-medium-words.txt +63087 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories-lowercase.txt +17776 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-directories.txt +20122 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions-lowercase.txt +914 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-extensions.txt +963 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files-lowercase.txt +10848 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-files.txt +11424 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words-lowercase.txt +38267 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/raft-small-words.txt +43003 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/spanish.txt +445 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/test_demo.txt +36 -0
- data/lib/itsi/server/config/known_paths/filename-dirname-bruteforce/upload_variants.txt +44 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/Logins.txt +71 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/cfm.txt +294 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/html.txt +295 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/jsp.txt +294 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/php.txt +294 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/windows-asp.txt +294 -0
- data/lib/itsi/server/config/known_paths/login-file-locations/windows-aspx.txt +294 -0
- data/lib/itsi/server/config/known_paths/password-file-locations/Passwords.txt +47 -0
- data/lib/itsi/server/config/known_paths/php/PHP.txt +30 -0
- data/lib/itsi/server/config/known_paths/php/PHP_CommonBackdoors.txt +5 -0
- data/lib/itsi/server/config/known_paths/proxy-conf.txt +31 -0
- data/lib/itsi/server/config/known_paths/tftp.txt +79 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/ADFS.txt +86 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/AdobeXML.txt +16 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Apache.txt +101 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/ApacheTomcat.txt +47 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Apache_Axis.txt +16 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/ColdFusion.txt +111 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/FatwireCMS.txt +390 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Frontpage.txt +38 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/HP_System_Mgmt_Homepage.txt +239 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/HTTP_POST_Microsoft.txt +2 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Hyperion.txt +578 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/IIS.txt +187 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/JBoss.txt +5 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/JRun.txt +13 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/JavaServlets_Common.txt +3 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Joomla_exploitable.txt +1937 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/LotusNotes.txt +206 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Netware.txt +18 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Oracle9i.txt +60 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/OracleAppServer.txt +192 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/README.md +6 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Ruby_Rails.txt +121 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/SAP.txt +463 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Sharepoint.txt +1707 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/SiteMinder.txt +19 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/SunAppServerGlassfish.txt +51 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/SuniPlanet.txt +35 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Vignette.txt +73 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Weblogic.txt +160 -0
- data/lib/itsi/server/config/known_paths/webservers-appservers/Websphere.txt +366 -0
- data/lib/itsi/server/config/known_paths/wellknown-rfc5785.txt +30 -0
- data/lib/itsi/server/config/known_paths.rb +20 -0
- data/lib/itsi/server/config/middleware/_index.md +56 -0
- data/lib/itsi/server/config/middleware/allow_list.md +46 -0
- data/lib/itsi/server/config/middleware/allow_list.rb +42 -0
- data/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
- data/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
- data/lib/itsi/server/config/middleware/auth_basic.md +45 -0
- data/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
- data/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
- data/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
- data/lib/itsi/server/config/middleware/cache_control.md +78 -0
- data/lib/itsi/server/config/middleware/cache_control.rb +45 -0
- data/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
- data/lib/itsi/server/config/middleware/compression.md +50 -0
- data/lib/itsi/server/config/middleware/compression.rb +37 -0
- data/lib/itsi/server/config/middleware/cors.md +93 -0
- data/lib/itsi/server/config/middleware/cors.rb +32 -0
- data/lib/itsi/server/config/middleware/csp.md +37 -0
- data/lib/itsi/server/config/middleware/csp.rb +44 -0
- data/lib/itsi/server/config/middleware/deny_list.md +45 -0
- data/lib/itsi/server/config/middleware/deny_list.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
- data/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
- data/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
- data/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
- data/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
- data/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
- data/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
- data/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
- data/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
- data/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
- data/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
- data/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
- data/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
- data/lib/itsi/server/config/middleware/error_response.md +61 -0
- data/lib/itsi/server/config/middleware/error_response.rb +36 -0
- data/lib/itsi/server/config/middleware/etag.md +59 -0
- data/lib/itsi/server/config/middleware/etag.rb +27 -0
- data/lib/itsi/server/config/middleware/grpc.md +172 -0
- data/lib/itsi/server/config/middleware/grpc.rb +54 -0
- data/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
- data/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
- data/lib/itsi/server/config/middleware/location.md +107 -0
- data/lib/itsi/server/config/middleware/location.rb +99 -0
- data/lib/itsi/server/config/middleware/log_requests.md +65 -0
- data/lib/itsi/server/config/middleware/log_requests.rb +31 -0
- data/lib/itsi/server/config/middleware/max_body.md +18 -0
- data/lib/itsi/server/config/middleware/max_body.rb +21 -0
- data/lib/itsi/server/config/middleware/proxy.md +62 -0
- data/lib/itsi/server/config/middleware/proxy.rb +41 -0
- data/lib/itsi/server/config/middleware/rackup_file.md +54 -0
- data/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
- data/lib/itsi/server/config/middleware/rate_limit.md +126 -0
- data/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
- data/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
- data/lib/itsi/server/config/middleware/redirect.md +55 -0
- data/lib/itsi/server/config/middleware/redirect.rb +25 -0
- data/lib/itsi/server/config/middleware/request_headers.md +34 -0
- data/lib/itsi/server/config/middleware/request_headers.rb +24 -0
- data/lib/itsi/server/config/middleware/response_headers.md +33 -0
- data/lib/itsi/server/config/middleware/response_headers.rb +25 -0
- data/lib/itsi/server/config/middleware/run.md +60 -0
- data/lib/itsi/server/config/middleware/run.rb +43 -0
- data/lib/itsi/server/config/middleware/static_assets.md +73 -0
- data/lib/itsi/server/config/middleware/static_assets.rb +87 -0
- data/lib/itsi/server/config/middleware/static_response.md +44 -0
- data/lib/itsi/server/config/middleware/static_response.rb +29 -0
- data/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
- data/lib/itsi/server/config/middleware/token_source.rb +32 -0
- data/lib/itsi/server/config/middleware.rb +13 -0
- data/lib/itsi/server/config/option.rb +14 -0
- data/lib/itsi/server/config/options/_index.md +37 -0
- data/lib/itsi/server/config/options/auto_reload_config.md +13 -0
- data/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
- data/lib/itsi/server/config/options/bind.md +71 -0
- data/lib/itsi/server/config/options/bind.rb +26 -0
- data/lib/itsi/server/config/options/certificates.md +65 -0
- data/lib/itsi/server/config/options/daemonize.md +14 -0
- data/lib/itsi/server/config/options/daemonize.rb +19 -0
- data/lib/itsi/server/config/options/fiber_scheduler.md +34 -0
- data/lib/itsi/server/config/options/fiber_scheduler.rb +21 -0
- data/lib/itsi/server/config/options/header_read_timeout.md +17 -0
- data/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
- data/lib/itsi/server/config/options/hooks/_index.md +11 -0
- data/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
- data/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
- data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
- data/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
- data/lib/itsi/server/config/options/hooks/after_start.md +12 -0
- data/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
- data/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
- data/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
- data/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
- data/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
- data/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
- data/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
- data/lib/itsi/server/config/options/include.md +20 -0
- data/lib/itsi/server/config/options/include.rb +36 -0
- data/lib/itsi/server/config/options/listen_backlog.md +11 -0
- data/lib/itsi/server/config/options/listen_backlog.rb +19 -0
- data/lib/itsi/server/config/options/log_format.md +18 -0
- data/lib/itsi/server/config/options/log_format.rb +19 -0
- data/lib/itsi/server/config/options/log_level.md +34 -0
- data/lib/itsi/server/config/options/log_level.rb +20 -0
- data/lib/itsi/server/config/options/log_target.md +38 -0
- data/lib/itsi/server/config/options/log_target.rb +19 -0
- data/lib/itsi/server/config/options/log_target_filters.md +17 -0
- data/lib/itsi/server/config/options/log_target_filters.rb +19 -0
- data/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
- data/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
- data/lib/itsi/server/config/options/nodelay.md +16 -0
- data/lib/itsi/server/config/options/nodelay.rb +19 -0
- data/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
- data/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
- data/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
- data/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
- data/lib/itsi/server/config/options/preload.md +21 -0
- data/lib/itsi/server/config/options/preload.rb +18 -0
- data/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
- data/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
- data/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
- data/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
- data/lib/itsi/server/config/options/request_timeout.md +23 -0
- data/lib/itsi/server/config/options/request_timeout.rb +19 -0
- data/lib/itsi/server/config/options/reuse_address.md +16 -0
- data/lib/itsi/server/config/options/reuse_address.rb +19 -0
- data/lib/itsi/server/config/options/reuse_port.md +16 -0
- data/lib/itsi/server/config/options/reuse_port.rb +19 -0
- data/lib/itsi/server/config/options/scheduler_threads.md +34 -0
- data/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
- data/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
- data/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
- data/lib/itsi/server/config/options/stream_body.md +32 -0
- data/lib/itsi/server/config/options/stream_body.rb +18 -0
- data/lib/itsi/server/config/options/threads.md +44 -0
- data/lib/itsi/server/config/options/threads.rb +17 -0
- data/lib/itsi/server/config/options/watch.md +16 -0
- data/lib/itsi/server/config/options/watch.rb +28 -0
- data/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
- data/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
- data/lib/itsi/server/config/options/workers.md +42 -0
- data/lib/itsi/server/config/options/workers.rb +17 -0
- data/lib/itsi/server/config/typed_struct.rb +242 -0
- data/lib/itsi/server/config.rb +289 -0
- data/lib/itsi/server/default_app/default_app.rb +34 -0
- data/lib/itsi/server/default_app/index.html +115 -0
- data/lib/itsi/server/default_config/Itsi.rb +107 -0
- data/lib/itsi/server/grpc/grpc_call.rb +246 -0
- data/lib/itsi/server/grpc/grpc_interface.rb +107 -0
- data/lib/itsi/server/grpc/reflection/v1/reflection_pb.rb +26 -0
- data/lib/itsi/server/grpc/reflection/v1/reflection_services_pb.rb +122 -0
- data/lib/itsi/server/rack/handler/itsi.rb +27 -0
- data/lib/itsi/server/rack_interface.rb +94 -0
- data/lib/itsi/server/route_tester.rb +157 -0
- data/lib/itsi/server/scheduler_interface.rb +21 -0
- data/lib/itsi/server/scheduler_mode.rb +10 -0
- data/lib/itsi/server/signal_trap.rb +33 -0
- data/lib/itsi/server/typed_handlers/param_parser.rb +196 -0
- data/lib/itsi/server/typed_handlers/source_parser.rb +56 -0
- data/lib/itsi/server/typed_handlers.rb +25 -0
- data/lib/itsi/server/version.rb +1 -1
- data/lib/itsi/server.rb +265 -9
- data/lib/itsi/standard_headers.rb +86 -0
- data/lib/ruby_lsp/itsi/addon.rb +129 -0
- data/lib/shell_completions/completions.rb +26 -0
- metadata +454 -28
- data/CHANGELOG.md +0 -5
- data/CODE_OF_CONDUCT.md +0 -132
- data/LICENSE.txt +0 -21
- data/ext/itsi_server/src/request/itsi_request.rs +0 -143
- data/ext/itsi_server/src/request/mod.rs +0 -1
- data/ext/itsi_server/src/server/bind.rs +0 -138
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.crt +0 -32
- data/ext/itsi_server/src/server/itsi_ca/itsi_ca.key +0 -52
- data/ext/itsi_server/src/server/itsi_server.rs +0 -182
- data/ext/itsi_server/src/server/listener.rs +0 -218
- data/ext/itsi_server/src/server/tls.rs +0 -138
- data/ext/itsi_server/src/server/transfer_protocol.rs +0 -23
- data/ext/itsi_server/src/stream_writer/mod.rs +0 -21
- data/lib/itsi/request.rb +0 -39
@@ -0,0 +1,61 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class IntrusionProtection < Middleware
|
5
|
+
|
6
|
+
require_relative "rate_limit_store"
|
7
|
+
require_relative "token_source"
|
8
|
+
|
9
|
+
insert_text <<~SNIPPET
|
10
|
+
intrusion_protection \\
|
11
|
+
banned_url_patterns: ${1|KnownPaths.php_php|},
|
12
|
+
banned_header_patterns: { "User-Agent" => ${2|%w[sqlmap curl]|} },
|
13
|
+
banned_time_seconds: ${3|300,600|},
|
14
|
+
store_config: ${4|"in_memory",{redis:{connection_url:"redis://localhost:6379"}}|},
|
15
|
+
error_response: ${5|"forbidden",{ code:403\\, plaintext:{inline:"Access Denied"} }|}
|
16
|
+
SNIPPET
|
17
|
+
|
18
|
+
|
19
|
+
detail "Detects and automatically bans clients that attempt to access suspicious URLs"
|
20
|
+
|
21
|
+
schema do
|
22
|
+
{
|
23
|
+
banned_url_patterns: Array(Type(String)).default([]),
|
24
|
+
banned_header_patterns: Hash(Type(String), Array(Type(String))).default({}),
|
25
|
+
banned_time_seconds: Type(Float).default(300),
|
26
|
+
store_config: (Required() & Or(Enum(["in_memory"]), Type(RateLimitStore))).default("in_memory"),
|
27
|
+
error_response: Type(ErrorResponseDef).default("forbidden"),
|
28
|
+
combine: Bool().default(true),
|
29
|
+
trusted_proxies: (Hash(Type(String), Type(TokenSource)) & Required()).default({})
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def build!
|
34
|
+
@params[:banned_url_patterns] = Array(@params[:banned_url_patterns]).flatten.map do |pattern|
|
35
|
+
if pattern.is_a?(Regexp)
|
36
|
+
pattern.source
|
37
|
+
else
|
38
|
+
"#{pattern}$"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
@params[:banned_header_patterns].transform_values! do |patterns|
|
43
|
+
Array(patterns).flatten.map do |pattern|
|
44
|
+
if pattern.is_a?(Regexp)
|
45
|
+
pattern.source
|
46
|
+
else
|
47
|
+
pattern
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if location.middleware[:intrusion_protection]
|
53
|
+
location.middleware[:intrusion_protection] = Array(location.middleware[:intrusion_protection]) + [@params]
|
54
|
+
else
|
55
|
+
location.middleware[:intrusion_protection] = @params
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
---
|
2
|
+
title: Location
|
3
|
+
url: /middleware/location
|
4
|
+
---
|
5
|
+
|
6
|
+
The `location` block is the essential building block of Itsi-powered apps.
|
7
|
+
It allows you to selectively apply middleware based on request structure.
|
8
|
+
This is similar to a `location` block in NGINX, but with added capabilities—most notably, support for nested location blocks.
|
9
|
+
{{< callout type="warn" >}}
|
10
|
+
Location blocks are matched in definition order, and only a single location block applies per request.
|
11
|
+
This rule is applied recursively: the first top-level match is chosen, then the first matching child, and so on.
|
12
|
+
{{</ callout >}}
|
13
|
+
|
14
|
+
## Examples
|
15
|
+
|
16
|
+
```ruby {filename="Itsi.rb"}
|
17
|
+
# Wildcard routes: matches any path beginning with /admin/
|
18
|
+
location "/admin/*" do
|
19
|
+
auth_basic ...
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
```ruby {filename="Itsi.rb"}
|
24
|
+
# Nested routes and named captures
|
25
|
+
location "/organizations/:organisation_id" do
|
26
|
+
location "/users" do
|
27
|
+
location "/:user_id([0-9]+)" do
|
28
|
+
rate_limiter requests: 10, seconds: 5, ...
|
29
|
+
auth_jwt ...
|
30
|
+
...
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Shared middleware for multiple exact sub-routes.
|
35
|
+
location "/settings", "/options" do
|
36
|
+
auth_basic ...
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
```ruby {filename="Itsi.rb"}
|
42
|
+
# Regex route: matches either 'users' or 'organizations'
|
43
|
+
location /(?:users)|(?:organizations)/ do
|
44
|
+
intrusion_protection banned_url_patterns: [/wp-admin/]
|
45
|
+
...
|
46
|
+
end
|
47
|
+
```
|
48
|
+
```ruby {filename="Itsi.rb"}
|
49
|
+
# Match on non-route options.
|
50
|
+
# Redirect http requests to https requests
|
51
|
+
location protocols: ["http"]
|
52
|
+
redirect type: :permanent, to: "https://{host}{path_and_query}"
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
## Route Matches
|
57
|
+
Routes have several options for matching:
|
58
|
+
|
59
|
+
{{% details title="Exact Match (e.g. `\"/api/users\"`)" closed="true" %}}
|
60
|
+
Matches the complete request path exactly. No prefix matching is performed.
|
61
|
+
{{% /details %}}
|
62
|
+
|
63
|
+
|
64
|
+
{{% details title="Wildcard Match (e.g. `\"/api/users/*\"`)" closed="true" %}}
|
65
|
+
Fuzzily matches any path that with support for wild-card dynamic segments.
|
66
|
+
{{% /details %}}
|
67
|
+
|
68
|
+
{{% details title="Named Captures (e.g. `\"/api/users/:id\"`)" closed="true" %}}
|
69
|
+
Similar to Wildcard match, but captures dynamic segments by name, using `:name` syntax. Matches are delimited by `/`, and captured values are accessible in logs and handlers.
|
70
|
+
|
71
|
+
You can restrict captures to specific character sets, using embedded regular expressions:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Matches numeric user IDs
|
75
|
+
location "/users/:id([0-9]+)" do
|
76
|
+
...
|
77
|
+
end
|
78
|
+
```
|
79
|
+
{{% /details %}}
|
80
|
+
{{% details title="Regex Match (e.g. `/api\/(users|organizations)/`)" closed="true" %}}
|
81
|
+
Full regular expression support for matching complex or variable patterns.
|
82
|
+
{{% /details %}}
|
83
|
+
|
84
|
+
{{% details title="Nested Matches" closed="true" %}}
|
85
|
+
Nested blocks allow deeper route matching. Matching proceeds recursively:
|
86
|
+
a top-level match is found first, followed by the first matching child block, and so on.
|
87
|
+
{{% /details %}}
|
88
|
+
|
89
|
+
|
90
|
+
## Options
|
91
|
+
Location blocks match can also match on several other request attributes:
|
92
|
+
* `methods`: An array of HTTP methods to match on. E.g. `%w[GET POST PUT DELETE]`
|
93
|
+
* `protocols`: An array of protocols to match on. %w[http https]
|
94
|
+
* `hosts`: An array of hosts to match on. E.g. `%w[example.com www.example.com]`
|
95
|
+
* `ports`: An array of ports to match on. E.g. `%w[80 443]`
|
96
|
+
* `extensions`: An array of file extensions to match on. E.g. `%w[html css js]`
|
97
|
+
* `content_types`: An array of content types to match on. E.g. `%w[text/html application/json]`
|
98
|
+
* `accepts`: An array of accept headers to match on. E.g. `%w[text/html application/json]`
|
99
|
+
|
100
|
+
Pass these to the location block using keyword arguments, e.g.
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
# Redirect all http JSON requests to use https exclusively.
|
104
|
+
location protocols: ["http"], content_types: ["application/json"]
|
105
|
+
redirect type: :permanent, to: "https://{host}{path_and_query}"
|
106
|
+
end
|
107
|
+
```
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Location < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
location "${1:/}" do
|
8
|
+
$2
|
9
|
+
end
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
detail "Group middleware by route and/or route options"
|
13
|
+
|
14
|
+
schema do
|
15
|
+
{
|
16
|
+
routes: Array(Or(Type(String), Type(Regexp))),
|
17
|
+
methods: Array(Type(String)),
|
18
|
+
protocols: Array(Type(String)),
|
19
|
+
schemes: Array(Type(String)),
|
20
|
+
hosts: Array(Type(String)),
|
21
|
+
ports: Array(Type(String)),
|
22
|
+
extensions: Array(Type(String)),
|
23
|
+
content_types: Array(Type(String)),
|
24
|
+
accepts: Array(Type(String)),
|
25
|
+
block: Type(Proc)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :location, :routes, :block, :protocols, :hosts, :ports,
|
30
|
+
:extensions, :content_types, :accepts, :block
|
31
|
+
|
32
|
+
def initialize(location,
|
33
|
+
*routes,
|
34
|
+
methods: [],
|
35
|
+
protocols: [],
|
36
|
+
schemes: [],
|
37
|
+
hosts: [],
|
38
|
+
ports: [],
|
39
|
+
extensions: [],
|
40
|
+
content_types: [],
|
41
|
+
accepts: [],
|
42
|
+
&block
|
43
|
+
)
|
44
|
+
|
45
|
+
@location = location
|
46
|
+
params = self.schema.new({
|
47
|
+
routes: routes,
|
48
|
+
methods: methods,
|
49
|
+
protocols: protocols,
|
50
|
+
schemes: schemes,
|
51
|
+
hosts: hosts,
|
52
|
+
ports: ports,
|
53
|
+
extensions: extensions,
|
54
|
+
content_types: content_types,
|
55
|
+
accepts: accepts,
|
56
|
+
block: block
|
57
|
+
}).to_h
|
58
|
+
@routes = params[:routes].empty? ? ["*"] : params[:routes]
|
59
|
+
@methods = params[:methods]
|
60
|
+
@protocols = params[:protocols] | params[:schemes]
|
61
|
+
@hosts = params[:hosts]
|
62
|
+
@ports = params[:ports]
|
63
|
+
@extensions = params[:extensions]
|
64
|
+
@content_types = params[:content_types]
|
65
|
+
@accepts = params[:accepts]
|
66
|
+
@block = block
|
67
|
+
end
|
68
|
+
|
69
|
+
def http_methods
|
70
|
+
@methods
|
71
|
+
end
|
72
|
+
|
73
|
+
def build!
|
74
|
+
build_child = lambda {
|
75
|
+
location.children << DSL.new(
|
76
|
+
location,
|
77
|
+
routes: routes,
|
78
|
+
methods: Array(http_methods) | location.http_methods,
|
79
|
+
protocols: Array(protocols) | location.protocols,
|
80
|
+
hosts: Array(hosts) | location.hosts,
|
81
|
+
ports: Array(ports) | location.ports,
|
82
|
+
extensions: Array(extensions) | location.extensions,
|
83
|
+
content_types: Array(content_types) | location.content_types,
|
84
|
+
accepts: Array(accepts) | location.accepts,
|
85
|
+
controller: location.controller,
|
86
|
+
&block
|
87
|
+
)
|
88
|
+
}
|
89
|
+
if location.parent.nil?
|
90
|
+
location.options[:middleware_loaders] << build_child
|
91
|
+
else
|
92
|
+
build_child[]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
---
|
2
|
+
title: Request Logs
|
3
|
+
url: /middleware/log_requests
|
4
|
+
---
|
5
|
+
|
6
|
+
The request logging middleware allows you to define customized log statements to occur before and/or after each request is processed.
|
7
|
+
|
8
|
+
You can provide a log level and format string to be written before and after each request.
|
9
|
+
|
10
|
+
|
11
|
+
```ruby {filename=Itsi.rb}
|
12
|
+
log_requests \
|
13
|
+
before: {
|
14
|
+
level: "INFO",
|
15
|
+
format: "[{request_id}] {method} {path_and_query} - {addr} "
|
16
|
+
},
|
17
|
+
after: {
|
18
|
+
level: "INFO",
|
19
|
+
format: "[{request_id}] └─ {status} in {response_time}"
|
20
|
+
}
|
21
|
+
```
|
22
|
+
|
23
|
+
|
24
|
+
The log statement can populated with several different placeholders.
|
25
|
+
Available values are:
|
26
|
+
|
27
|
+
### `before` Format String
|
28
|
+
* `request_id` - (A short, unique hexadecimal request identifier)
|
29
|
+
* `request_id_full` - (A full 128-bit unique request identifier)
|
30
|
+
* `method` - The HTTP method
|
31
|
+
* `path` - The HTTP Path
|
32
|
+
* `addr` - The client's IP address
|
33
|
+
* `host` - The request host
|
34
|
+
* `path_and_query` - The path and query combined
|
35
|
+
* `query` - The request query string
|
36
|
+
* `port` - The bound port
|
37
|
+
* `start_time` - The request start time
|
38
|
+
* `<Header-Name>`: Any existing request header. For example `{Accept}` or `{Cookie}` will be replaced with its current value.
|
39
|
+
|
40
|
+
|
41
|
+
### `after` Format String
|
42
|
+
* `request_id` - (A short, unique hexadecimal request identifier)
|
43
|
+
* `request_id_full` - (A full 128-bit unique request identifier)
|
44
|
+
* `status` - The HTTP status code
|
45
|
+
* `addr` - The client's IP address
|
46
|
+
* `response_time` - The response time in milliseconds
|
47
|
+
* `<Header-Name>`: Any existing response header. For example `{Content-Type}` or `{Set-Cookie}` will be replaced with its current value.
|
48
|
+
|
49
|
+
|
50
|
+
### Path Attributes
|
51
|
+
In addition to this, any capture groups referenced by container location blocks
|
52
|
+
are also made available, to be interpolated into the log statement. E.g.:
|
53
|
+
|
54
|
+
```ruby {filename=Itsi.rb}
|
55
|
+
|
56
|
+
location "/users/:user_id" do # 1. If we capture user_id here.
|
57
|
+
|
58
|
+
log_requests before: {
|
59
|
+
level: "INFO",
|
60
|
+
format: "[{request_id}] User: {user_id}" # 2. Then we can log the user_id here.
|
61
|
+
}
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
```
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class LogRequests < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
log_requests \\
|
8
|
+
before: { level: ${1|"INFO","WARN","ERROR","DEBUG"|} format: ${2|"[{request_id}] {method} {path_and_query} - {addr} "|} },
|
9
|
+
after: { level: ${3|"INFO","WARN","ERROR","DEBUG"|}, format: ${4|"[{request_id}] └─ {status} in {response_time}"|} }
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
detail "Enable logging before or after requests"
|
13
|
+
|
14
|
+
LogRequestConfig = TypedStruct.new do
|
15
|
+
{
|
16
|
+
level: (Required() & Enum(%w[INFO WARN ERROR DEBUG])).default("INFO"),
|
17
|
+
format: Type(String)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
schema do
|
22
|
+
{
|
23
|
+
before: Type(LogRequestConfig),
|
24
|
+
after: Type(LogRequestConfig)
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
title: Max Body
|
3
|
+
url: /options/max_body
|
4
|
+
---
|
5
|
+
|
6
|
+
Limits the maximum request body size in bytes. This helps prevent excessively large payloads, which can cause resource exhaustion or denial-of-service issues.
|
7
|
+
|
8
|
+
### Default
|
9
|
+
|
10
|
+
```ruby {filename=Itsi.rb}
|
11
|
+
max_body 10 * 1024 ** 2 # 10 MiB
|
12
|
+
```
|
13
|
+
|
14
|
+
### Example
|
15
|
+
|
16
|
+
```ruby {filename=Itsi.rb}
|
17
|
+
max_body 5 * 1024 ** 2 # 5 MiB
|
18
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class MaxBody < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
max_body limit_bytes: ${1: 10 * 1024 ** 2} # Maximum body size in bytes
|
8
|
+
SNIPPET
|
9
|
+
|
10
|
+
detail "Limit request body size."
|
11
|
+
|
12
|
+
schema do
|
13
|
+
{
|
14
|
+
limit_bytes: (Type(Integer) & Required()).default(10 * 1024 ** 2) # Default 10 MiB
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
---
|
2
|
+
title: Reverse Proxy
|
3
|
+
url: /middleware/proxy
|
4
|
+
---
|
5
|
+
|
6
|
+
The Reverse Proxy middleware enables reverse proxying by forwarding incoming HTTP requests to one of several backend servers. It supports streaming requests and responses, uses a dynamic URL rewriting mechanism to compute the target URL, supports multiple backend selection strategies, and can override or add headers before forwarding requests.
|
7
|
+
|
8
|
+
## Proxy Configuration
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
proxy \
|
12
|
+
to: "http://backend.example.com/api{path}{query}", \
|
13
|
+
backends: ["127.0.0.1:3001", "127.0.0.1:3002"], \
|
14
|
+
backend_priority: "round_robin", \
|
15
|
+
headers: { "X-Forwarded-For" => { rewrite: "{addr}" } }, \
|
16
|
+
verify_ssl: false, \
|
17
|
+
timeout: 30, \
|
18
|
+
tls_sni: true, \
|
19
|
+
error_response: "bad_gateway"
|
20
|
+
```
|
21
|
+
## Options
|
22
|
+
| **Option** | **Description** |
|
23
|
+
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
24
|
+
| `to` | The target URL. It supports dynamic URL rewriting using placeholders like `{path}` and `{query}`. If no backends are given, it will perform DNS resolution to determine the appropriate backend to route to. This parameter also determines the SNI hostname and Host header (unless overridden). |
|
25
|
+
| `backends` (Optional) | An array of Socket addresses. E.g. `["127.0.0.1:3001", "127.0.0.1:3002"]`. If provided, all requests will be routed to one of these backends based on the selected `backend_priority` algorithm. **Note:** The proxy uses persistent connections, so repeated testing from the same client will typically be satisfied by the same backend. |
|
26
|
+
| `backend_priority` (Optional) | The strategy for selecting a backend server. Options include `round_robin`, `ordered`, and `random`. Defaults to `round_robin`. |
|
27
|
+
| `headers` (Optional) | A hash of headers to be overridden or added before forwarding requests. To clear a header, set the value to `nil`. |
|
28
|
+
| `verify_ssl` (Optional) | A boolean indicating whether to verify SSL certificates. Defaults to `true`. |
|
29
|
+
| `timeout` (Optional) | The timeout in seconds for the proxy request. Failures to respond in time will result in a 504 timeout error. Defaults to `30` seconds. |
|
30
|
+
| `tls_sni` (Optional) | A boolean indicating whether to use TLS SNI. Defaults to `true`. |
|
31
|
+
| `error_response` (Optional) | The error response to be returned when the proxy fails. Users can either use a built-in error response or provide a custom one. See [Error Responses](/middleware/error_response) for more details on how to structure this. Defaults to the built-in `502 Bad Gateway` response. |
|
32
|
+
|
33
|
+
## How It Works
|
34
|
+
|
35
|
+
1. **URL Rewriting**
|
36
|
+
The `to` parameter is a dynamic template that applies the [String Rewrite](/middleware/string_rewrite) mechanism. For instance, placeholders such as `{path}` and `{query}` are replaced with parts from the incoming request.
|
37
|
+
*Example*:
|
38
|
+
- For a request to `/resource?id=5`, a template of
|
39
|
+
```ruby
|
40
|
+
"http://backend.example.com/api{path}{query}"
|
41
|
+
```
|
42
|
+
produces:
|
43
|
+
```
|
44
|
+
http://backend.example.com/api/resource?id=5
|
45
|
+
```
|
46
|
+
|
47
|
+
2. **Backend Selection**
|
48
|
+
The `backends` array lists available backend server addresses (formatted as `"IP:port"`). The `backend_priority` setting controls how a backend is chosen:
|
49
|
+
- **round_robin**: Cycles sequentially through the list.
|
50
|
+
- **ordered**: Always selects the first backend.
|
51
|
+
- **random**: Chooses a backend at random.
|
52
|
+
Note - The proxy uses persistent connections, so repeated testing from the same client will typically be satisfied by the same backend.
|
53
|
+
|
54
|
+
3. **Header Overrides**
|
55
|
+
The `headers` option lets you specify extra or overriding headers. Each header value may be a literal or a string rewrite. For example, overriding `"X-Forwarded-For"` to carry the client’s IP is done by:
|
56
|
+
```ruby
|
57
|
+
{ "X-Forwarded-For" => { rewrite: "{addr}" } }
|
58
|
+
```
|
59
|
+
|
60
|
+
4. **Request Forwarding and Error Handling**
|
61
|
+
Depending on whether the request method is idempotent, the middleware buffers the request body to allow retries, or streams it directly. If the target URL is invalid or a backend error occurs (e.g. timeout or connection error), a configurable error response is returned.
|
62
|
+
See [Error Responses](/middleware/error_response) for more details on how to customize errors.
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Proxy < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
proxy \\
|
8
|
+
to: "${1:http://backend.example.com/api{path}{query}}", \\
|
9
|
+
backends: [${2:"127.0.0.1:3001", "127.0.0.1:3002"}], \\
|
10
|
+
backend_priority: ${3|"round_robin","ordered","random"|}, \\
|
11
|
+
headers: { ${4| "X-Forwarded-For" => { rewrite: "{addr}" },|} }, \\
|
12
|
+
verify_ssl: ${5|true,false|}, \\
|
13
|
+
timeout: ${6|30,60|}, \\
|
14
|
+
tls_sni: ${7|true,false|}, \\
|
15
|
+
error_response: ${8|"bad_gateway", "service_unavailable", { code: 503\\, default_format: "html"\\, html: { inline: "<h1>Service Unavailable</h1>" } }|}
|
16
|
+
SNIPPET
|
17
|
+
|
18
|
+
detail "Forwards incoming requests to a backend server using dynamic URL rewriting. Supports various backend selection strategies and header overriding."
|
19
|
+
|
20
|
+
schema do
|
21
|
+
{
|
22
|
+
to: Type(String) & Required(),
|
23
|
+
backends: Array(Type(String)),
|
24
|
+
backend_priority: Enum(["round_robin", "ordered", "random"]).default("round_robin"),
|
25
|
+
headers: Hash(Type(String), Type(String)).default({}),
|
26
|
+
verify_ssl: Bool().default(true),
|
27
|
+
tls_sni: Bool().default(true),
|
28
|
+
timeout: Type(Integer).default(30),
|
29
|
+
error_response: Type(ErrorResponseDef).default("bad_gateway"),
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
def build!
|
34
|
+
require 'uri'
|
35
|
+
@params[:backends]||= URI.extract(@params[:to]).map(&URI.method(:parse)).map{|u| "#{u.scheme}://#{u.host}:#{u.port}" }
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
---
|
2
|
+
title: Rackup File
|
3
|
+
url: /middleware/rackup_file
|
4
|
+
---
|
5
|
+
|
6
|
+
You can use the `rackup_file` middleware to mount a rack application defined in a Rackup file (typically `config.ru`)
|
7
|
+
|
8
|
+
The alternative way to mount a rack application is to use the [`run`](/middleware/run) middleware to define a Rack app inline.
|
9
|
+
|
10
|
+
You can mount several rack applications to run simultaneously within a single Itsi application, using different location blocks.
|
11
|
+
Depending on *where* you mount the app, the application will receive different values for `PATH_INFO`, `SCRIPT_NAME`.
|
12
|
+
|
13
|
+
|
14
|
+
{{< callout >}}
|
15
|
+
If no `Itsi.rb` file is defined, Itsi will attempt to run the app defined at `./config.ru` by default, just like other Rack servers. You can also use `-r` or `--rackup_file` flags to specify a different file.
|
16
|
+
{{< /callout >}}
|
17
|
+
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
### Simple inline Rackup file.
|
22
|
+
```ruby {filename=Itsi.rb}
|
23
|
+
rackup_file "config.ru"
|
24
|
+
```
|
25
|
+
|
26
|
+
|
27
|
+
### Rack app mounted at a subpath
|
28
|
+
```ruby {filename=Itsi.rb}
|
29
|
+
require 'rack'
|
30
|
+
location "/subpath/*" do
|
31
|
+
rackup_file "config.ru"
|
32
|
+
end
|
33
|
+
|
34
|
+
rackup_file "config.ru"
|
35
|
+
|
36
|
+
```
|
37
|
+
|
38
|
+
```bash
|
39
|
+
# SCRIPT_NAME is "/subpath", path_info is "/child_path"
|
40
|
+
$ curl http://0.0.0.0:3000/subpath/child_path
|
41
|
+
|
42
|
+
# SCRIPT_NAME is "", path_info is "/root/child_path"
|
43
|
+
$ curl http://0.0.0.0:3000/root/child_path
|
44
|
+
:/root/child_path
|
45
|
+
```
|
46
|
+
|
47
|
+
### Options
|
48
|
+
* `nonblocking` (default false). Determines whether requests sent to this Rack application should be run on non-blocking threads. Only applies if running in hybrid (non-blocking and blocking thread pool) mode. Otherwise this is a no-op and will run in whatever mode is set globally.
|
49
|
+
* `sendfile` (default true). Determines whether Itsi should respect the `X-Sendfile` header set by the Rack application and use the `sendfile` function to efficiently send files. (Despite the name, this does not use the OS-level `sendfile` system call). Note. Itsi enforces the restriction that the referenced file must be within a child directory of the application root.
|
50
|
+
|
51
|
+
e.g.
|
52
|
+
```ruby {filename=Itsi.rb}
|
53
|
+
rackup_file "config.ru", nonblocking: true, sendfile: false
|
54
|
+
```
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class RackupFile < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
rackup_file \\
|
8
|
+
"config.ru",
|
9
|
+
nonblocking: ${2|true,false|},
|
10
|
+
sendfile: ${3|true,false|}
|
11
|
+
|
12
|
+
SNIPPET
|
13
|
+
|
14
|
+
detail "Define an inline Rack Application"
|
15
|
+
|
16
|
+
schema do
|
17
|
+
{
|
18
|
+
nonblocking: Bool().default(false),
|
19
|
+
sendfile: Bool().default(true)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(location, app, **params)
|
24
|
+
super(location, params)
|
25
|
+
raise "Rackup file must be a string" unless app.is_a?(String)
|
26
|
+
@app = Itsi::Server::RackInterface.for(app)
|
27
|
+
end
|
28
|
+
|
29
|
+
def build!
|
30
|
+
app_args = {
|
31
|
+
preloader: -> { @app},
|
32
|
+
sendfile: @params[:sendfile],
|
33
|
+
nonblocking: @params[:nonblocking],
|
34
|
+
base_path: "^(?<base_path>#{location.paths_from_parent.gsub(/\.\*\)$/, ')')}).*$"
|
35
|
+
}
|
36
|
+
location.middleware[:app] = app_args
|
37
|
+
location.location("*") do
|
38
|
+
@middleware[:app] = app_args
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|