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,126 @@
|
|
1
|
+
---
|
2
|
+
title: Rate Limiter
|
3
|
+
url: /middleware/rate_limit
|
4
|
+
---
|
5
|
+
|
6
|
+
The **Rate Limiter** middleware enforces a fixed‑window rate limit on incoming requests. You configure a maximum number of requests allowed in a given time span, along with how to identify the client and where to store counters (in‑memory or Redis).
|
7
|
+
|
8
|
+
By default it limits per IP address using an in‑memory store, but you can:
|
9
|
+
|
10
|
+
- Change the window size (`requests` per `seconds`)
|
11
|
+
- Limit based on other attributes (header or query parameter)
|
12
|
+
- Swap to a Redis backend for cross‑process rate limiting
|
13
|
+
- Customize the error response when the limit is exceeded
|
14
|
+
|
15
|
+
## Configuration
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
rate_limit \
|
19
|
+
requests: 100, # max 100 requests
|
20
|
+
seconds: 60, # per 60‑second window
|
21
|
+
key: "address", # limit by client IP
|
22
|
+
store_config: "in_memory", # use local in‑memory store
|
23
|
+
error_response: "too_many_requests"
|
24
|
+
```
|
25
|
+
|
26
|
+
### `requests` / `seconds`
|
27
|
+
|
28
|
+
- **`requests`**: Number of allowed requests in each window (positive integer).
|
29
|
+
- **`seconds`**: Length of each fixed window in seconds (positive integer).
|
30
|
+
|
31
|
+
### `key`
|
32
|
+
|
33
|
+
How to identify the client:
|
34
|
+
|
35
|
+
- **`"address"`** (default): use the client’s socket IP.
|
36
|
+
- **Header or query parameter**:
|
37
|
+
```ruby
|
38
|
+
key: { parameter: { header: { name: "X-Api-Key-Id" } } }
|
39
|
+
```
|
40
|
+
or
|
41
|
+
```ruby
|
42
|
+
key: { parameter: { query: { name: "user_id" } } }
|
43
|
+
```
|
44
|
+
|
45
|
+
### `store_config`
|
46
|
+
|
47
|
+
Where to keep counters:
|
48
|
+
|
49
|
+
- **`"in_memory"`** (default): per‑process, reset when server restarts.
|
50
|
+
- **Redis** (shared across workers):
|
51
|
+
```ruby
|
52
|
+
store_config: { redis: { connection_url: "redis://localhost:6379/1" } }
|
53
|
+
```
|
54
|
+
|
55
|
+
### `error_response`
|
56
|
+
|
57
|
+
Customizes the response when the limit is reached (default is built‑in `too_many_requests`):
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
error_response: {
|
61
|
+
code: 429,
|
62
|
+
plaintext: { inline: "Rate limit exceeded" },
|
63
|
+
default: "plaintext"
|
64
|
+
}
|
65
|
+
```
|
66
|
+
|
67
|
+
## Rate Limit Response Headers
|
68
|
+
|
69
|
+
When a request **exceeds** the allowed rate, the middleware returns your configured error response **plus** these headers:
|
70
|
+
|
71
|
+
| Header | Meaning |
|
72
|
+
|---------------------------|------------------------------------------------------------------------------------------|
|
73
|
+
| **X-RateLimit-Limit** | The maximum number of requests allowed per window (`requests` value). |
|
74
|
+
| **X-RateLimit-Remaining** | How many requests remain in the current window (will be `0` once the limit is hit). |
|
75
|
+
| **X-RateLimit-Reset** | Seconds until the current window resets (time until your counter zeroes out). |
|
76
|
+
| **Retry-After** | Same value as `X-RateLimit-Reset` — suggests when clients should retry their request. |
|
77
|
+
|
78
|
+
> **Example**
|
79
|
+
> With `requests: 5, seconds: 60`, after 5 calls the 6th returns:
|
80
|
+
> ```
|
81
|
+
> 429 Too Many Requests
|
82
|
+
> X-RateLimit-Limit: 5
|
83
|
+
> X-RateLimit-Remaining: 0
|
84
|
+
> X-RateLimit-Reset: 42
|
85
|
+
> Retry-After: 42
|
86
|
+
> ```
|
87
|
+
|
88
|
+
## How It Works
|
89
|
+
|
90
|
+
1. **On each request**
|
91
|
+
- Compute the client key (IP, header, or query).
|
92
|
+
- Increment a counter for the current time window.
|
93
|
+
|
94
|
+
2. **Fixed‑window logic**
|
95
|
+
- If the counter ≤ `requests`, allow through.
|
96
|
+
- Otherwise, immediately return the configured `error_response` plus the **X-RateLimit** headers.
|
97
|
+
|
98
|
+
3. **Store options**
|
99
|
+
- **In‑memory**: simple hash, fast but not shared across processes.
|
100
|
+
- **Redis**: atomic `INCR` + `EXPIRE` commands, shared across all workers.
|
101
|
+
|
102
|
+
Place `rate_limit` anywhere in your routing DSL to apply it to all downstream handlers in that scope.
|
103
|
+
|
104
|
+
|
105
|
+
## Trusted Proxies
|
106
|
+
|
107
|
+
By default, a rate limiter middleware uses the IP address from the underlying socket (remote_addr). However, if your server is behind a reverse proxy, all requests will appear to come from the proxy’s IP address. This can break IP-based rules or cause rate-limiting to group all users together.
|
108
|
+
|
109
|
+
To address this, you can declare trusted proxies and instruct the server to extract the original client IP from forwarded headers only if the request came from one of these proxies.
|
110
|
+
|
111
|
+
|
112
|
+
### Configuring trusted_proxies
|
113
|
+
|
114
|
+
To trust one or more upstream proxies, provide a trusted_proxies map in the middleware configuration.
|
115
|
+
E.g.
|
116
|
+
```ruby {filename=Itsi.rb}
|
117
|
+
rate_limit \
|
118
|
+
requests: 100, # max 100 requests
|
119
|
+
seconds: 60, # per 60‑second window
|
120
|
+
key: "address", # limit by client IP
|
121
|
+
store_config: "in_memory", # use local in‑memory store
|
122
|
+
error_response: "too_many_requests",
|
123
|
+
trusted_proxies: {
|
124
|
+
"192.168.1.1" => { header: { name: "X-Forwarded-For" } }
|
125
|
+
}
|
126
|
+
```
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class RateLimit < Middleware
|
5
|
+
require_relative "rate_limit_store"
|
6
|
+
require_relative "token_source"
|
7
|
+
|
8
|
+
insert_text <<~SNIPPET
|
9
|
+
rate_limit \\
|
10
|
+
requests: ${1|1,5,100|},
|
11
|
+
seconds: ${2|1,5,100|},
|
12
|
+
key: ${3|"address",{parameter:{header:{name:"X-Forwarded-For"}}}|},
|
13
|
+
store_config: ${4|"in_memory",{redis:{connection_url: "redis://localhost:6379"}}|},
|
14
|
+
error_response: ${5|"too_many_requests", { code: 429\\, default_format: "html"\\, html: { inline: "<h1>Unauthorized</h1>" } }|}
|
15
|
+
SNIPPET
|
16
|
+
|
17
|
+
detail "Automatically limits the number of requests a client can make within a given time period."
|
18
|
+
|
19
|
+
|
20
|
+
schema do
|
21
|
+
{
|
22
|
+
requests: Required() & Type(Integer) & Range(1..2**32),
|
23
|
+
seconds: Required() & Type(Integer) & Range(1..2**32),
|
24
|
+
key: (Required() & Or(Enum(["address"]), Type(RateLimitKey))).default("address"),
|
25
|
+
store_config: (Required() & Or(Enum(["in_memory"]), Type(RateLimitStore))).default("in_memory"),
|
26
|
+
error_response: Type(ErrorResponseDef).default("too_many_requests"),
|
27
|
+
trusted_proxies: (Hash(Type(String), Type(TokenSource)) & Required()).default({})
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
|
5
|
+
RateLimitKey = TypedStruct.new do
|
6
|
+
{
|
7
|
+
parameter: Or(
|
8
|
+
Hash(Enum(["header"]), Hash(Enum(["name"]), Type(String))) & Required(),
|
9
|
+
Hash(Enum(["query"]), Type(String)) & Required()
|
10
|
+
)
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
RateLimitStore = TypedStruct.new do
|
15
|
+
{
|
16
|
+
redis: Type(TypedStruct.new do
|
17
|
+
{
|
18
|
+
connection_url: Type(String)& Required()
|
19
|
+
}
|
20
|
+
end) & Required()
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
---
|
2
|
+
title: Redirect
|
3
|
+
url: /middleware/redirect
|
4
|
+
---
|
5
|
+
|
6
|
+
The Redirect middleware enables automatic redirection of incoming requests to a different URL. It computes the target URL using a string rewrite rule and responds with an HTTP redirect status code based on the configuration. Once the middleware processes a request, it immediately returns a redirection response without further processing.
|
7
|
+
|
8
|
+
## Redirect configuration
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
redirect \
|
12
|
+
to: "https://example.com/new-path", \
|
13
|
+
type: "permanent"
|
14
|
+
```
|
15
|
+
|
16
|
+
## Redirect Applied to a sub-location
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
location "/old-path" do
|
20
|
+
redirect \
|
21
|
+
to: "https://example.com/new-path", \
|
22
|
+
type: "temporary"
|
23
|
+
# No further route processing occurs for /old-path.
|
24
|
+
end
|
25
|
+
```
|
26
|
+
## Redirect HTTP to HTTPS
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
location protocols: [:http] do
|
30
|
+
redirect \
|
31
|
+
to: "https://{host}{path_and_query}", \
|
32
|
+
type: "moved_permanently"
|
33
|
+
end
|
34
|
+
```
|
35
|
+
> A shorthand for the above exists, call `redirect_http_to_https!`. Note that this is
|
36
|
+
an alias for the above, and as such is subject to ordinary [location](/middleware/location) resolution rules.
|
37
|
+
To make sure this rule takes precedence, place it above other locations in the `Itsi.rb` file.
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
## Configuration Options
|
42
|
+
|
43
|
+
- **to**:
|
44
|
+
A [string rewrite rule](/middleware/string_rewrites) (or literal string) specifying the target URL for the redirection. This value can incorporate dynamic portions of the incoming request.
|
45
|
+
|
46
|
+
- **type**:
|
47
|
+
Specifies the type of redirection. Allowed values include:
|
48
|
+
- `"permanent"`: Responds with a 308 Permanent Redirect.
|
49
|
+
- `"temporary"`: Responds with a 307 Temporary Redirect.
|
50
|
+
- `"moved_permanently"`: Responds with a 301 Moved Permanently.
|
51
|
+
- `"found"`: Responds with a 302 Found.
|
52
|
+
|
53
|
+
## How It Works
|
54
|
+
|
55
|
+
When a request is received, the Redirect middleware immediately intercepts it and builds a redirect response. The target URL is computed via the provided rewrite rule (`to`), and the response is sent with the appropriate HTTP status code as determined by the `type` option. No further handling is performed on the request.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Redirect < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
redirect \\
|
8
|
+
to: "${1:https://example.com/new-path}",
|
9
|
+
type: ${2|"permanent","temporary","found","moved_permanently"|}
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
detail "Automatically redirects incoming requests to a new URL based on a string rewrite rule."
|
13
|
+
|
14
|
+
Redirect = TypedStruct.new do
|
15
|
+
{
|
16
|
+
to: (Required() & Type(String)),
|
17
|
+
type: Enum(["permanent", "temporary", "found", "moved_permanently"]).default("moved_permanently")
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
schema Redirect
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
---
|
2
|
+
title: Request Headers
|
3
|
+
url: /middleware/request_headers
|
4
|
+
---
|
5
|
+
|
6
|
+
The **Request Headers** middleware lets you add, override or remove HTTP headers **before** your application handler sees the request. You can inject static values or use the full power of [String Rewrite](/middleware/string_rewrite) to generate header values based on path, query, method, etc.
|
7
|
+
|
8
|
+
## Configuration
|
9
|
+
```ruby {filename=Itsi.rb}
|
10
|
+
request_headers \
|
11
|
+
additions: {
|
12
|
+
"X-Correlation-ID" => ["{request_id_full}"],
|
13
|
+
"X-Env" => ["production"]
|
14
|
+
},
|
15
|
+
removals: ["X-Forwarded-For"]
|
16
|
+
```
|
17
|
+
|
18
|
+
- **additions** (`Hash(String,Array(StringRewrite))`)
|
19
|
+
A map of header names to an array of StringRewrite templates. Each template is rendered **after** removals.
|
20
|
+
- **removals** `Array(String)`
|
21
|
+
A list of header names to delete outright. If you want to override an existing header, include it in **both** removals and additions.
|
22
|
+
|
23
|
+
## Examples
|
24
|
+
```ruby {filename=Itsi.rb}
|
25
|
+
# Add a per‑request UUID and drop any X‑Forwarded‑For header
|
26
|
+
request_headers \
|
27
|
+
additions: { "X-Correlation-ID" => ["{request_id}"] },
|
28
|
+
removals: ["X-Forwarded-For"]
|
29
|
+
|
30
|
+
# Inject the full request path and query
|
31
|
+
request_headers \
|
32
|
+
additions: { "X-Full-URL" => ["{path_and_query}"] },
|
33
|
+
removals: []
|
34
|
+
```
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class RequestHeaders < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
request_headers \\
|
8
|
+
additions: { ${1:"X-Correlation-ID" => ["{request_id_full\\}"]} },
|
9
|
+
removals: [${2:"X-Forwarded-For"}]
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
detail "Add, override or remove request headers before reaching your handler."
|
13
|
+
|
14
|
+
schema do
|
15
|
+
{
|
16
|
+
additions: Hash(Type(String), Array(Type(String))).default({}),
|
17
|
+
removals: Array(Type(String)).default([]),
|
18
|
+
combine: Bool().default(true)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
title: Response Headers
|
3
|
+
url: /middleware/response_headers
|
4
|
+
---
|
5
|
+
|
6
|
+
The **Response Headers** middleware lets you add, override or remove HTTP headers **after** your application handler has produced a response. You can attach static values or dynamically compute them via [String Rewrite](/middleware/string_rewrite).
|
7
|
+
|
8
|
+
## Configuration
|
9
|
+
```ruby {filename=Itsi.rb}
|
10
|
+
response_headers \
|
11
|
+
additions: {
|
12
|
+
"X-Processed-By" => ["Itsi"],
|
13
|
+
"X-Response-Time-Millis" => ["{response_time}"]
|
14
|
+
},
|
15
|
+
removals: ["Server"]
|
16
|
+
```
|
17
|
+
- **additions** `Hash(String,Array(StringRewrite))`
|
18
|
+
A map of header names to StringRewrite templates. Templates are evaluated against the final response and context in **after**.
|
19
|
+
- **removals** `Array(String)`
|
20
|
+
A list of header names to delete before adding new ones.
|
21
|
+
|
22
|
+
## Examples
|
23
|
+
```ruby {filename=Itsi.rb}
|
24
|
+
# Stamp every response with our server name
|
25
|
+
response_headers \
|
26
|
+
additions: { "X-Powered-By" => ["Itsi"] },
|
27
|
+
removals: []
|
28
|
+
|
29
|
+
# Remove the Server header and add timing info
|
30
|
+
response_headers \
|
31
|
+
additions: { "X-Response-Time" => ["{response_time}"] },
|
32
|
+
removals: ["Server"]
|
33
|
+
```
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class ResponseHeaders < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
response_headers \\
|
8
|
+
additions: { ${1:"X-Powered-By" => ["Itsi"]} },
|
9
|
+
removals: [${2:"Server"}]
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
|
13
|
+
detail "Add, override or remove response headers before sending to the client."
|
14
|
+
|
15
|
+
schema do
|
16
|
+
{
|
17
|
+
additions: Hash(Type(String), Array(Type(String))).default({}),
|
18
|
+
removals: Array(Type(String)).default([]),
|
19
|
+
combine: Bool().default(true)
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
---
|
2
|
+
title: Run
|
3
|
+
url: /middleware/run
|
4
|
+
---
|
5
|
+
|
6
|
+
You can use the `run` middleware to run an inline rack application.
|
7
|
+
The alternative way to mount a rack application is to use a [`rackup_file`](/middleware/rackup_file) middleware.
|
8
|
+
|
9
|
+
You can mount several rack applications to run simultaneously within a single Itsi application, using different location blocks.
|
10
|
+
Depending on *where* you mount the app, the application will receive different values for `PATH_INFO`, `SCRIPT_NAME`.
|
11
|
+
|
12
|
+
## Configuration
|
13
|
+
|
14
|
+
### Simple inline Rack app.
|
15
|
+
```ruby {filename=Itsi.rb}
|
16
|
+
run ->(env){ [200, { 'content-type' => 'text/plain' }, ['OK']] }
|
17
|
+
```
|
18
|
+
|
19
|
+
### Rack app using Rack::Builder
|
20
|
+
```ruby {filename=Itsi.rb}
|
21
|
+
run(Rack::Builder.app do
|
22
|
+
use Rack::CommonLogger
|
23
|
+
run ->(env) { [200, { 'content-type' => 'text/plain' }, ['OK']] }
|
24
|
+
end)
|
25
|
+
```
|
26
|
+
|
27
|
+
|
28
|
+
### Rack app mounted at a subpath
|
29
|
+
```ruby {filename=Itsi.rb}
|
30
|
+
require 'rack'
|
31
|
+
location "/subpath/*" do
|
32
|
+
run(Rack::Builder.app do
|
33
|
+
use Rack::CommonLogger
|
34
|
+
run ->(env) { [200, { 'content-type' => 'text/plain' }, [[env['SCRIPT_NAME'], env['PATH_INFO']].join(":") ] ] }
|
35
|
+
end)
|
36
|
+
end
|
37
|
+
|
38
|
+
run(Rack::Builder.app do
|
39
|
+
use Rack::CommonLogger
|
40
|
+
run ->(env) { [200, { 'content-type' => 'text/plain' }, [[env['SCRIPT_NAME'], env['PATH_INFO']].join(":") ] ] }
|
41
|
+
end)
|
42
|
+
|
43
|
+
```
|
44
|
+
|
45
|
+
```bash
|
46
|
+
$ curl http://0.0.0.0:3000/subpath/child_path
|
47
|
+
/subpath:/child_path
|
48
|
+
|
49
|
+
$ curl http://0.0.0.0:3000/root/child_path
|
50
|
+
:/root/child_path
|
51
|
+
```
|
52
|
+
|
53
|
+
### Options
|
54
|
+
* `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.
|
55
|
+
* `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.
|
56
|
+
|
57
|
+
e.g.
|
58
|
+
```ruby {filename=Itsi.rb}
|
59
|
+
run ->(env){ [200, { 'content-type' => 'text/plain' }, ['OK']] }, nonblocking: true, sendfile: false
|
60
|
+
```
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Run < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
run \\
|
8
|
+
${1:->(env){[200, {"Content-Type" => "text/plain"\\}, ["Hello, World!"]]}},
|
9
|
+
nonblocking: ${2|true,false|},
|
10
|
+
sendfile: ${3|true,false|}
|
11
|
+
SNIPPET
|
12
|
+
|
13
|
+
detail "Define an inline Rack Application"
|
14
|
+
|
15
|
+
schema do
|
16
|
+
{
|
17
|
+
nonblocking: Bool().default(false),
|
18
|
+
sendfile: Bool().default(true)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(location, app, params={})
|
23
|
+
super(location, params)
|
24
|
+
raise "App must be a Rack application" unless app.respond_to?(:call)
|
25
|
+
@app = app
|
26
|
+
end
|
27
|
+
|
28
|
+
def build!
|
29
|
+
app_args = {
|
30
|
+
preloader: -> { Itsi::Server::RackInterface.for(@app) },
|
31
|
+
sendfile: @params[:sendfile],
|
32
|
+
nonblocking: @params[:nonblocking],
|
33
|
+
base_path: "^(?<base_path>#{location.paths_from_parent.gsub(/\.\*\)$/, ')')}).*$"
|
34
|
+
}
|
35
|
+
location.middleware[:app] = app_args
|
36
|
+
location.location("*") do
|
37
|
+
@middleware[:app] = app_args
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
---
|
2
|
+
title: Static Assets
|
3
|
+
url: /middleware/static_assets
|
4
|
+
---
|
5
|
+
|
6
|
+
The Static Assets middleware serves files from a specified root directory. It is capable of optimized delivery of static content such as HTML, CSS, JavaScript, images, as well as large assets, such as video files using streaming bodies and range requests.
|
7
|
+
It can auto-index directories for simple directory listings.
|
8
|
+
|
9
|
+
## Key Features
|
10
|
+
- **Auto Indexing**: Optionally generate directory listings when an index file is missing.
|
11
|
+
- **HTML Fallback**: When enabled, the middleware attempts to serve a file with a `.html` extension if the requested file is not found.
|
12
|
+
- **In-Memory Caching**: Files under a certain size (and up to a configurable count) are cached in memory for performance.
|
13
|
+
- **Custom Headers**: User-supplied headers (e.g., for caching) can be added to responses.
|
14
|
+
- **Relative Path Processing**: When enabled, the middleware rewrites request paths relative to a configured base path.
|
15
|
+
- **Partial Content**: Supports Range requests for serving partial file content.
|
16
|
+
|
17
|
+
## Example
|
18
|
+
|
19
|
+
```ruby {filename=Itsi.rb}
|
20
|
+
static_assets root_dir: "./"
|
21
|
+
```
|
22
|
+
|
23
|
+
## Configuration Options
|
24
|
+
|
25
|
+
|
26
|
+
| Option | Description |
|
27
|
+
|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
28
|
+
| **`root_dir`** (Default ".") | The relative or absolute disk path where static files reside. |
|
29
|
+
| **`not_found_behavior`** (Default `{error: "not_found"}`) | Determines what to do when a file isn’t found. See [Not Found Behavior](#not-found-behavior) below. |
|
30
|
+
| **`auto_index`** (Default `false`) | If <code>true</code>, directory listings are automatically generated when no index file is found. Defaults to <code>false</code>. |
|
31
|
+
| **`try_html_extension`** (Default `true`) | If <code>true</code>, when the requested file isn’t found, the middleware attempts to serve the same path with a <code>.html</code> extension. Defaults to <code>true</code>. |
|
32
|
+
| **`max_file_size_in_memory`** (Default `1048576`) | Maximum file size (in bytes) for caching files in memory. Files larger than this will be served from disk. Defaults to <code>1048576</code> (1 MB). |
|
33
|
+
| **`max_files_in_memory`** (Default `100`) | Maximum number of files to cache in memory. Defaults to <code>100</code>. |
|
34
|
+
| **`file_check_interval`** (Default `1`) | Max time (in seconds) a file stays in cache before the file-system is checked for modifications. Defaults to <code>1</code>. |
|
35
|
+
| **`headers`** (Default `nil`) | A hash of additional headers to include in responses (e.g. <code>{"Cache-Control" => "max-age=3600"}</code>). |
|
36
|
+
| **`allowed_extensions`** (Default `[]`) | An array of permitted file extensions (e.g. <code>["html", "css", "js", "png", "jpg"]</code>). If a requested file’s extension isn’t in this list, it won’t be served. An empty list (default) means all extensions are allowed. |
|
37
|
+
| **`relative_path`** (Default `true`) | If <code>true</code>, the effective file lookup path is computed relative to the base path at which the middleware is mounted (See [location](/middleware/location) to understand mounting options). Defaults to <code>true</code>. |
|
38
|
+
| **`serve_hidden_files`** (Default `false`) | If <code>false</code>, files whose names start with a dot (".") are not served. Defaults to <code>false</code>. |
|
39
|
+
|
40
|
+
|
41
|
+
## Not Found Behavior
|
42
|
+
The static assets middleware supports many configuration options when a file is not found.
|
43
|
+
* **`fallthrough`**: The request is *not* handled by this middleware and is instead served by the next middleware in the chain. The option is given as a string. E.g.
|
44
|
+
```ruby
|
45
|
+
error_response: "fallthrough"
|
46
|
+
```
|
47
|
+
* **`index`**: Unsatisfiable requests instead result in serving an index file. (Useful for SPAs with client-side routing).
|
48
|
+
```ruby
|
49
|
+
error_response: {index: "./path/to/index.html" }
|
50
|
+
```
|
51
|
+
* **`redirect`**: Unsatisfiable requests are redirected. Options for type are the same as defined for the [redirect](/middleware/redirect) middleware.
|
52
|
+
```ruby
|
53
|
+
error_response: {redirect: { to: "http://example.com/redirect_path", type: "permanent" }}
|
54
|
+
```
|
55
|
+
* **`error`**: Provide an overridden error response. See [`error_response`](/middleware/error_response) for details.
|
56
|
+
e.g.
|
57
|
+
```ruby
|
58
|
+
error_response: {error: "not_found"}
|
59
|
+
```
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
error_response: \
|
63
|
+
{
|
64
|
+
error:
|
65
|
+
{
|
66
|
+
code: 404,
|
67
|
+
plaintext: {inline: "File not found"},
|
68
|
+
json: {inline: "{\"message\": \"File not found\"}"},
|
69
|
+
html: {file: "./path/to/not_found.html"},
|
70
|
+
default: "plaintext"
|
71
|
+
}
|
72
|
+
}
|
73
|
+
```
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class StaticAssets < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
static_assets \\
|
8
|
+
root_dir: "${1|./,/var/www,|}",
|
9
|
+
not_found_behavior: ${2|"fallthrough",{index: "index.html"},{error: "not_found"}|},
|
10
|
+
auto_index: ${3|true,false|},
|
11
|
+
try_html_extension: ${4|true,false|},
|
12
|
+
max_file_size_in_memory: ${5|1048576,2097152|},
|
13
|
+
max_files_in_memory: ${6|100,500,1000|},
|
14
|
+
file_check_interval: ${7|1,60,120|},
|
15
|
+
headers: { ${8|,"Cache-Control" => "max-age=3600",|} },
|
16
|
+
allowed_extensions: ${9|%w[html css js png jpg],[]|},
|
17
|
+
relative_path: ${10|true,false|},
|
18
|
+
serve_hidden_files: ${11|true,false|}
|
19
|
+
SNIPPET
|
20
|
+
|
21
|
+
detail "Serves static files from a designated directory with options for auto indexing, in-memory caching, and custom header support. Supports relative path rewriting and file range requests."
|
22
|
+
|
23
|
+
ErrorResponse = TypedStruct.new do
|
24
|
+
{
|
25
|
+
error: Type(ErrorResponseDef) & Required()
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
IndexResponse = TypedStruct.new do
|
30
|
+
{
|
31
|
+
index: Type(String) & Required()
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
RedirectResponse = TypedStruct.new do
|
36
|
+
{
|
37
|
+
redirect: Type(Redirect::Redirect) & Required()
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
schema do
|
42
|
+
{
|
43
|
+
root_dir: (Type(String) & Required()).default("./"),
|
44
|
+
not_found_behavior: Or(
|
45
|
+
Enum(["fallthrough", "index", "redirect", "internal_server_error"]),
|
46
|
+
Type(IndexResponse),
|
47
|
+
Type(RedirectResponse),
|
48
|
+
Type(ErrorResponse)
|
49
|
+
).default({error: "not_found"}),
|
50
|
+
allowed_extensions: (Array(Type(String)) & Required()).default([]),
|
51
|
+
auto_index: Bool().default(false),
|
52
|
+
try_html_extension: Bool().default(true),
|
53
|
+
max_file_size_in_memory: Type(Integer).default(1048576),
|
54
|
+
max_files_in_memory: Type(Integer).default(100),
|
55
|
+
file_check_interval: Type(Integer).default(1),
|
56
|
+
headers: Hash(Type(String), Type(String)).default({}),
|
57
|
+
relative_path: Bool().default(true),
|
58
|
+
serve_hidden_files: Bool().default(false)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def build!
|
63
|
+
root_dir = @params[:root_dir] || "."
|
64
|
+
|
65
|
+
if !File.exist?(root_dir)
|
66
|
+
warn "Warning: static_assets root_dir '#{root_dir}' does not exist!"
|
67
|
+
elsif !File.directory?(root_dir)
|
68
|
+
warn "Warning: static_assets root_dir '#{root_dir}' is not a directory!"
|
69
|
+
end
|
70
|
+
|
71
|
+
@params[:relative_path] = true unless @params.key?(:relative_path)
|
72
|
+
@params[:allowed_extensions] ||= []
|
73
|
+
|
74
|
+
if @params[:try_html_extension] && @params[:allowed_extensions].include?("html")
|
75
|
+
@params[:allowed_extensions] << ""
|
76
|
+
end
|
77
|
+
|
78
|
+
@params[:base_path] = "^(?<base_path>#{location.paths_from_parent}).*$"
|
79
|
+
params = @params
|
80
|
+
location.location("*", extensions: @params[:allowed_extensions]) do
|
81
|
+
@middleware[:static_assets] = params
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|