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,122 @@
|
|
1
|
+
---
|
2
|
+
title: Schemas
|
3
|
+
url: /middleware/endpoint/schemas
|
4
|
+
next: error_response/
|
5
|
+
---
|
6
|
+
|
7
|
+
Endpoints also support basic schema enforcement for both request and and response bodies. Endpoint **Schemas** are simply plain-old Ruby hashes, which map named keys to allowed types.
|
8
|
+
|
9
|
+
E.g.
|
10
|
+
```ruby {filename=Itsi.rb}
|
11
|
+
# This is a valid schema
|
12
|
+
SimpleSchema = {
|
13
|
+
score: Integer
|
14
|
+
}
|
15
|
+
```
|
16
|
+
|
17
|
+
A few special rules/conventions apply:
|
18
|
+
|
19
|
+
* Regexp patterns are used in place of symbol keys to define dynamic parameters that must match a specific pattern (A key of `/.*/` matches any string).
|
20
|
+
* A `:Boolean` symbol can be used instead of a class to require boolean parameters (as a proxy for the combination of TrueClass and FalseClass)
|
21
|
+
* `Array` keys are used to define arrays of values.
|
22
|
+
* Objects can be nested
|
23
|
+
* A special `_required` key indicates which parameters in the current object are required.
|
24
|
+
* Arrays must be homogeneous (No support for union types).
|
25
|
+
* Schema validation *only* supports primitive Ruby types, Date, Time, Datetime, arrays and hashes (no unions or advanced coercion).
|
26
|
+
|
27
|
+
|
28
|
+
## Supported types
|
29
|
+
```ruby {filename=Itsi.rb}
|
30
|
+
# Demo schema with all supported types included
|
31
|
+
SupportedTypesSchema = {
|
32
|
+
_required: %i[name age active preferences created_at last_login],
|
33
|
+
name: String, # A user's name
|
34
|
+
age: Integer, # The user's age
|
35
|
+
active: :Boolean, # Whether the user is active
|
36
|
+
preferences: {
|
37
|
+
_required: %i[theme notifications],
|
38
|
+
theme: Symbol, # Preferred theme (e.g., :dark, :light)
|
39
|
+
notifications: :Boolean # Whether notifications are enabled
|
40
|
+
},
|
41
|
+
scores: Array[Float], # A list of user scores
|
42
|
+
metadata: {
|
43
|
+
_required: %i[signup_date last_purchase],
|
44
|
+
signup_date: Date, # The date the user signed up
|
45
|
+
last_purchase: DateTime # The timestamp of the last purchase
|
46
|
+
},
|
47
|
+
last_login: Time # The last login time
|
48
|
+
}
|
49
|
+
```
|
50
|
+
|
51
|
+
{{< callout >}}
|
52
|
+
Itsi will check for the presence and structure of all:
|
53
|
+
* [Schemas](/middleware/schemas)
|
54
|
+
* [Controller methods](/middleware/controller)
|
55
|
+
|
56
|
+
at **boot time** ensuring that you can't be caught out by naming mismatches at runtime, or during a hot-reload.
|
57
|
+
If Itsi boots successfully, the referenced schemas objects can be found.
|
58
|
+
{{</ callout >}}
|
59
|
+
|
60
|
+
|
61
|
+
## Request Body Schemas
|
62
|
+
|
63
|
+
```ruby {filename=Itsi.rb}
|
64
|
+
AddressSchema = {
|
65
|
+
_required: %i[street city postcode],
|
66
|
+
street: String,
|
67
|
+
city: String,
|
68
|
+
postcode: String,
|
69
|
+
country: String # Optional
|
70
|
+
}
|
71
|
+
|
72
|
+
UserInputSchema = {
|
73
|
+
_required: %i[first_name last_name email address],
|
74
|
+
first_name: String,
|
75
|
+
last_name: String,
|
76
|
+
email: String,
|
77
|
+
age: Integer,
|
78
|
+
active: :Boolean,
|
79
|
+
roles: Array[String],
|
80
|
+
address: AddressSchema
|
81
|
+
}
|
82
|
+
|
83
|
+
UserResponseSchema = {
|
84
|
+
_required: %i[id email full_name],
|
85
|
+
id: Integer,
|
86
|
+
email: String,
|
87
|
+
full_name: String,
|
88
|
+
created_at: String,
|
89
|
+
address: AddressSchema
|
90
|
+
}
|
91
|
+
|
92
|
+
post "/users" do |request, params: UserInputSchema, response_format: UserResponseSchema|
|
93
|
+
user = User.create!(params)
|
94
|
+
request.created \
|
95
|
+
json: {
|
96
|
+
id: user.id,
|
97
|
+
email: user.email,
|
98
|
+
full_name: "#{user.first_name} #{user.last_name}",
|
99
|
+
created_at: user.created_at.iso8601,
|
100
|
+
address: {
|
101
|
+
street: user.address.street,
|
102
|
+
city: user.address.city,
|
103
|
+
postcode: user.address.postcode
|
104
|
+
}
|
105
|
+
},
|
106
|
+
as: response_format
|
107
|
+
end
|
108
|
+
```
|
109
|
+
Endpoints with schema validation applied can count on requests *only* being invoked with correctly formed parameters (and descriptive errors being returned if schema enforcement fails.)
|
110
|
+
|
111
|
+
You can *optionally* choose to apply a corresponding response schema validation to response objects.
|
112
|
+
|
113
|
+
## Response Body Schemas
|
114
|
+
```ruby {filename=Itsi.rb}
|
115
|
+
PingSchema = {
|
116
|
+
status: String
|
117
|
+
}
|
118
|
+
|
119
|
+
get "/ping" do |req, response_format: PingSchema|
|
120
|
+
req.ok json: { status: "ok" }, as: response_format
|
121
|
+
end
|
122
|
+
```
|
@@ -0,0 +1,61 @@
|
|
1
|
+
---
|
2
|
+
title: Error Response
|
3
|
+
url: /middleware/error_response
|
4
|
+
prev: schemas/
|
5
|
+
---
|
6
|
+
|
7
|
+
All of the below middlewares allow error responses to be customized (though will select a sane default if left unspecified).
|
8
|
+
* [`allow_list`](/middleware/allow_list)
|
9
|
+
* [`auth_api_key`](/middleware/auth_api_key)
|
10
|
+
* [`auth_jwt`](/middleware/auth_jwt)
|
11
|
+
* [`deny_list`](/middleware/deny_list)
|
12
|
+
* [`intrusion_protection`](/middleware/intrusion_protection)
|
13
|
+
* [`max_body`](/middleware/max_body)
|
14
|
+
* [`proxy`](/middleware/proxy)
|
15
|
+
* [`rate_limit`](/middleware/rate_limit)
|
16
|
+
|
17
|
+
You can override the default error responses by providing a custom error response, either selecting a different built-in type,
|
18
|
+
or providing a completely overridden options.
|
19
|
+
The following built-in types are available:
|
20
|
+
* `internal_server_error` (500)
|
21
|
+
* `not_found` (404)
|
22
|
+
* `unauthorized` (401)
|
23
|
+
* `forbidden` (403)
|
24
|
+
* `payload_too_large` (413)
|
25
|
+
* `too_many_requests` (429)
|
26
|
+
* `bad_gateway` (502)
|
27
|
+
* `service_unavailable` (503)
|
28
|
+
* `gateway_timeout` (504)
|
29
|
+
|
30
|
+
## Reuse a built-in type
|
31
|
+
To reuse a built-in type you can provide a string option for the `error_response` property.
|
32
|
+
E.g.
|
33
|
+
```ruby
|
34
|
+
auth_api_key .. other options.., error_response: 'forbidden'
|
35
|
+
```
|
36
|
+
|
37
|
+
## Override the error response
|
38
|
+
You may instead wish to completely override the error response. You can provide a status code, and a message in up to three
|
39
|
+
formats: plain-text, JSON, or HTML (at least one must be provided). Itsi will serve the appropriate type based on the `Accept` header of the incoming request, or fall back to the default if the requested type is not available.
|
40
|
+
Each of these three response formats can either be provided as an in-memory string, or a file path.
|
41
|
+
|
42
|
+
E.g.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
auth_api_key .. other options.., error_response: {
|
46
|
+
status: 403,
|
47
|
+
plaintext: nil, # No plain-text response provided
|
48
|
+
json: { inline: {"message": "Forbidden"} }, # We provide the JSON response inline
|
49
|
+
html: { file: './forbidden.html'}, # We provide the HTML response as a file path
|
50
|
+
default: 'json' # When the Accept header doesn't match a supported response type, we'll default to JSON
|
51
|
+
}
|
52
|
+
|
53
|
+
# Or, e.g.
|
54
|
+
auth_api_key .. other options.., error_response: {
|
55
|
+
status: 401,
|
56
|
+
plaintext: "Unauthorized",
|
57
|
+
json: { file: "unauthorized.json" },
|
58
|
+
html: { inline: "<h1>Unauthorized</h1>" },
|
59
|
+
default: 'html'
|
60
|
+
}
|
61
|
+
```
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
InlineContentSource = TypedStruct.new do
|
5
|
+
{
|
6
|
+
inline: Type(String)
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
10
|
+
FileContentSource = TypedStruct.new do
|
11
|
+
{
|
12
|
+
file: Type(String)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
ContentSource = TypedStruct.new do
|
17
|
+
Or(Type(InlineContentSource), Type(FileContentSource))
|
18
|
+
end
|
19
|
+
|
20
|
+
ErrorResponse = TypedStruct.new do
|
21
|
+
{
|
22
|
+
code: Type(Integer) & Required(),
|
23
|
+
plaintext: Type(ContentSource),
|
24
|
+
html: Type(ContentSource),
|
25
|
+
json: Type(ContentSource),
|
26
|
+
default: Enum(["plaintext", "html", "json"]) & Required()
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
ErrorResponseDef = TypedStruct.new do
|
31
|
+
Or(Enum(%w[internal_server_error not_found unauthorized forbidden payload_too_large
|
32
|
+
too_many_requests bad_gateway service_unavailable gateway_timeout]), Type(ErrorResponse)) & Required()
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
---
|
2
|
+
title: ETag
|
3
|
+
url: /middleware/etag
|
4
|
+
---
|
5
|
+
|
6
|
+
The ETag middleware enables HTTP entity tag generation for responses. It provides cache validation by automatically computing and attaching an ETag to outgoing responses, and optionally responding with `304 Not Modified` if the client includes a matching `If-None-Match` header.
|
7
|
+
|
8
|
+
ETags are useful for optimizing client-side caching, conditional GETs, and reducing unnecessary data transfer.
|
9
|
+
|
10
|
+
|
11
|
+
## ETag configuration
|
12
|
+
```ruby {filename=Itsi.rb}
|
13
|
+
etag \
|
14
|
+
type: "strong",
|
15
|
+
algorithm: "sha256",
|
16
|
+
min_body_size: 0,
|
17
|
+
handle_if_none_match: true
|
18
|
+
```
|
19
|
+
|
20
|
+
## ETag Applied to a sub-location
|
21
|
+
```ruby {filename=Itsi.rb}
|
22
|
+
location "/assets" do
|
23
|
+
etag \
|
24
|
+
type: "weak",
|
25
|
+
algorithm: "md5",
|
26
|
+
min_body_size: 1024,
|
27
|
+
handle_if_none_match: true
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## Configuration Options
|
32
|
+
|
33
|
+
- **type**: Specifies whether the generated ETag is `"strong"` or `"weak"`.
|
34
|
+
- `strong`: ETag changes with any byte-level difference in the body.
|
35
|
+
- `weak`: Indicates a semantic equivalence rather than byte-level identity.
|
36
|
+
|
37
|
+
- **algorithm**: Specifies the hash algorithm used to compute the ETag.
|
38
|
+
- `sha256` (default)
|
39
|
+
- `md5`
|
40
|
+
|
41
|
+
- **min_body_size**: Minimum response body size (in bytes) required before an ETag is generated. Use this to skip ETags for small or trivial responses.
|
42
|
+
|
43
|
+
- **handle_if_none_match**: When `true`, incoming requests with a matching `If-None-Match` header will receive a `304 Not Modified` response (instead of a full body), if the ETag matches the computed value.
|
44
|
+
|
45
|
+
## How It Works
|
46
|
+
|
47
|
+
### Before the Response
|
48
|
+
If `handle_if_none_match` is enabled and the request includes an `If-None-Match` header, the value is stored in the request context for comparison later.
|
49
|
+
|
50
|
+
### After the Response
|
51
|
+
|
52
|
+
1. If the status code is cacheable (e.g., 200 OK, 201 Created), the middleware proceeds.
|
53
|
+
2. If an ETag header is already present or if `Cache-Control: no-store` is set, it skips computation.
|
54
|
+
3. If the response body is not streamable and meets the `min_body_size`, it is buffered.
|
55
|
+
4. A hash (SHA-256 or MD5) is computed from the full body content.
|
56
|
+
5. The ETag header is inserted using either strong (`"abc123"`) or weak (`W/"abc123"`) formatting.
|
57
|
+
6. If the incoming request had a matching `If-None-Match`, the response is replaced with a 304 Not Modified.
|
58
|
+
|
59
|
+
---
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Etag < Middleware
|
5
|
+
|
6
|
+
insert_text <<~SNIPPET
|
7
|
+
etag \\
|
8
|
+
type: ${1|"strong","weak"|},
|
9
|
+
algorithm: ${2|"sha256","md5"|},
|
10
|
+
min_body_size: ${3|0,1024|},
|
11
|
+
handle_if_none_match: ${4|true,false|}
|
12
|
+
SNIPPET
|
13
|
+
|
14
|
+
detail "Enables ETag generation for the server."
|
15
|
+
|
16
|
+
schema do
|
17
|
+
{
|
18
|
+
type: (Enum(["strong", "weak"]) & Required()).default("strong"),
|
19
|
+
algorithm: (Enum(["sha256", "md5"]) & Required()).default("sha256"),
|
20
|
+
min_body_size: Range(0...1024 ** 3).default(0),
|
21
|
+
handle_if_none_match: Bool().default(true)
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
---
|
2
|
+
title: gRPC
|
3
|
+
url: /middleware/grpc
|
4
|
+
---
|
5
|
+
|
6
|
+
The **gRPC** middleware lets you expose one or more Ruby gRPC service handlers directly in Itsi.
|
7
|
+
This allows you to use Itsi's efficient asynchronous server to serve requests and gain enhanced performance and asynchronous capabilities.
|
8
|
+
|
9
|
+
Under the covers it:
|
10
|
+
|
11
|
+
1. Serves a full HTTP/2 gRPC endpoint (with binary frames, trailers, `HTTP/2` compression, and reflection).
|
12
|
+
2. Provides a **JSON‑over‑HTTP** gateway for each unary or streaming method—so you can POST JSON and receive JSON arrays without a gRPC client.
|
13
|
+
3. Automatically enables `gRPC` reflection (so client like `evans`, `grpcurl` or `Postman` can discover your service endpoints without needing access to raw `.proto` files).
|
14
|
+
4. Supports optional per‑call compression (`none`, `deflate`, `gzip`) and a non‑blocking execution mode.
|
15
|
+
|
16
|
+
---
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# Define (or require) your service implementation:
|
22
|
+
# Mount it in your Itsi.rb:
|
23
|
+
grpc EchoServiceImpl.new,
|
24
|
+
nonblocking: false do # prepend response with grpc‑encoding:gzip
|
25
|
+
# any additional middleware can nest here, e.g.:
|
26
|
+
response_headers additions: { "X-Service" => ["Echo"] }
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
## Options
|
31
|
+
|
32
|
+
| Option | Type | Default | Description |
|
33
|
+
|---------------|---------|---------|---------------------------------------------------------------|
|
34
|
+
| `*handlers` | Object | – | One or more gRPC service implementations |
|
35
|
+
| `nonblocking` | Boolean | false | Run handler in fiber/thread‑pool (nonblocking mode). Only effective if using [hybrid mode](/options/scheduler_threads), otherwise the gRPC handler will adopt the server global concurrency mode (threads or fibers) |
|
36
|
+
| `reflection` | Boolean | true | Determines whether to serve reflection endpoints. (Useful for clients to auto-discover services) |
|
37
|
+
| `&block` | Proc | – | **Optional** You can add additional middleware inside an optional block, to apply to all gRPC requests (e.g. rate limiters, deny lists, max body etc. etc.). |
|
38
|
+
|
39
|
+
Reflection is served only over HTTP/2; JSON‑over‑HTTP works with HTTP/1.1.
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
## Walkthrough
|
44
|
+
The below is a simple walkthrough of using Itsi and the [Ruby gRPC](https://grpc.io/docs/languages/ruby/basics/) library to expose a simple "Echo" service in Itsi, complete with both native gRPC/HTTP2 and a JSON‑over‑HTTP gateway.
|
45
|
+
|
46
|
+
{{% steps %}}
|
47
|
+
|
48
|
+
### Step 1 — Define your gRPC contract
|
49
|
+
|
50
|
+
Create a file `echo.proto` with:
|
51
|
+
```proto
|
52
|
+
syntax = "proto3";
|
53
|
+
package echo;
|
54
|
+
|
55
|
+
service EchoService {
|
56
|
+
rpc Echo(EchoRequest) returns (EchoResponse);
|
57
|
+
}
|
58
|
+
|
59
|
+
message EchoRequest {
|
60
|
+
string message = 1;
|
61
|
+
}
|
62
|
+
|
63
|
+
message EchoResponse {
|
64
|
+
string message = 1;
|
65
|
+
}
|
66
|
+
```
|
67
|
+
|
68
|
+
### Step 2 — Generate Ruby stubs
|
69
|
+
|
70
|
+
Install the Ruby gRPC tools and run:
|
71
|
+
```bash
|
72
|
+
gem install grpc-tools
|
73
|
+
grpc_tools_ruby_protoc -I . --ruby_out=./ --grpc_out=./ echo.proto
|
74
|
+
```
|
75
|
+
This produces `echo_services_pb.rb` and supporting files.
|
76
|
+
|
77
|
+
### Step 3 — Implement the service
|
78
|
+
|
79
|
+
Create `echo_service_impl.rb`:
|
80
|
+
```ruby {filename=echo_service_impl.rb}
|
81
|
+
require_relative 'echo_services_pb'
|
82
|
+
|
83
|
+
class EchoServiceImpl < Echo::EchoService::Service
|
84
|
+
# Unary RPC implementation
|
85
|
+
def echo(req, _unused_call)
|
86
|
+
Echo::EchoResponse.new(message: req.message)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
### Step 4 — Mount in Itsi
|
92
|
+
|
93
|
+
In your `Itsi.rb` at the project root, add:
|
94
|
+
|
95
|
+
```ruby {filename=Itsi.rb}
|
96
|
+
require_relative 'echo_service_impl'
|
97
|
+
|
98
|
+
bind "https://localhost:3000"
|
99
|
+
grpc EchoServiceImpl.new,
|
100
|
+
nonblocking: false,
|
101
|
+
compression: 'gzip' do
|
102
|
+
# Nested middleware still works:
|
103
|
+
response_headers additions: { 'X-Service' => ['Echo'] }
|
104
|
+
end
|
105
|
+
```
|
106
|
+
### Step 5 — Start the server
|
107
|
+
```bash
|
108
|
+
itsi serve
|
109
|
+
```
|
110
|
+
|
111
|
+
### Step 6 — Test with a gRPC client
|
112
|
+
|
113
|
+
E.g. using [Evans](https://github.com/ktr0731/evans)
|
114
|
+
|
115
|
+
```bash
|
116
|
+
evans --host localhost --port 3000 repl
|
117
|
+
|
118
|
+
______
|
119
|
+
| ____|
|
120
|
+
| |__ __ __ __ _ _ __ ___
|
121
|
+
| __| \ \ / / / _. | | '_ \ / __|
|
122
|
+
| |____ \ V / | (_| | | | | | \__ \
|
123
|
+
|______| \_/ \__,_| |_| |_| |___/
|
124
|
+
|
125
|
+
more expressive universal gRPC client
|
126
|
+
|
127
|
+
|
128
|
+
echo.EchoService@127.0.0.1:3000> call Echo
|
129
|
+
message (TYPE_STRING) => Hello
|
130
|
+
{
|
131
|
+
"message": "Hello"
|
132
|
+
}
|
133
|
+
|
134
|
+
echo.EchoService@127.0.0.1:3000>
|
135
|
+
```
|
136
|
+
|
137
|
+
### Step 7 — Try the JSON gateway
|
138
|
+
|
139
|
+
You can also POST plain JSON (works over HTTP/1.1 or HTTP/2):
|
140
|
+
```bash
|
141
|
+
curl \
|
142
|
+
-H 'Content-Type: application/json' \
|
143
|
+
-H "Content-Type: application/json" \
|
144
|
+
-X POST http://localhost:3000/echo.EchoService/Echo \
|
145
|
+
-d '{"message":"world"}'
|
146
|
+
|
147
|
+
{"message":"world"}
|
148
|
+
|
149
|
+
```
|
150
|
+
|
151
|
+
{{% /steps %}}
|
152
|
+
|
153
|
+
|
154
|
+
## JSON gateway
|
155
|
+
Itsi exposes gRPC services via a secondary JSON gateways for use with simple HTTP clients.
|
156
|
+
Once mounted, each service‐method is *also* reachable via HTTP/2 and via simple JSON POSTs:
|
157
|
+
|
158
|
+
```bash
|
159
|
+
# Unary RPC (Echo)
|
160
|
+
curl -X POST http://0.0.0.0:3000/EchoService/Echo \
|
161
|
+
-H "Content-Type: application/json" \
|
162
|
+
-d '{"message":"hello"}'
|
163
|
+
# → 200 OK, body: {"message":"hello"}
|
164
|
+
|
165
|
+
# Server streaming RPC (e.g. "Numbers"): POST an array, receive JSON array:
|
166
|
+
curl -X POST http://0.0.0.0:3000/NumberService/Stream \
|
167
|
+
-H "Content-Type: application/json" \
|
168
|
+
-d '[{"n":1},{"n":2},{"n":3}]'
|
169
|
+
# → 200 OK, body: [{"n":1},{"n":2},{"n":3}]
|
170
|
+
```
|
171
|
+
|
172
|
+
Under the hood, the same framing machinery is used—you just get plain JSON arrays instead of gRPC frames.
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class Grpc < Middleware
|
5
|
+
insert_text [
|
6
|
+
<<~SNIPPET,
|
7
|
+
grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|} do
|
8
|
+
${3:# nested middleware…}
|
9
|
+
end
|
10
|
+
SNIPPET
|
11
|
+
|
12
|
+
<<~SNIPPET,
|
13
|
+
grpc ${1:MyServiceImpl.new}, nonblocking: ${2|false,true|}
|
14
|
+
SNIPPET
|
15
|
+
]
|
16
|
+
|
17
|
+
detail [
|
18
|
+
"gRPC service with middleware (with HTTP/2, compression, reflection and JSON gateway)",
|
19
|
+
"gRPC service (with HTTP/2, compression, reflection and JSON gateway)"
|
20
|
+
]
|
21
|
+
|
22
|
+
schema do
|
23
|
+
{
|
24
|
+
handlers: Array(Type(Object)) & Required(),
|
25
|
+
reflection: Bool().default(true),
|
26
|
+
nonblocking: Bool().default(false),
|
27
|
+
inner_block: Type(Proc)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(location, *handlers, reflection: true, nonblocking: false, &block)
|
32
|
+
super(location, {
|
33
|
+
handlers: handlers,
|
34
|
+
reflection: reflection,
|
35
|
+
nonblocking: nonblocking,
|
36
|
+
inner_block: block
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
def build!
|
41
|
+
location.grpc_reflection(@params[:handlers]) if @params[:reflection]
|
42
|
+
nonblocking = @params[:nonblocking]
|
43
|
+
blk = @params[:inner_block]
|
44
|
+
@params[:handlers].each do |handler|
|
45
|
+
location.location(Regexp.new("#{Regexp.escape(handler.class.service_name)}/(?:#{handler.class.rpc_descs.keys.map(&:to_s).join("|")})")) do
|
46
|
+
@middleware[:app] = { preloader: -> { Itsi::Server::GrpcInterface.for(handler) }, request_type: "grpc", nonblocking: nonblocking }
|
47
|
+
instance_exec(&blk) if blk
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
---
|
2
|
+
title: Intrusion Protection
|
3
|
+
url: /middleware/intrusion_protection
|
4
|
+
---
|
5
|
+
|
6
|
+
The **Intrusion Protection** middleware detects and automatically bans clients that attempt to access suspicious URLs or send malicious header values. It combines pattern‑based detection (on request paths and header values) with a back‑end ban manager to temporarily block offending IPs.
|
7
|
+
|
8
|
+
- **URL Patterns**: a list of regexes; any matching request path causes an immediate ban.
|
9
|
+
- **Header Patterns**: per‑header regex lists; any matching header value causes a ban.
|
10
|
+
- **Ban Duration**: how long (in seconds) to block the client IP.
|
11
|
+
- **Store**: in‑memory or Redis‑backed (`store_config`) for both tracking and bans.
|
12
|
+
- **Error Response**: customizable (default is `forbidden`).
|
13
|
+
|
14
|
+
## Configuration
|
15
|
+
|
16
|
+
```ruby {filename=Itsi.rb}
|
17
|
+
intrusion_protection \
|
18
|
+
banned_url_patterns: [
|
19
|
+
"/admin/login", # brute‑force login attempts
|
20
|
+
/\.php$/ # any PHP‑extension request
|
21
|
+
],
|
22
|
+
banned_header_patterns: {
|
23
|
+
"User-Agent" => [
|
24
|
+
"sqlmap", # SQL injection scanner
|
25
|
+
"curl" # script‑based probing
|
26
|
+
]
|
27
|
+
},
|
28
|
+
banned_time_seconds: 300, # ban for 5 minutes
|
29
|
+
store_config: "in_memory",# or { redis: { connection_url: "redis://…" } }
|
30
|
+
error_response: "forbidden"
|
31
|
+
```
|
32
|
+
|
33
|
+
### Using `KnownPaths` Helpers
|
34
|
+
|
35
|
+
Itsi provides a `KnownPaths` module with many pre‑assembled lists of common attack targets taken from [FuzzDB](https://blog.mozilla.org/security/2013/08/16/introducing-fuzzdb/) (e.g. typical login or backup file locations). Each helper returns an `Array<String>` you can pass directly:
|
36
|
+
|
37
|
+
```ruby {filename=Itsi.rb}
|
38
|
+
# ban all common WordPress plugin endpoints
|
39
|
+
intrusion_protection \
|
40
|
+
banned_url_patterns: Itsi::Server::KnownPaths.cms_wp_plugins,
|
41
|
+
banned_time_seconds: 600
|
42
|
+
|
43
|
+
# ban both login files and directory‑brute paths
|
44
|
+
intrusion_protection \
|
45
|
+
banned_url_patterns: (
|
46
|
+
Itsi::Server::KnownPaths.login_file_locations_logins +
|
47
|
+
Itsi::Server::KnownPaths.filename_dirname_bruteforce_common_web_extensions
|
48
|
+
).uniq,
|
49
|
+
banned_time_seconds: 900
|
50
|
+
```
|
51
|
+
|
52
|
+
Available helper methods live under `Itsi::Server::KnownPaths`—for example:
|
53
|
+
|
54
|
+
- `login_file_locations_logins`
|
55
|
+
- `filename_dirname_bruteforce_test_demo`
|
56
|
+
- `cms_wp_plugins`
|
57
|
+
- `php_php_common_backdoors`
|
58
|
+
- …and many more.
|
59
|
+
To see all options, execute
|
60
|
+
```ruby
|
61
|
+
Itsi::Server::KnownPaths::ALL
|
62
|
+
```
|
63
|
+
in a REPL or see the raw input files [here](https://github.com/wouterken/itsi/tree/main/gems/server/lib/itsi/server/config/known_paths).
|
64
|
+
|
65
|
+
### Options
|
66
|
+
|
67
|
+
- **banned_url_patterns** (Array<String>)
|
68
|
+
Regexes applied to the full `path_and_query` of each request. A match → immediate ban+403.
|
69
|
+
- **banned_header_patterns** (Hash<String,Array<String>>)
|
70
|
+
For each header name, a list of regexes tested against that header’s value. A match → ban+403.
|
71
|
+
- **banned_time_seconds** (Integer)
|
72
|
+
Duration (in seconds) to keep the client IP banned.
|
73
|
+
- **store_config** (`"in_memory"` or `{ redis: { connection_url: String } }`)
|
74
|
+
Backend for counters and ban state.
|
75
|
+
- **error_response** (String or detailed ErrorResponse)
|
76
|
+
Response returned on detection or if IP is already banned (default: `forbidden`).
|
77
|
+
- **trusted_proxies** (Hash<String,Hash>)
|
78
|
+
Map of trusted proxy IP addresses to their forwarded header configuration.
|
79
|
+
|
80
|
+
## How It Works
|
81
|
+
|
82
|
+
1. **Initialization**
|
83
|
+
- Compile `banned_url_patterns` into a `RegexSet`.
|
84
|
+
- Compile each set of header patterns into its own `RegexSet`.
|
85
|
+
- Instantiate a `RateLimiter` and `BanManager` (in‑memory or Redis).
|
86
|
+
|
87
|
+
2. **Per‑Request**
|
88
|
+
- **Check ban status**: if the IP is already banned, return `error_response` immediately.
|
89
|
+
- **URL check**: if the request’s `path_and_query` matches any banned URL pattern, ban the IP for `banned_time_seconds` and return `error_response`.
|
90
|
+
- **Header check**: for each configured header, if its value matches any banned pattern, ban the IP and return `error_response`.
|
91
|
+
- Otherwise, allow the request to proceed.
|
92
|
+
|
93
|
+
Banned IPs are automatically un‑banned after the specified TTL.
|
94
|
+
|
95
|
+
## Trusted Proxies
|
96
|
+
|
97
|
+
By default, an intrusion protection 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.
|
98
|
+
|
99
|
+
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.
|
100
|
+
|
101
|
+
|
102
|
+
### Configuring trusted_proxies
|
103
|
+
|
104
|
+
To trust one or more upstream proxies, provide a trusted_proxies map in the middleware configuration.
|
105
|
+
E.g.
|
106
|
+
```ruby {filename=Itsi.rb}
|
107
|
+
intrusion_protection \
|
108
|
+
banned_url_patterns: [
|
109
|
+
"/admin/login", # brute‑force login attempts
|
110
|
+
/\.php$/ # any PHP‑extension request
|
111
|
+
],
|
112
|
+
banned_header_patterns: {
|
113
|
+
"User-Agent" => [
|
114
|
+
"sqlmap", # SQL injection scanner
|
115
|
+
"curl" # script‑based probing
|
116
|
+
]
|
117
|
+
},
|
118
|
+
banned_time_seconds: 300, # ban for 5 minutes
|
119
|
+
store_config: "in_memory",# or { redis: { connection_url: "redis://…" } }
|
120
|
+
error_response: "forbidden",
|
121
|
+
trusted_proxies: {
|
122
|
+
"192.168.1.1" => { header: { name: "X-Forwarded-For" } }
|
123
|
+
}
|
124
|
+
```
|