itsi 0.1.20 → 0.2.3
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/CHANGELOG.md +1 -8
- data/Cargo.lock +29 -30
- data/LICENSE.txt +698 -0
- data/README.md +16 -4
- data/Rakefile +9 -5
- data/crates/itsi_acme/.gitignore +4 -0
- data/crates/itsi_acme/Cargo.toml +86 -0
- data/crates/itsi_acme/LICENSE-APACHE +201 -0
- data/crates/itsi_acme/LICENSE-MIT +23 -0
- data/crates/itsi_acme/README.md +9 -0
- data/crates/itsi_acme/examples/high_level.rs +63 -0
- data/crates/itsi_acme/examples/high_level_warp.rs +52 -0
- data/crates/itsi_acme/examples/low_level.rs +87 -0
- data/crates/itsi_acme/examples/low_level_axum.rs +66 -0
- data/crates/itsi_acme/src/acceptor.rs +81 -0
- data/crates/itsi_acme/src/acme.rs +354 -0
- data/crates/itsi_acme/src/axum.rs +86 -0
- data/crates/itsi_acme/src/cache.rs +39 -0
- data/crates/itsi_acme/src/caches/boxed.rs +80 -0
- data/crates/itsi_acme/src/caches/composite.rs +69 -0
- data/crates/itsi_acme/src/caches/dir.rs +106 -0
- data/crates/itsi_acme/src/caches/mod.rs +11 -0
- data/crates/itsi_acme/src/caches/no.rs +78 -0
- data/crates/itsi_acme/src/caches/test.rs +136 -0
- data/crates/itsi_acme/src/config.rs +172 -0
- data/crates/itsi_acme/src/https_helper.rs +69 -0
- data/crates/itsi_acme/src/incoming.rs +142 -0
- data/crates/itsi_acme/src/jose.rs +161 -0
- data/crates/itsi_acme/src/lib.rs +142 -0
- data/crates/itsi_acme/src/resolver.rs +59 -0
- data/crates/itsi_acme/src/state.rs +424 -0
- data/crates/itsi_rb_helpers/src/lib.rs +4 -3
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_scheduler/src/itsi_scheduler.rs +8 -2
- data/crates/itsi_scheduler/src/lib.rs +1 -0
- data/crates/itsi_server/Cargo.toml +1 -1
- data/crates/itsi_server/src/lib.rs +2 -1
- data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +18 -1
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +11 -3
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +148 -66
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +2 -0
- data/crates/itsi_server/src/server/binds/bind.rs +3 -0
- data/crates/itsi_server/src/server/binds/listener.rs +12 -5
- data/crates/itsi_server/src/server/binds/tls.rs +13 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +12 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +8 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +9 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +48 -43
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +11 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +39 -12
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +36 -27
- data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +25 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +12 -3
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +74 -72
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +15 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +11 -8
- data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +19 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +5 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/max_body.rs +2 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +11 -5
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +17 -20
- data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +19 -8
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +16 -37
- data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +22 -12
- data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +26 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +7 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +14 -4
- data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +19 -0
- data/crates/itsi_server/src/server/middleware_stack/mod.rs +49 -13
- data/crates/itsi_server/src/server/mod.rs +1 -0
- data/crates/itsi_server/src/server/redirect_type.rs +26 -0
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +22 -16
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +49 -12
- data/crates/itsi_server/src/server/signal.rs +1 -0
- data/crates/itsi_server/src/server/size_limited_incoming.rs +6 -0
- data/crates/itsi_server/src/server/thread_worker.rs +5 -1
- data/crates/itsi_server/src/services/itsi_http_service.rs +20 -2
- data/crates/itsi_server/src/services/rate_limiter.rs +15 -4
- data/crates/itsi_server/src/services/static_file_server.rs +33 -19
- data/crates/itsi_tracing/src/lib.rs +42 -22
- data/docs/content/_index.md +2 -3
- data/docs/content/acknowledgements/_index.md +5 -2
- data/docs/content/configuration/_index.md +8 -5
- data/docs/content/contact/_index.md +8 -1
- data/docs/content/directory_listing.jpg +0 -0
- data/docs/content/error_page.jpg +0 -0
- data/docs/content/faqs/_index.md +5 -3
- data/docs/content/features/_index.md +56 -50
- data/docs/content/getting_started/_index.md +8 -5
- data/docs/content/getting_started/local_development.md +76 -9
- data/docs/content/getting_started/logging.md +15 -9
- data/docs/content/getting_started/running_itsi_in_production.md +5 -3
- data/docs/content/getting_started/signals.md +37 -0
- data/docs/content/itsi_scheduler/_index.md +8 -7
- data/docs/content/utilities/_index.md +13 -0
- data/docs/content/utilities/config_file_testing.md +17 -0
- data/docs/content/utilities/passfile_generator.md +41 -0
- data/docs/content/utilities/route_testing.md +27 -0
- data/docs/content/utilities/secrets_management.md +30 -0
- data/docs/hugo.yaml +4 -1
- data/fairytale.txt +3 -4
- data/gems/scheduler/Cargo.lock +74 -17
- data/gems/scheduler/README.md +4 -5
- data/gems/scheduler/Rakefile +0 -4
- data/gems/scheduler/itsi-scheduler.gemspec +2 -2
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/scheduler/lib/itsi/scheduler.rb +9 -4
- data/gems/scheduler/test/test_active_record.rb +12 -7
- data/gems/server/Cargo.lock +28 -29
- data/gems/server/Rakefile +0 -4
- data/gems/server/exe/itsi +13 -2
- data/gems/server/itsi-server.gemspec +2 -2
- data/gems/server/lib/itsi/http_request/response_status_shortcodes.rb +2 -0
- data/gems/server/lib/itsi/http_request.rb +58 -30
- data/gems/server/lib/itsi/http_response.rb +10 -7
- data/gems/server/lib/itsi/passfile.rb +6 -7
- data/gems/server/lib/itsi/server/config/config_helpers.rb +41 -29
- data/gems/server/lib/itsi/server/config/dsl.rb +22 -442
- data/gems/server/lib/itsi/server/config/known_paths.rb +14 -7
- data/gems/server/lib/itsi/server/config/middleware/_index.md +6 -4
- data/gems/server/lib/itsi/server/config/middleware/allow_list.md +46 -0
- data/gems/server/lib/itsi/server/config/middleware/allow_list.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_api_key.md +90 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_api_key.rb +51 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_basic.md +45 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_basic.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_jwt.md +82 -0
- data/gems/server/lib/itsi/server/config/middleware/auth_jwt.rb +38 -0
- data/gems/server/lib/itsi/server/config/middleware/cache_control.md +78 -0
- data/gems/server/lib/itsi/server/config/middleware/cache_control.rb +45 -0
- data/gems/server/lib/itsi/server/config/middleware/cidr_to_regex.rb +50 -0
- data/gems/server/lib/itsi/server/config/middleware/compression.md +50 -0
- data/gems/server/lib/itsi/server/config/middleware/compression.rb +37 -0
- data/gems/server/lib/itsi/server/config/middleware/cors.md +93 -0
- data/gems/server/lib/itsi/server/config/middleware/cors.rb +32 -0
- data/gems/server/lib/itsi/server/config/middleware/csp.md +37 -0
- data/gems/server/lib/itsi/server/config/middleware/csp.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/deny_list.md +45 -0
- data/gems/server/lib/itsi/server/config/middleware/deny_list.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/_index.md +159 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.md +186 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/controller.rb +33 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/delete.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/endpoint.rb +99 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/get.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/get.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/http_request.md +44 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/http_response.md +39 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/patch.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/post.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/post.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/put.md +12 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/put.rb +42 -0
- data/gems/server/lib/itsi/server/config/middleware/endpoint/schemas.md +122 -0
- data/gems/server/lib/itsi/server/config/middleware/error_response.md +74 -0
- data/gems/server/lib/itsi/server/config/middleware/error_response.rb +36 -0
- data/gems/server/lib/itsi/server/config/middleware/etag.md +59 -0
- data/gems/server/lib/itsi/server/config/middleware/etag.rb +27 -0
- data/gems/server/lib/itsi/server/config/middleware/grpc.md +172 -0
- data/gems/server/lib/itsi/server/config/middleware/grpc.rb +54 -0
- data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.md +124 -0
- data/gems/server/lib/itsi/server/config/middleware/intrusion_protection.rb +61 -0
- data/gems/server/lib/itsi/server/config/middleware/location.md +107 -0
- data/gems/server/lib/itsi/server/config/middleware/location.rb +99 -0
- data/gems/server/lib/itsi/server/config/middleware/log_requests.md +13 -11
- data/gems/server/lib/itsi/server/config/middleware/log_requests.rb +1 -3
- data/gems/server/lib/itsi/server/config/middleware/max_body.md +18 -0
- data/gems/server/lib/itsi/server/config/middleware/max_body.rb +21 -0
- data/gems/server/lib/itsi/server/config/middleware/proxy.md +62 -0
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +41 -0
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.md +54 -0
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +44 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit.md +126 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit.rb +34 -0
- data/gems/server/lib/itsi/server/config/middleware/rate_limit_store.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/redirect.md +55 -0
- data/gems/server/lib/itsi/server/config/middleware/redirect.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/request_headers.md +34 -0
- data/gems/server/lib/itsi/server/config/middleware/request_headers.rb +24 -0
- data/gems/server/lib/itsi/server/config/middleware/response_headers.md +33 -0
- data/gems/server/lib/itsi/server/config/middleware/response_headers.rb +25 -0
- data/gems/server/lib/itsi/server/config/middleware/run.md +60 -0
- data/gems/server/lib/itsi/server/config/middleware/run.rb +43 -0
- data/gems/server/lib/itsi/server/config/middleware/static_assets.md +113 -0
- data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +87 -0
- data/gems/server/lib/itsi/server/config/middleware/static_response.md +44 -0
- data/gems/server/lib/itsi/server/config/middleware/static_response.rb +29 -0
- data/gems/server/lib/itsi/server/config/middleware/string_rewrite.md +67 -0
- data/gems/server/lib/itsi/server/config/middleware/token_source.rb +32 -0
- data/gems/server/lib/itsi/server/config/middleware.rb +4 -0
- data/gems/server/lib/itsi/server/config/option.rb +4 -0
- data/gems/server/lib/itsi/server/config/options/_index.md +3 -2
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.md +13 -0
- data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +41 -0
- data/gems/server/lib/itsi/server/config/options/bind.md +71 -0
- data/gems/server/lib/itsi/server/config/options/bind.rb +26 -0
- data/gems/server/lib/itsi/server/config/options/certificates.md +65 -0
- data/gems/server/lib/itsi/server/config/options/daemonize.md +14 -0
- data/gems/server/lib/itsi/server/config/options/daemonize.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/fiber_scheduler.md +1 -2
- data/gems/server/lib/itsi/server/config/options/fiber_scheduler.rb +6 -3
- data/gems/server/lib/itsi/server/config/options/header_read_timeout.md +17 -0
- data/gems/server/lib/itsi/server/config/options/header_read_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/hooks/_index.md +11 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_fork.md +13 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_fork.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.md +14 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_memory_limit_reached.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_start.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/after_start.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_fork.md +13 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_fork.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_restart.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_restart.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.md +12 -0
- data/gems/server/lib/itsi/server/config/options/hooks/before_shutdown.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/include.md +20 -0
- data/gems/server/lib/itsi/server/config/options/include.rb +36 -0
- data/gems/server/lib/itsi/server/config/options/listen_backlog.md +11 -0
- data/gems/server/lib/itsi/server/config/options/listen_backlog.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_format.md +18 -0
- data/gems/server/lib/itsi/server/config/options/log_format.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_level.md +34 -0
- data/gems/server/lib/itsi/server/config/options/log_level.rb +20 -0
- data/gems/server/lib/itsi/server/config/options/log_target.md +38 -0
- data/gems/server/lib/itsi/server/config/options/log_target.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/log_target_filters.md +17 -0
- data/gems/server/lib/itsi/server/config/options/log_target_filters.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.md +27 -0
- data/gems/server/lib/itsi/server/config/options/multithreaded_reactor.rb +24 -0
- data/gems/server/lib/itsi/server/config/options/nodelay.md +16 -0
- data/gems/server/lib/itsi/server/config/options/nodelay.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.md +19 -0
- data/gems/server/lib/itsi/server/config/options/oob_gc_responses_threshold.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/pin_worker_cores.md +17 -0
- data/gems/server/lib/itsi/server/config/options/pin_worker_cores.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/preload.md +21 -0
- data/gems/server/lib/itsi/server/config/options/preload.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/recv_buffer_size.md +15 -0
- data/gems/server/lib/itsi/server/config/options/recv_buffer_size.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.md +21 -0
- data/gems/server/lib/itsi/server/config/options/redirect_http_to_https.rb +30 -0
- data/gems/server/lib/itsi/server/config/options/request_timeout.md +23 -0
- data/gems/server/lib/itsi/server/config/options/request_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/reuse_address.md +16 -0
- data/gems/server/lib/itsi/server/config/options/reuse_address.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/reuse_port.md +16 -0
- data/gems/server/lib/itsi/server/config/options/reuse_port.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/scheduler_threads.md +34 -0
- data/gems/server/lib/itsi/server/config/options/scheduler_threads.rb +17 -0
- data/gems/server/lib/itsi/server/config/options/shutdown_timeout.md +17 -0
- data/gems/server/lib/itsi/server/config/options/shutdown_timeout.rb +19 -0
- data/gems/server/lib/itsi/server/config/options/stream_body.md +32 -0
- data/gems/server/lib/itsi/server/config/options/stream_body.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/threads.md +7 -2
- data/gems/server/lib/itsi/server/config/options/threads.rb +1 -1
- data/gems/server/lib/itsi/server/config/options/watch.md +16 -0
- data/gems/server/lib/itsi/server/config/options/watch.rb +28 -0
- data/gems/server/lib/itsi/server/config/options/worker_memory_limit.md +22 -0
- data/gems/server/lib/itsi/server/config/options/worker_memory_limit.rb +18 -0
- data/gems/server/lib/itsi/server/config/options/workers.md +1 -2
- data/gems/server/lib/itsi/server/config/options/workers.rb +1 -1
- data/gems/server/lib/itsi/server/config/typed_struct.rb +68 -32
- data/gems/server/lib/itsi/server/config.rb +163 -119
- data/gems/server/lib/itsi/server/default_app/default_app.rb +1 -1
- data/gems/server/lib/itsi/server/default_config/Itsi.rb +3 -3
- data/gems/server/lib/itsi/server/grpc/grpc_call.rb +4 -5
- data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +10 -4
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +2 -3
- data/gems/server/lib/itsi/server/rack_interface.rb +0 -1
- data/gems/server/lib/itsi/server/route_tester.rb +61 -9
- data/gems/server/lib/itsi/server/signal_trap.rb +1 -1
- data/gems/server/lib/itsi/server/typed_handlers/param_parser.rb +14 -18
- data/gems/server/lib/itsi/server/typed_handlers/source_parser.rb +13 -10
- data/gems/server/lib/itsi/server/typed_handlers.rb +12 -4
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +111 -27
- data/gems/server/lib/itsi/standard_headers.rb +80 -80
- data/gems/server/lib/ruby_lsp/itsi/addon.rb +20 -18
- data/gems/server/test/helpers/test_helper.rb +90 -29
- data/gems/server/test/middleware/allow_list.rb +128 -0
- data/gems/server/test/middleware/auth_api_key.rb +141 -0
- data/gems/server/test/middleware/auth_basic.rb +91 -0
- data/gems/server/test/middleware/auth_jwt.rb +214 -0
- data/gems/server/test/middleware/cache_control.rb +82 -0
- data/gems/server/test/middleware/cidr_to_regex.rb +46 -0
- data/gems/server/test/middleware/compression.rb +89 -0
- data/gems/server/test/middleware/cors.rb +113 -0
- data/gems/server/test/middleware/csp.rb +62 -0
- data/gems/server/test/middleware/deny_list.rb +131 -0
- data/gems/server/test/middleware/endpoint.rb +300 -0
- data/gems/server/test/middleware/etag.rb +75 -0
- data/gems/server/test/middleware/grpc/grpc.rb +158 -0
- data/gems/server/test/middleware/grpc/test_service.proto +32 -0
- data/gems/server/test/middleware/grpc/test_service_impl.rb +28 -0
- data/gems/server/test/middleware/grpc/test_service_pb.rb +18 -0
- data/gems/server/test/middleware/grpc/test_service_services_pb.rb +30 -0
- data/gems/server/test/middleware/header_interpolation.rb +35 -0
- data/gems/server/test/middleware/intrusion_protection.rb +259 -0
- data/gems/server/test/middleware/location.rb +220 -0
- data/gems/server/test/middleware/max_body.rb +20 -0
- data/gems/server/test/middleware/proxy.rb +415 -0
- data/gems/server/test/middleware/rate_limit.rb +211 -0
- data/gems/server/test/middleware/redirect.rb +85 -0
- data/gems/server/test/middleware/request_headers.rb +50 -0
- data/gems/server/test/middleware/response_headers.rb +50 -0
- data/gems/server/test/middleware/static_assets.rb +374 -0
- data/gems/server/test/middleware/static_response.rb +56 -0
- data/gems/server/test/middleware/string_rewrite.rb +112 -0
- data/gems/server/test/middleware/test_log_requests.rb +54 -2
- data/gems/server/test/options/bind.rb +47 -0
- data/gems/server/test/options/header_read_timeout.rb +23 -0
- data/gems/server/test/options/test_request_timeout.rb +16 -0
- data/gems/server/test/options/test_workers.rb +11 -6
- data/gems/server/test/{test_itsi_server.rb → rack/test_rack_server.rb} +2 -2
- data/lib/itsi/version.rb +1 -1
- data/tasks.txt +15 -72
- metadata +209 -10
- data/examples/static_assets_example.rb +0 -83
- data/gems/server/lib/itsi/server/default_config/Itsi-rackup.rb +0 -119
@@ -1,16 +1,68 @@
|
|
1
1
|
module Itsi
|
2
2
|
class Server
|
3
|
+
# Utility module for printing Itsi route information
|
3
4
|
module RouteTester
|
4
|
-
|
5
5
|
require "set"
|
6
6
|
require "strscan"
|
7
|
-
|
7
|
+
require "debug"
|
8
8
|
def format_mw(mw)
|
9
|
-
|
9
|
+
mw_name, mw_args = mw
|
10
|
+
case mw_name
|
10
11
|
when "app"
|
11
|
-
"
|
12
|
+
"\e[33mapp\e[0m(#{mw_args["app_proc"].inspect.split(" ")[1][0...-1]})"
|
13
|
+
when "log_requests"
|
14
|
+
if mw_args["before"] && mw_args["after"]
|
15
|
+
"\e[33mlog_requests\e[0m(before: #{mw_args["before"]["format"][0..6]}..., after: #{mw_args["after"]["format"][0..6]}...)"
|
16
|
+
elsif mw_args["before"]
|
17
|
+
"\e[33mlog_requests\e[0m(before: #{mw_args["before"]["format"][0..6]}...)"
|
18
|
+
elsif mw_args["after"]
|
19
|
+
"\e[33mlog_requests\e[0m(before: nil, after: #{mw_args["after"]["format"][0..6]}...)"
|
20
|
+
end
|
21
|
+
when "compress"
|
22
|
+
"\e[33mcompress\e[0m(#{mw_args["algorithms"].join(" ")}, #{mw_args["mime_types"]})"
|
23
|
+
when "cors"
|
24
|
+
"\e[33mcors\e[0m(#{mw_args["allow_origins"].join(" ")}, #{mw_args["allow_methods"].join(" ")})"
|
25
|
+
when "etag"
|
26
|
+
"\e[33metag\e[0m(#{mw_args["type"]}/#{mw_args["algorithm"]}, #{mw_args["handle_if_none_match"] ? "if_none_match" : ""})"
|
27
|
+
when "cache_control"
|
28
|
+
"\e[33mcache_control\e[0m(max_age: #{mw_args["max_age"]}, #{mw_args.select do |_, v|
|
29
|
+
v == true
|
30
|
+
end.keys.join(", ")})"
|
31
|
+
when "redirect"
|
32
|
+
"\e[33mredirect\e[0m(to: #{mw_args["to"]}, type: #{mw_args["type"]})"
|
33
|
+
when "static_assets"
|
34
|
+
"\e[33mstatic_assets\e[0m(path: #{mw_args["root_dir"]})"
|
35
|
+
when "auth_api_key"
|
36
|
+
"\e[33mauth_api_key\e[0m(keys: #{mw_args["valid_keys"].keys}#{mw_args["credentials_file"] ? ", credentials_file: #{mw_args["credentials_file"]}" : ""})"
|
37
|
+
when "auth_basic"
|
38
|
+
"\e[33mbasic_auth\e[0m(keys: #{mw_args["realm"]}#{mw_args["credentials_file"] ? ", credentials_file: #{mw_args["credentials_file"]}" : ""})"
|
39
|
+
when "auth_jwt"
|
40
|
+
"\e[33mjwt_auth\e[0m(#{mw_args["verifiers"].keys.join(",")})"
|
41
|
+
when "rate_limit"
|
42
|
+
key = mw_args["key"].is_a?(Hash) ? mw_args["key"]["parameter"] : mw_args["key"]
|
43
|
+
"\e[33mrate_limit\e[0m(rps: #{mw_args["requests"]}/#{mw_args["seconds"]}, key: #{key})"
|
44
|
+
when "allow_list"
|
45
|
+
"\e[33mallow_list\e[0m(patterns: #{mw_args["allowed_patterns"].join(", ")})"
|
46
|
+
when "deny_list"
|
47
|
+
"\e[33mdeny_list\e[0m(patterns: #{mw_args["denied_patterns"].join(", ")})"
|
48
|
+
when "csp"
|
49
|
+
"\e[33mcsp\e[0m(#{mw_args["policy"].map { |k, v| "#{k}: #{v.join(",")}" }.join(", ")})"
|
50
|
+
when "intrusion_protection"
|
51
|
+
[mw_args].flatten.map do |mw_args|
|
52
|
+
"\e[33mintrusion_protection\e[0m(banned_url_patterns: #{mw_args["banned_url_patterns"]&.length}, banned_header_patterns: #{mw_args["banned_header_patterns"]&.keys&.join(", ")}, #{mw_args["banned_time_seconds"]}s)"
|
53
|
+
end.join("\n")
|
54
|
+
when "request_headers"
|
55
|
+
[mw_args].flatten.map do |mw_args|
|
56
|
+
"\e[33mrequest_headers\e[0m(added: #{mw_args["additions"].keys}, removed: #{mw_args["removals"]})"
|
57
|
+
end.join("\n")
|
58
|
+
when "response_headers"
|
59
|
+
[mw_args].flatten.map do |mw_args|
|
60
|
+
"\e[33mresponse_headers\e[0m(added: #{mw_args["additions"].keys}, removed: #{mw_args["removals"]})"
|
61
|
+
end.join("\n")
|
62
|
+
when "static_response"
|
63
|
+
"\e[response_headers\e[0m(#{mw_args["code"]} body: #{mw_args["body"][0..10]})"
|
12
64
|
else
|
13
|
-
mw["
|
65
|
+
"\e[33m#{mw.first}\e[0m"
|
14
66
|
end
|
15
67
|
end
|
16
68
|
|
@@ -21,12 +73,12 @@ module Itsi
|
|
21
73
|
end.compact
|
22
74
|
filter_str = filters.any? ? filters.join(", ") : "(none)"
|
23
75
|
|
24
|
-
middlewares = stack["middleware"]
|
76
|
+
middlewares = stack["middleware"].to_a
|
25
77
|
|
26
78
|
puts "─" * 76
|
27
|
-
puts "
|
28
|
-
puts "
|
29
|
-
puts "
|
79
|
+
puts "\e[32mRoute:\e[0m \e[33m#{route_str}\e[0m"
|
80
|
+
puts "\e[32mConditions:\e[0m \e[34m#{filter_str}\e[0m"
|
81
|
+
puts "\e[32mMiddleware:\e[0m • #{format_mw(middlewares.first)}"
|
30
82
|
middlewares[1..].each do |mw|
|
31
83
|
puts " • #{format_mw(mw)}"
|
32
84
|
end
|
@@ -23,21 +23,21 @@ module Itsi
|
|
23
23
|
case v
|
24
24
|
when true, 'true', '1', 1 then true
|
25
25
|
when false, 'false', '0', 0 then false
|
26
|
-
else raise "Cannot cast #{v.inspect} to Boolean"
|
26
|
+
else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
|
27
27
|
end
|
28
28
|
},
|
29
29
|
FalseClass => ->(v){
|
30
30
|
case v
|
31
31
|
when true, 'true', '1', 1 then true
|
32
32
|
when false, 'false', '0', 0 then false
|
33
|
-
else raise "Cannot cast #{v.inspect} to Boolean"
|
33
|
+
else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
|
34
34
|
end
|
35
35
|
},
|
36
36
|
:Boolean => ->(v){
|
37
37
|
case v
|
38
38
|
when true, 'true', '1', 1 then true
|
39
39
|
when false, 'false', '0', 0 then false
|
40
|
-
else raise "Cannot cast #{v.inspect} to Boolean"
|
40
|
+
else raise ValidationError.new("Cannot cast #{v.inspect} to Boolean")
|
41
41
|
end
|
42
42
|
},
|
43
43
|
Date => ->(v){ Date.parse(v.to_s) },
|
@@ -45,17 +45,6 @@ module Itsi
|
|
45
45
|
DateTime => ->(v){ DateTime.parse(v.to_s) }
|
46
46
|
}.compare_by_identity
|
47
47
|
|
48
|
-
# Extracts the expected type and required flag from a schema definition.
|
49
|
-
def extract_schema(schema_def)
|
50
|
-
if schema_def.is_a?(Hash) && schema_def.key?(:_type)
|
51
|
-
expected_type = schema_def[:_type]
|
52
|
-
required = schema_def.fetch(:required, true)
|
53
|
-
[expected_type, required]
|
54
|
-
else
|
55
|
-
[schema_def, true]
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
48
|
# Preprocess the schema into fixed keys (as symbols) and regex keys.
|
60
49
|
# Memoizes the result based on the schema.
|
61
50
|
def processed_schema(schema)
|
@@ -63,8 +52,9 @@ module Itsi
|
|
63
52
|
@@schema_cache[schema] ||= begin
|
64
53
|
fixed = {}
|
65
54
|
regex = []
|
55
|
+
required_params = schema[:_required] || []
|
66
56
|
schema.each do |k, schema_def|
|
67
|
-
expected_type, required =
|
57
|
+
expected_type, required = schema_def, required_params.include?(k)
|
68
58
|
if k.is_a?(Regexp)
|
69
59
|
regex << [k, [expected_type, required]]
|
70
60
|
else
|
@@ -179,16 +169,22 @@ module Itsi
|
|
179
169
|
end
|
180
170
|
|
181
171
|
# Process regex keys (only string keys not already handled as fixed keys).
|
182
|
-
params.keys.
|
172
|
+
params.keys.each do |key|
|
173
|
+
if key == :_required
|
174
|
+
params.delete(key)
|
175
|
+
next
|
176
|
+
end
|
183
177
|
next if fixed_schema.has_key?(key.to_sym) || fixed_schema.has_key?(key)
|
184
|
-
regex_schema.
|
178
|
+
unless regex_schema.find do |regex, (expected_type, _required)|
|
185
179
|
if regex.match(key)
|
186
180
|
new_path = path + [key]
|
187
181
|
err = cast_value!(params, key, expected_type, new_path)
|
188
182
|
errors << err if err
|
189
|
-
|
183
|
+
true # only use the first matching regex
|
190
184
|
end
|
191
185
|
end
|
186
|
+
params.delete(key)
|
187
|
+
end
|
192
188
|
end
|
193
189
|
|
194
190
|
raise ValidationError.new(errors) unless errors.empty?
|
@@ -2,37 +2,41 @@ module Itsi
|
|
2
2
|
class Server
|
3
3
|
module TypedHandlers
|
4
4
|
module SourceParser
|
5
|
-
require
|
6
|
-
|
5
|
+
require "prism"
|
7
6
|
|
7
|
+
# Source Parser interprets endpoint handlers
|
8
|
+
# and extracts arity and schema information.
|
8
9
|
def self.extract_expr_from_source_location(proc)
|
9
|
-
|
10
|
+
source_location = proc.source_location
|
11
|
+
source_lines = IO.readlines(source_location.first)
|
10
12
|
|
11
13
|
proc_line = source_location.last - 1
|
12
14
|
first_line = source_lines[proc_line]
|
13
15
|
|
14
|
-
until first_line =~ /(?:lambda|proc|->|def|.*?do\s
|
16
|
+
until first_line =~ /(?:lambda|proc|->|def|.*?do\s*|.*?\{.*?\|)/ || proc_line.zero?
|
15
17
|
proc_line -= 1
|
16
18
|
first_line = source_lines[proc_line]
|
17
19
|
end
|
18
20
|
lines = source_lines[proc_line..]
|
19
|
-
lines[0] = lines[0][/(?:lambda|proc|->|def|.*?do\s
|
21
|
+
lines[0] = lines[0][/(?:lambda|proc|->|def|.*?do\s+|.*?\{.*?\|).*/]
|
20
22
|
src_str = lines.first << "\n"
|
21
23
|
intermediate = Prism.parse(src_str)
|
22
24
|
|
23
25
|
lines[1..-1].each do |line|
|
24
26
|
break if intermediate.success?
|
27
|
+
|
25
28
|
token_count = 0
|
26
29
|
line.split(/(?=\s|;|\)|\})/).each do |token|
|
27
30
|
src_str << token
|
28
31
|
token_count += 1
|
29
32
|
intermediate = Prism.parse(src_str)
|
30
33
|
next unless intermediate.success? && token_count > 1
|
34
|
+
|
31
35
|
break
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
|
-
raise
|
39
|
+
raise "Source Extraction Failed" unless intermediate.success?
|
36
40
|
|
37
41
|
src = intermediate.value.statements.body.first.yield_self do |s|
|
38
42
|
s.type == :call_node ? s.block : s
|
@@ -40,14 +44,13 @@ module Itsi
|
|
40
44
|
params = src.parameters
|
41
45
|
params = params.parameters if params.respond_to?(:parameters)
|
42
46
|
requireds = (params&.requireds || []).map(&:name)
|
43
|
-
optionals = params&.optionals || []
|
44
47
|
keywords = (params&.keywords || []).map do |kw|
|
45
|
-
[kw.name, kw.value.slice.gsub(/^_\./,
|
48
|
+
[kw.name, kw.value.slice.gsub(/^_\./, "$.")]
|
46
49
|
end.to_h
|
47
50
|
|
48
51
|
[requireds.length, keywords]
|
49
|
-
rescue
|
50
|
-
[
|
52
|
+
rescue StandardError
|
53
|
+
[proc.parameters.select { |p| p == :req }&.length || 0, {}]
|
51
54
|
end
|
52
55
|
end
|
53
56
|
end
|
@@ -5,10 +5,18 @@ module Itsi
|
|
5
5
|
class Server
|
6
6
|
module TypedHandlers
|
7
7
|
def self.handler_for(proc, input_schema)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
if input_schema
|
9
|
+
input_schema = proc.binding.eval(input_schema)
|
10
|
+
lambda do |req|
|
11
|
+
req.params(input_schema) do |params|
|
12
|
+
proc.call(req, params: params)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
else
|
16
|
+
lambda do |req|
|
17
|
+
req.params do |params|
|
18
|
+
proc.call(req, params)
|
19
|
+
end
|
12
20
|
end
|
13
21
|
end
|
14
22
|
end
|
@@ -17,6 +17,9 @@ require_relative "http_response"
|
|
17
17
|
require_relative "passfile"
|
18
18
|
require_relative "../shell_completions/completions"
|
19
19
|
|
20
|
+
require "securerandom"
|
21
|
+
require "fileutils"
|
22
|
+
|
20
23
|
module Itsi
|
21
24
|
class Server
|
22
25
|
extend RackInterface
|
@@ -24,21 +27,25 @@ module Itsi
|
|
24
27
|
extend RouteTester
|
25
28
|
|
26
29
|
class << self
|
27
|
-
|
28
30
|
def running?
|
29
|
-
|
31
|
+
@running && !@running.empty?
|
30
32
|
end
|
31
33
|
|
32
34
|
def start_in_background_thread(cli_params = {}, &blk)
|
33
|
-
@
|
35
|
+
@background_threads ||= []
|
36
|
+
server, background_thread = start(cli_params, background: true, &blk)
|
37
|
+
@background_threads << background_thread
|
38
|
+
server
|
34
39
|
end
|
35
40
|
|
36
41
|
def start(cli_params, background: false, &blk)
|
37
42
|
itsi_file = Itsi::Server::Config.config_file_path(cli_params[:config_file])
|
43
|
+
Itsi.log_debug "Constructing server #{cli_params}: #{itsi_file}"
|
38
44
|
server = new(cli_params, itsi_file, blk)
|
39
45
|
previous_handler = Signal.trap(:INT, :DEFAULT)
|
40
46
|
run = lambda do
|
41
|
-
@running
|
47
|
+
@running ||= []
|
48
|
+
@running << server
|
42
49
|
|
43
50
|
if cli_params[:daemonize]
|
44
51
|
Itsi.log_info("Itsi is running in the background. Writing pid to #{Itsi::Server::Config.pid_file_path}")
|
@@ -47,13 +54,15 @@ module Itsi
|
|
47
54
|
end
|
48
55
|
write_pid
|
49
56
|
|
57
|
+
Itsi.log_info "Starting Itsi..."
|
50
58
|
server.start
|
51
|
-
@running
|
59
|
+
@running.delete(server)
|
52
60
|
Signal.trap(:INT, previous_handler)
|
53
61
|
server
|
54
62
|
end
|
55
|
-
background ? Thread.new(&run) : run[]
|
56
|
-
rescue
|
63
|
+
background ? [server, Thread.new(&run)] : run[]
|
64
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
65
|
+
Itsi.log_error e.message
|
57
66
|
end
|
58
67
|
|
59
68
|
def static(cli_params)
|
@@ -61,7 +70,8 @@ module Itsi
|
|
61
70
|
end
|
62
71
|
|
63
72
|
def stop
|
64
|
-
return unless pid = get_pid
|
73
|
+
return unless (pid = get_pid)
|
74
|
+
|
65
75
|
Process.kill(:INT, pid)
|
66
76
|
i = 0
|
67
77
|
while i < 10
|
@@ -74,16 +84,18 @@ module Itsi
|
|
74
84
|
end
|
75
85
|
end
|
76
86
|
|
77
|
-
def
|
78
|
-
@running
|
79
|
-
@
|
87
|
+
def stop_background_threads
|
88
|
+
@running && @running.each(&:stop)
|
89
|
+
@background_threads&.each(&:join)
|
90
|
+
@background_threads = []
|
91
|
+
@running = []
|
80
92
|
end
|
81
93
|
|
82
94
|
def write_pid
|
83
95
|
File.write(Itsi::Server::Config.pid_file_path, Process.pid)
|
84
96
|
end
|
85
97
|
|
86
|
-
def get_pid(warn=true)
|
98
|
+
def get_pid(warn = true)
|
87
99
|
pid = File.read(Itsi::Server::Config.pid_file_path).to_i
|
88
100
|
if Process.kill(0, pid)
|
89
101
|
pid
|
@@ -97,7 +109,7 @@ module Itsi
|
|
97
109
|
end
|
98
110
|
|
99
111
|
def test
|
100
|
-
Itsi::Server::Config.test!(
|
112
|
+
Itsi::Server::Config.test!({})
|
101
113
|
end
|
102
114
|
|
103
115
|
def init
|
@@ -105,25 +117,25 @@ module Itsi
|
|
105
117
|
end
|
106
118
|
|
107
119
|
def reload
|
108
|
-
return unless pid = get_pid
|
120
|
+
return unless (pid = get_pid)
|
109
121
|
|
110
122
|
Process.kill(:HUP, pid)
|
111
123
|
end
|
112
124
|
|
113
125
|
def restart
|
114
|
-
return unless pid = get_pid
|
126
|
+
return unless (pid = get_pid)
|
115
127
|
|
116
128
|
Process.kill(:USR1, pid)
|
117
129
|
end
|
118
130
|
|
119
131
|
def passfile(options, subcmd)
|
120
132
|
filename = options[:passfile]
|
121
|
-
unless filename
|
133
|
+
unless filename || subcmd == "echo"
|
122
134
|
puts "Error: passfile not set. Use --passfile option to provide a path to a file containing hashed credentials."
|
123
135
|
puts "This file contains hashed credentials and should not be included in source control without additional protection."
|
124
136
|
exit(1)
|
125
137
|
end
|
126
|
-
algorithm = options.fetch(:algorithm,
|
138
|
+
algorithm = options.fetch(:algorithm, "sha256")
|
127
139
|
|
128
140
|
unless %w[sha256 sha512 bcrypt argon2 none].include?(algorithm)
|
129
141
|
puts "Invalid algorithm"
|
@@ -131,9 +143,9 @@ module Itsi
|
|
131
143
|
end
|
132
144
|
|
133
145
|
case subcmd
|
134
|
-
when
|
146
|
+
when "add", "echo"
|
135
147
|
Passfile.send(subcmd, filename, algorithm)
|
136
|
-
when
|
148
|
+
when "remove", "list"
|
137
149
|
Passfile.send(subcmd, filename)
|
138
150
|
else
|
139
151
|
puts "Valid subcommands are: add | remove | list"
|
@@ -141,31 +153,104 @@ module Itsi
|
|
141
153
|
end
|
142
154
|
end
|
143
155
|
|
156
|
+
def unique_path(dir, filename)
|
157
|
+
base = File.basename(filename, ".*")
|
158
|
+
ext = File.extname(filename)
|
159
|
+
candidate = File.join(dir, filename)
|
160
|
+
return candidate unless File.exist?(candidate)
|
161
|
+
|
162
|
+
i = 1
|
163
|
+
loop do
|
164
|
+
new_name = "#{base}_#{i}#{ext}"
|
165
|
+
candidate = File.join(dir, new_name)
|
166
|
+
return candidate unless File.exist?(candidate)
|
167
|
+
|
168
|
+
i += 1
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def save_or_print(filename, content, options)
|
173
|
+
if options[:save_dir]
|
174
|
+
FileUtils.mkdir_p(options[:save_dir])
|
175
|
+
path = unique_path(options[:save_dir], filename)
|
176
|
+
File.write(path, content)
|
177
|
+
puts "Written to #{path}"
|
178
|
+
else
|
179
|
+
puts content
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def secret(options)
|
184
|
+
require "openssl"
|
185
|
+
require "base64"
|
186
|
+
|
187
|
+
puts "Enter algorithm (one of: HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384):"
|
188
|
+
alg = $stdin.gets.chomp.upcase
|
189
|
+
|
190
|
+
case alg
|
191
|
+
when /^HS(\d+)$/
|
192
|
+
bits = ::Regexp.last_match(1).to_i
|
193
|
+
bytes = bits / 8
|
194
|
+
key = SecureRandom.random_bytes(bytes)
|
195
|
+
pem = Base64.strict_encode64(key)
|
196
|
+
content = "=== HMAC #{bits}-bit Secret (base64) ===\n#{pem}\n"
|
197
|
+
save_or_print("hmac_#{bits}_secret.txt", content, options)
|
198
|
+
|
199
|
+
when /^RS/, /^PS/
|
200
|
+
rsa = OpenSSL::PKey::RSA.new(2048)
|
201
|
+
priv = rsa.to_pem
|
202
|
+
pub = rsa.public_key.to_pem
|
203
|
+
save_or_print("rsa_private.pem", "=== RSA Private Key ===\n#{priv}", options)
|
204
|
+
save_or_print("rsa_public.pem", "=== RSA Public Key ===\n#{pub}", options)
|
205
|
+
|
206
|
+
when "ES256", "ES384"
|
207
|
+
curve = (alg == "ES256" ? "prime256v1" : "secp384r1")
|
208
|
+
ec = OpenSSL::PKey::EC.new(curve)
|
209
|
+
ec.generate_key
|
210
|
+
priv = ec.to_pem
|
211
|
+
pub_ec = ec.dup
|
212
|
+
pub_ec.private_key = nil
|
213
|
+
pub = pub_ec.to_pem
|
214
|
+
save_or_print("ecdsa_private.pem", "=== ECDSA Private Key ===\n#{priv}", options)
|
215
|
+
save_or_print("ecdsa_public.pem", "=== ECDSA Public Key ===\n#{pub}", options)
|
216
|
+
|
217
|
+
else
|
218
|
+
warn "Unsupported algorithm: #{alg}"
|
219
|
+
exit 1
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
144
223
|
def add_worker
|
145
|
-
return unless pid = get_pid
|
224
|
+
return unless (pid = get_pid)
|
146
225
|
|
147
226
|
Process.kill(:TTIN, pid)
|
148
227
|
end
|
149
228
|
|
150
229
|
def remove_worker
|
151
|
-
return unless pid = get_pid
|
230
|
+
return unless (pid = get_pid)
|
152
231
|
|
153
232
|
Process.kill(:TTOU, pid)
|
154
233
|
end
|
155
234
|
|
156
235
|
def status
|
157
|
-
return unless pid = get_pid
|
236
|
+
return unless (pid = get_pid)
|
237
|
+
|
158
238
|
Itsi.log_info("Itsi running on #{pid}")
|
159
239
|
Process.kill(:USR2, pid)
|
160
240
|
end
|
161
241
|
|
162
242
|
def load_route_middleware_stack(cli_params)
|
163
|
-
Config.build_config(cli_params,
|
164
|
-
|
165
|
-
|
243
|
+
middleware, errors = Config.build_config(cli_params,
|
244
|
+
Itsi::Server::Config.config_file_path(cli_params[:config_file_path]))
|
245
|
+
if errors.any?
|
246
|
+
puts errors
|
247
|
+
[]
|
248
|
+
else
|
249
|
+
middleware["middleware_loader"][]
|
250
|
+
end
|
166
251
|
end
|
167
252
|
|
168
|
-
def test_route(cli_params
|
253
|
+
def test_route(cli_params, route_str)
|
169
254
|
matched_route = load_route_middleware_stack(cli_params).find do |route|
|
170
255
|
route["route"] =~ route_str
|
171
256
|
end
|
@@ -187,7 +272,6 @@ module Itsi
|
|
187
272
|
end
|
188
273
|
|
189
274
|
alias serve start
|
190
|
-
|
191
275
|
end
|
192
276
|
end
|
193
277
|
end
|