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,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is the default Itsi configuration file, installed when you run `itsi init`
|
4
|
+
# It contains a sane starting point for configuring your Itsi server.
|
5
|
+
# You can use this file in both development and production environments.
|
6
|
+
# Most of the options in this file can be overridden by command line options.
|
7
|
+
# Check out itsi -h to learn more about the command line options available to you.
|
8
|
+
|
9
|
+
env = ENV.fetch("APP_ENV") { ENV.fetch("RACK_ENV", "development") }
|
10
|
+
|
11
|
+
# Number of worker processes to spawn
|
12
|
+
# If more than 1, Itsi will be booted in Cluster mode
|
13
|
+
workers ENV.fetch("ITSI_WORKERS") {
|
14
|
+
require "etc"
|
15
|
+
env == "development" ? 1 : nil
|
16
|
+
}
|
17
|
+
|
18
|
+
# Number of threads to spawn per worker process
|
19
|
+
# For pure CPU bound applicationss, you'll get the best results keeping this number low
|
20
|
+
# Setting a value of 1 is great for superficial benchmarks, but in reality
|
21
|
+
# it's better to set this a bit higher to allow expensive requests to get overtaken and minimize head-of-line blocking
|
22
|
+
threads ENV.fetch("ITSI_THREADS", 3)
|
23
|
+
|
24
|
+
# If your application is IO bound (e.g. performing a lot of proxied HTTP requests, or heavy queries etc)
|
25
|
+
# you can see *substantial* benefits from enabling this option.
|
26
|
+
# To set this option, pass a string, not a class (as we will not have loaded the class yet)
|
27
|
+
# E.g.
|
28
|
+
# `fiber_scheduler "Itsi::Scheduler"` - The default fast and light-weight scheduler that comes with Itsi
|
29
|
+
# `fiber_scheduler "Async::Scheduler"` - Bring your own scheduler!
|
30
|
+
fiber_scheduler nil
|
31
|
+
|
32
|
+
# If you bind to https, without specifying a certificate, Itsi will use a self-signed certificate.
|
33
|
+
# The self-signed certificate will use a CA generated for your host and stored inside `ITSI_LOCAL_CA_DIR` (Defaults to ~/.itsi)
|
34
|
+
# bind "https://localhost:3000"
|
35
|
+
# bind "https://localhost:3000?domains=dev.itsi.fyi"
|
36
|
+
#
|
37
|
+
# If you want to use let's encrypt to generate you a real certificate you and pass cert=acme and an acme_email address to generate one.
|
38
|
+
# bind "https://itsi.fyi?cert=acme&acme_email=admin@itsi.fyi"
|
39
|
+
# You can generate certificates for multiple domains at once, by passing a comma-separated list of domains
|
40
|
+
# bind "https://0.0.0.0?domains=foo.itsi.fyi,bar.itsi.fyi&cert=acme&acme_email=admin@itsi.fyi"
|
41
|
+
#
|
42
|
+
# If you already have a certificate you can specify it using the cert and key parameters
|
43
|
+
# bind "https://itsi.fyi?cert=/path/to/cert.pem&key=/path/to/key.pem"
|
44
|
+
#
|
45
|
+
# You can also bind to a unix socket or a tls unix socket. E.g.
|
46
|
+
# bind "unix:///tmp/itsi.sock"
|
47
|
+
# bind "tls:///tmp/itsi.secure.sock"
|
48
|
+
|
49
|
+
if env == "development"
|
50
|
+
bind "http://localhost:3000"
|
51
|
+
else
|
52
|
+
bind "https://0.0.0.0?domains=#{ENV["PRODUCTION_DOMAINS"]}&cert=acme&acme_email=admin@itsi.fyi"
|
53
|
+
end
|
54
|
+
|
55
|
+
# If you want to preload the application, set preload to true
|
56
|
+
# to load the entire rack-app defined in rack_file_name before forking.
|
57
|
+
# Alternatively, you can preload just a specific set of gems in a group in your gemfile,
|
58
|
+
# by providing the group name here.
|
59
|
+
# E.g.
|
60
|
+
#
|
61
|
+
# preload :preload # Load gems inside the preload group
|
62
|
+
# preload false # Don't preload.
|
63
|
+
#
|
64
|
+
# If you want to be able to perform zero-downtime deploys using a single itsi process,
|
65
|
+
# you should disable preloads, so that the application is loaded fresh each time a new worker boots
|
66
|
+
preload true
|
67
|
+
|
68
|
+
# Set the maximum memory limit for each worker process in bytes
|
69
|
+
# When this limit is reached, the worker will be gracefully restarted.
|
70
|
+
# Only one worker is restarted at a time to ensure we don't take down
|
71
|
+
# all of them at once, if they reach the threshold simultaneously.
|
72
|
+
worker_memory_limit 1024 * 1024 * 1024
|
73
|
+
|
74
|
+
# You can provide an optional block of code to run, when a worker hits its memory threshold (Use this to send yourself an alert,
|
75
|
+
# write metrics to disk etc. etc.)
|
76
|
+
after_memory_limit_reached do |pid|
|
77
|
+
puts "Worker #{pid} has reached its memory threshold and will restart"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Do clean up of any non-threadsafe resources before forking a new worker here.
|
81
|
+
before_fork {}
|
82
|
+
|
83
|
+
# Reinitialize any non-threadsafe resources after forking a new worker here.
|
84
|
+
after_fork {}
|
85
|
+
|
86
|
+
# Shutdown timeout
|
87
|
+
# Number of seconds to wait for workers to gracefully shutdown before killing them.
|
88
|
+
shutdown_timeout 5
|
89
|
+
|
90
|
+
# Set this to false for application environments that require rack.input to be a rewindable body
|
91
|
+
# (like Rails). For rack applications that can stream inputs, you can set this to true for a more memory-efficient approach.
|
92
|
+
stream_body false
|
93
|
+
|
94
|
+
# OOB GC responses threshold
|
95
|
+
# Specifies how frequently OOB gc should be triggered during periods where there is a gap in queued requests.
|
96
|
+
# Setting this too low can substantially worsen performance
|
97
|
+
oob_gc_responses_threshold 512
|
98
|
+
|
99
|
+
# Log level
|
100
|
+
# Set this to one of the following values: debug, info, warn, error, fatal
|
101
|
+
# Can also be set using the ITSI_LOG environment variable
|
102
|
+
log_level :info
|
103
|
+
|
104
|
+
# Log Format
|
105
|
+
# Set this to be either :plain or :json. If you leave it blank Itsi will try
|
106
|
+
# and auto-detect the format based on the TTY environment.
|
107
|
+
log_format :plain
|
@@ -0,0 +1,246 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
module Itsi
|
6
|
+
class GrpcCall
|
7
|
+
attr_accessor :rpc_desc
|
8
|
+
|
9
|
+
def input_stream?
|
10
|
+
@input_stream ||= @rpc_desc&.input&.is_a?(GRPC::RpcDesc::Stream) || false
|
11
|
+
end
|
12
|
+
|
13
|
+
def output_stream?
|
14
|
+
@output_stream ||= @rpc_desc&.output&.is_a?(GRPC::RpcDesc::Stream) || false
|
15
|
+
end
|
16
|
+
|
17
|
+
def input_type
|
18
|
+
@input_type ||= input_stream? ? rpc_desc.input.type : rpc_desc.input
|
19
|
+
end
|
20
|
+
|
21
|
+
def output_type
|
22
|
+
@output_type ||= output_stream? ? rpc_desc.output.type : rpc_desc.output
|
23
|
+
end
|
24
|
+
|
25
|
+
def reader
|
26
|
+
@reader ||= IO.open(stream.reader_fileno, "rb")
|
27
|
+
end
|
28
|
+
|
29
|
+
def close
|
30
|
+
if output_stream? && content_type == "application/json"
|
31
|
+
stream.write("[") unless @opened
|
32
|
+
stream.write("]")
|
33
|
+
end
|
34
|
+
|
35
|
+
@reader&.close
|
36
|
+
stream.close
|
37
|
+
end
|
38
|
+
|
39
|
+
def deadline
|
40
|
+
return @deadline if defined?(@deadline)
|
41
|
+
return @deadline = nil unless timeout
|
42
|
+
|
43
|
+
@deadline = Time.now + timeout
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_from_json_stream(json_stream)
|
47
|
+
first_char = nil
|
48
|
+
loop do
|
49
|
+
char = json_stream.read(1)
|
50
|
+
break if char.nil?
|
51
|
+
if char =~ /\s/
|
52
|
+
next
|
53
|
+
elsif ["[", ","].include?(char)
|
54
|
+
first_char = char
|
55
|
+
break
|
56
|
+
elsif char == "]"
|
57
|
+
return nil
|
58
|
+
else
|
59
|
+
# If the first non-whitespace character is not '[' or comma, return nil.
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
return nil if first_char.nil?
|
65
|
+
|
66
|
+
# Step 2: Process objects until we hit the end of the JSON stream or array.
|
67
|
+
loop do
|
68
|
+
# Skip any whitespace or commas preceding an object.
|
69
|
+
char = nil
|
70
|
+
loop do
|
71
|
+
char = json_stream.read(1)
|
72
|
+
break if char.nil?
|
73
|
+
next if char =~ /\s/
|
74
|
+
|
75
|
+
break
|
76
|
+
end
|
77
|
+
# The next non-whitespace, non-comma character should be the start of an object.
|
78
|
+
return nil unless char == "{"
|
79
|
+
|
80
|
+
# Step 3: Start buffering the JSON object.
|
81
|
+
buffer = "{".dup
|
82
|
+
stack = ["{"]
|
83
|
+
in_string = false
|
84
|
+
escape = false
|
85
|
+
|
86
|
+
while stack.any?
|
87
|
+
ch = json_stream.read(1)
|
88
|
+
return nil if ch.nil? # premature end of stream
|
89
|
+
|
90
|
+
buffer << ch
|
91
|
+
|
92
|
+
|
93
|
+
if in_string
|
94
|
+
if escape
|
95
|
+
escape = false
|
96
|
+
next
|
97
|
+
end
|
98
|
+
if ch == "\\"
|
99
|
+
escape = true
|
100
|
+
elsif ch == '"'
|
101
|
+
in_string = false
|
102
|
+
end
|
103
|
+
elsif ch == '"'
|
104
|
+
in_string = true
|
105
|
+
elsif ["{", "["].include?(ch)
|
106
|
+
stack.push(ch)
|
107
|
+
elsif ["}", "]"].include?(ch)
|
108
|
+
expected = (ch == "}" ? "{" : "[")
|
109
|
+
# Check for matching bracket.
|
110
|
+
return nil unless stack.last == expected
|
111
|
+
|
112
|
+
stack.pop
|
113
|
+
end
|
114
|
+
end
|
115
|
+
# Yield the complete JSON object (as a string).
|
116
|
+
return buffer
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def remote_read
|
121
|
+
if content_type == "application/json"
|
122
|
+
if input_stream?
|
123
|
+
if next_item = parse_from_json_stream(reader)
|
124
|
+
input_type.decode_json(next_item)
|
125
|
+
end
|
126
|
+
else
|
127
|
+
input_type.decode_json(reader.read)
|
128
|
+
end
|
129
|
+
else
|
130
|
+
header = reader.read(5)
|
131
|
+
return nil if header.nil? || header.bytesize < 5
|
132
|
+
|
133
|
+
compressed = header.bytes[0] == 1
|
134
|
+
length = header[1..4].unpack1("N")
|
135
|
+
|
136
|
+
data = reader.read(length)
|
137
|
+
return nil if data.nil?
|
138
|
+
|
139
|
+
data = decompress_input(data) if compressed
|
140
|
+
|
141
|
+
input_type.decode(data)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def send_framed_message(message_data, compressed = nil)
|
146
|
+
if content_type == "application/json"
|
147
|
+
if output_stream?
|
148
|
+
if @opened
|
149
|
+
stream.write(",\n")
|
150
|
+
else
|
151
|
+
stream.write("[")
|
152
|
+
@opened = true
|
153
|
+
end
|
154
|
+
end
|
155
|
+
message_data = output_type.encode_json(message_data)
|
156
|
+
stream.write(message_data)
|
157
|
+
else
|
158
|
+
message_data = output_type.encode(message_data)
|
159
|
+
should_compress = compressed.nil? ? should_compress_output?(message_data.bytesize) : compressed
|
160
|
+
|
161
|
+
if should_compress
|
162
|
+
message_data = compress_output(message_data)
|
163
|
+
compressed_flag = 1
|
164
|
+
else
|
165
|
+
compressed_flag = 0
|
166
|
+
end
|
167
|
+
|
168
|
+
message = [compressed_flag, message_data.bytesize].pack("CN") << message_data
|
169
|
+
stream.write(message)
|
170
|
+
|
171
|
+
@body_written = true
|
172
|
+
end
|
173
|
+
rescue IOError
|
174
|
+
close
|
175
|
+
end
|
176
|
+
|
177
|
+
def remote_send(response)
|
178
|
+
send_framed_message(response)
|
179
|
+
end
|
180
|
+
|
181
|
+
def deadline_exceeded?
|
182
|
+
@deadline && @deadline <= Time.now
|
183
|
+
end
|
184
|
+
|
185
|
+
def each_remote_read
|
186
|
+
return enum_for(:each_remote_read) unless block_given?
|
187
|
+
|
188
|
+
while (resp = remote_read) || !cancelled?
|
189
|
+
|
190
|
+
yield resp
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def bidi_streamer?
|
195
|
+
input_stream? && output_stream?
|
196
|
+
end
|
197
|
+
|
198
|
+
def client_streamer?
|
199
|
+
input_stream? && !output_stream?
|
200
|
+
end
|
201
|
+
|
202
|
+
def server_streamer?
|
203
|
+
!input_stream? && output_stream?
|
204
|
+
end
|
205
|
+
|
206
|
+
def request_response?
|
207
|
+
!input_stream? && !output_stream?
|
208
|
+
end
|
209
|
+
|
210
|
+
def send_initial_metadata(kv_pairs)
|
211
|
+
add_headers(kv_pairs.transform_values { |v| Array(v) })
|
212
|
+
end
|
213
|
+
|
214
|
+
def send_empty
|
215
|
+
remote_send(output_type.new) unless @body_written
|
216
|
+
end
|
217
|
+
|
218
|
+
def send_status(status_code, status_details, trailing_metadata = {})
|
219
|
+
trailers = {
|
220
|
+
"grpc-status" => status_code.to_s
|
221
|
+
}
|
222
|
+
|
223
|
+
unless status_details.nil? || status_details.empty?
|
224
|
+
encoded_message = status_details.gsub(/[ #%&+,:;<=>?@\[\]^`{|}~\\"]/) do |c|
|
225
|
+
"%" + c.ord.to_s(16).upcase
|
226
|
+
end
|
227
|
+
trailers["grpc-message"] = encoded_message
|
228
|
+
end
|
229
|
+
|
230
|
+
trailing_metadata.each do |key, value|
|
231
|
+
trailers[key] = \
|
232
|
+
if key.to_s.end_with?("-bin")
|
233
|
+
Base64.strict_encode64(value.to_s)
|
234
|
+
else
|
235
|
+
value.to_s
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
send_trailers(trailers)
|
240
|
+
end
|
241
|
+
|
242
|
+
def send_trailers(trailers)
|
243
|
+
stream.send_trailers(trailers)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
class GrpcInterface
|
4
|
+
DeadlineExceeded = Class.new(StandardError)
|
5
|
+
|
6
|
+
attr_accessor :service, :service_class
|
7
|
+
|
8
|
+
def self.for(service)
|
9
|
+
interface = new(service)
|
10
|
+
lambda do |request|
|
11
|
+
interface.handle_request(request)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.reflection_for(handlers)
|
16
|
+
require_relative "reflection/v1/reflection_services_pb"
|
17
|
+
interface = new(Grpc::Reflection::V1::ServerReflection::Service.new(handlers))
|
18
|
+
lambda do |request|
|
19
|
+
interface.handle_request(request)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(service)
|
24
|
+
@service = service
|
25
|
+
@service_class = service.class
|
26
|
+
@rpc_descs = @service_class.rpc_descs.transform_keys do |k|
|
27
|
+
k.to_s.gsub(/([a-z])([A-Z])/, "\\1_\\2").downcase.to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle_request(active_call)
|
32
|
+
puts "Handling active call"
|
33
|
+
unless (active_call.rpc_desc = @rpc_descs[active_call.method_name])
|
34
|
+
active_call.stream.write("\n")
|
35
|
+
active_call.send_status(13, "Method not found")
|
36
|
+
active_call.close
|
37
|
+
return
|
38
|
+
end
|
39
|
+
|
40
|
+
active_call.send_initial_metadata(
|
41
|
+
{
|
42
|
+
"grpc-accept-encoding" => "gzip, deflate, identity",
|
43
|
+
"content-type" => active_call.json? ? "application/json" : "application/grpc"
|
44
|
+
}
|
45
|
+
)
|
46
|
+
|
47
|
+
begin
|
48
|
+
if active_call.bidi_streamer?
|
49
|
+
handle_bidi_streaming(active_call)
|
50
|
+
elsif active_call.client_streamer?
|
51
|
+
handle_client_streaming(active_call)
|
52
|
+
elsif active_call.server_streamer?
|
53
|
+
handle_server_streaming(active_call)
|
54
|
+
elsif active_call.request_response?
|
55
|
+
handle_unary(active_call)
|
56
|
+
end
|
57
|
+
active_call.send_status(0, "Success")
|
58
|
+
rescue Google::Protobuf::ParseError => e
|
59
|
+
active_call.send_empty
|
60
|
+
active_call.send_status(3, e.message)
|
61
|
+
rescue DeadlineExceeded => e
|
62
|
+
active_call.send_empty
|
63
|
+
active_call.send_status(4, e.message)
|
64
|
+
rescue StandardError => e
|
65
|
+
active_call.send_empty
|
66
|
+
active_call.send_status(13, e.message)
|
67
|
+
end
|
68
|
+
rescue StandardError => e
|
69
|
+
Itsi.log_warn("Unhandled error in grpc_interface: #{e.message}")
|
70
|
+
ensure
|
71
|
+
active_call.close
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def handle_unary(active_call)
|
77
|
+
message = active_call.remote_read
|
78
|
+
response = service.send(active_call.method_name, message, active_call)
|
79
|
+
active_call.remote_send(response)
|
80
|
+
end
|
81
|
+
|
82
|
+
def handle_client_streaming(active_call)
|
83
|
+
response = service.send(active_call.method_name, active_call.each_remote_read, active_call)
|
84
|
+
active_call.remote_send(response)
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_server_streaming(active_call)
|
88
|
+
message = active_call.remote_read
|
89
|
+
result = service.send(active_call.method_name, message, active_call) do |response|
|
90
|
+
active_call.remote_send(response)
|
91
|
+
end
|
92
|
+
if result.kind_of?(Enumerator)
|
93
|
+
result.each { |response| active_call.remote_send(response) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def handle_bidi_streaming(active_call)
|
98
|
+
result = service.send(active_call.method_name, active_call.each_remote_read, active_call) do |response|
|
99
|
+
active_call.remote_send(response)
|
100
|
+
end
|
101
|
+
if result.kind_of?(Enumerator)
|
102
|
+
result.each { |response| active_call.remote_send(response) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
|
+
# source: reflection.proto
|
4
|
+
|
5
|
+
require 'google/protobuf'
|
6
|
+
require "google/protobuf/descriptor_pb"
|
7
|
+
|
8
|
+
descriptor_data = "\n\x10reflection.proto\x12\x12grpc.reflection.v1\"\x85\x02\n\x17ServerReflectionRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x1a\n\x10\x66ile_by_filename\x18\x03 \x01(\tH\x00\x12 \n\x16\x66ile_containing_symbol\x18\x04 \x01(\tH\x00\x12I\n\x19\x66ile_containing_extension\x18\x05 \x01(\x0b\x32$.grpc.reflection.v1.ExtensionRequestH\x00\x12\'\n\x1d\x61ll_extension_numbers_of_type\x18\x06 \x01(\tH\x00\x12\x17\n\rlist_services\x18\x07 \x01(\tH\x00\x42\x11\n\x0fmessage_request\"E\n\x10\x45xtensionRequest\x12\x17\n\x0f\x63ontaining_type\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x01(\x05\"\xb8\x03\n\x18ServerReflectionResponse\x12\x12\n\nvalid_host\x18\x01 \x01(\t\x12\x45\n\x10original_request\x18\x02 \x01(\x0b\x32+.grpc.reflection.v1.ServerReflectionRequest\x12N\n\x18\x66ile_descriptor_response\x18\x04 \x01(\x0b\x32*.grpc.reflection.v1.FileDescriptorResponseH\x00\x12U\n\x1e\x61ll_extension_numbers_response\x18\x05 \x01(\x0b\x32+.grpc.reflection.v1.ExtensionNumberResponseH\x00\x12I\n\x16list_services_response\x18\x06 \x01(\x0b\x32\'.grpc.reflection.v1.ListServiceResponseH\x00\x12;\n\x0e\x65rror_response\x18\x07 \x01(\x0b\x32!.grpc.reflection.v1.ErrorResponseH\x00\x42\x12\n\x10message_response\"7\n\x16\x46ileDescriptorResponse\x12\x1d\n\x15\x66ile_descriptor_proto\x18\x01 \x03(\x0c\"K\n\x17\x45xtensionNumberResponse\x12\x16\n\x0e\x62\x61se_type_name\x18\x01 \x01(\t\x12\x18\n\x10\x65xtension_number\x18\x02 \x03(\x05\"K\n\x13ListServiceResponse\x12\x34\n\x07service\x18\x01 \x03(\x0b\x32#.grpc.reflection.v1.ServiceResponse\"\x1f\n\x0fServiceResponse\x12\x0c\n\x04name\x18\x01 \x01(\t\":\n\rErrorResponse\x12\x12\n\nerror_code\x18\x01 \x01(\x05\x12\x15\n\rerror_message\x18\x02 \x01(\t2\x89\x01\n\x10ServerReflection\x12u\n\x14ServerReflectionInfo\x12+.grpc.reflection.v1.ServerReflectionRequest\x1a,.grpc.reflection.v1.ServerReflectionResponse(\x01\x30\x01\x42\x66\n\x15io.grpc.reflection.v1B\x15ServerReflectionProtoP\x01Z4google.golang.org/grpc/reflection/grpc_reflection_v1b\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Grpc
|
14
|
+
module Reflection
|
15
|
+
module V1
|
16
|
+
ServerReflectionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionRequest").msgclass
|
17
|
+
ExtensionRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionRequest").msgclass
|
18
|
+
ServerReflectionResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServerReflectionResponse").msgclass
|
19
|
+
FileDescriptorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.FileDescriptorResponse").msgclass
|
20
|
+
ExtensionNumberResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ExtensionNumberResponse").msgclass
|
21
|
+
ListServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ListServiceResponse").msgclass
|
22
|
+
ServiceResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ServiceResponse").msgclass
|
23
|
+
ErrorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.reflection.v1.ErrorResponse").msgclass
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# Source: reflection.proto for package 'grpc.reflection.v1'
|
3
|
+
# Original file comments:
|
4
|
+
# Copyright 2016 The gRPC Authors
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
# Service exported by server reflection. A more complete description of how
|
19
|
+
# server reflection works can be found at
|
20
|
+
# https://github.com/grpc/grpc/blob/master/doc/server-reflection.md
|
21
|
+
#
|
22
|
+
# The canonical version of this proto can be found at
|
23
|
+
# https://github.com/grpc/grpc-proto/blob/master/grpc/reflection/v1/reflection.proto
|
24
|
+
#
|
25
|
+
|
26
|
+
require "grpc"
|
27
|
+
require_relative "reflection_pb"
|
28
|
+
|
29
|
+
module Grpc
|
30
|
+
module Reflection
|
31
|
+
module V1
|
32
|
+
module ServerReflection
|
33
|
+
class Service
|
34
|
+
include ::GRPC::GenericService
|
35
|
+
|
36
|
+
self.marshal_class_method = :encode
|
37
|
+
self.unmarshal_class_method = :decode
|
38
|
+
self.service_name = "grpc.reflection.v1.ServerReflection"
|
39
|
+
|
40
|
+
# The reflection service is structured as a bidirectional stream, ensuring
|
41
|
+
# all related requests go to a single server.
|
42
|
+
rpc :ServerReflectionInfo, stream(::Grpc::Reflection::V1::ServerReflectionRequest),
|
43
|
+
stream(::Grpc::Reflection::V1::ServerReflectionResponse)
|
44
|
+
|
45
|
+
def initialize(handlers)
|
46
|
+
@handlers = handlers
|
47
|
+
super()
|
48
|
+
end
|
49
|
+
|
50
|
+
def server_reflection_info(req, _unused_call)
|
51
|
+
req.each do |request|
|
52
|
+
res = Grpc::Reflection::V1::ServerReflectionResponse.new
|
53
|
+
|
54
|
+
if !request.list_services.empty?
|
55
|
+
res.list_services_response = Grpc::Reflection::V1::ListServiceResponse.new(service: list_services_response)
|
56
|
+
elsif !request.file_containing_symbol.empty?
|
57
|
+
res.file_descriptor_response = Grpc::Reflection::V1::FileDescriptorResponse.new(
|
58
|
+
file_descriptor_proto: [
|
59
|
+
Google::Protobuf::FileDescriptorProto.encode(Google::Protobuf::DescriptorPool.generated_pool.lookup(request.file_containing_symbol).file_descriptor.to_proto)
|
60
|
+
]
|
61
|
+
)
|
62
|
+
elsif !request.file_by_filename.empty?
|
63
|
+
# Handle file_by_filename requests
|
64
|
+
file_descriptor = find_file_descriptor_by_filename(request.file_by_filename)
|
65
|
+
if file_descriptor
|
66
|
+
res.file_descriptor_response = Grpc::Reflection::V1::FileDescriptorResponse.new(
|
67
|
+
file_descriptor_proto: [Google::Protobuf::FileDescriptorProto.encode(file_descriptor)]
|
68
|
+
)
|
69
|
+
else
|
70
|
+
res.error_response = Grpc::Reflection::V1::ErrorResponse.new(
|
71
|
+
error_code: 5, # NOT_FOUND
|
72
|
+
error_message: "File not found: #{request.file_by_filename}"
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
yield res
|
77
|
+
# We can loop here if running in Fiber mode, but for best compatibility with blocking IO modes
|
78
|
+
# we'll close the connection and force the client to reconnect force
|
79
|
+
# subsequent reflection requests
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def find_file_descriptor_by_filename(filename)
|
85
|
+
# First try direct lookup in the pool
|
86
|
+
|
87
|
+
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(filename)&.file_descriptor
|
88
|
+
return descriptor.to_proto if descriptor
|
89
|
+
|
90
|
+
proto_name = convert_file_path_to_proto_name(filename)
|
91
|
+
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(proto_name)&.file_descriptor
|
92
|
+
return descriptor.to_proto if descriptor
|
93
|
+
|
94
|
+
nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def convert_file_path_to_proto_name(file_path)
|
98
|
+
# Remove .proto extension
|
99
|
+
file_path = file_path.sub(/\.proto$/, "")
|
100
|
+
|
101
|
+
# Split path into parts
|
102
|
+
parts = file_path.split("/")
|
103
|
+
|
104
|
+
# Convert last part to PascalCase (e.g., money -> Money)
|
105
|
+
parts[-1] = parts[-1].split("_").map(&:capitalize).join
|
106
|
+
|
107
|
+
# Join with dots
|
108
|
+
parts.join(".")
|
109
|
+
end
|
110
|
+
|
111
|
+
def list_services_response
|
112
|
+
@list_services_response ||= @handlers.map(&:class).map(&:service_name).map do |name|
|
113
|
+
Grpc::Reflection::V1::ServiceResponse.new(name: name)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
Stub = Service.rpc_stub_class
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
return unless defined?(::Rackup::Handler) || defined?(Rack::Handler)
|
2
|
+
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
module Handler
|
6
|
+
module Itsi
|
7
|
+
def self.run(app, options = {})
|
8
|
+
host = options.fetch(:host, "127.0.0.1")
|
9
|
+
port = options.fetch(:Port, 3001)
|
10
|
+
::Itsi::Server.start(
|
11
|
+
{
|
12
|
+
app: app,
|
13
|
+
binds: ["http://#{host}:#{port}"]
|
14
|
+
}
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if defined?(Rackup)
|
22
|
+
::Rackup::Handler.register("itsi", Rack::Handler::Itsi)
|
23
|
+
::Rackup::Handler.register("Itsi", Rack::Handler::Itsi)
|
24
|
+
elsif defined?(Rack)
|
25
|
+
::Rack::Handler.register("itsi", Rack::Handler::Itsi)
|
26
|
+
::Rack::Handler.register("Itsi", Rack::Handler::Itsi)
|
27
|
+
end
|