itsi 0.1.11 → 0.1.12
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 +1535 -45
- data/{sandbox/itsi_itsi_file/Itsi.rb → Itsi.rb} +19 -13
- data/Rakefile +8 -7
- data/crates/itsi_error/src/lib.rs +9 -0
- data/crates/itsi_rb_helpers/Cargo.toml +1 -0
- data/crates/itsi_rb_helpers/src/heap_value.rs +18 -0
- data/crates/itsi_rb_helpers/src/lib.rs +34 -7
- data/crates/itsi_server/Cargo.toml +69 -30
- data/crates/itsi_server/src/lib.rs +79 -147
- data/crates/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
- data/crates/itsi_server/src/{body_proxy/itsi_body_proxy.rs → ruby_types/itsi_body_proxy/mod.rs} +22 -3
- data/crates/itsi_server/src/ruby_types/itsi_grpc_request.rs +147 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_response.rs +19 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_stream/mod.rs +216 -0
- data/{gems/server/ext/itsi_server/src/request/itsi_request.rs → crates/itsi_server/src/ruby_types/itsi_http_request.rs} +101 -117
- data/crates/itsi_server/src/{response/itsi_response.rs → ruby_types/itsi_http_response.rs} +72 -41
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +355 -0
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +82 -0
- data/crates/itsi_server/src/ruby_types/mod.rs +55 -0
- data/crates/itsi_server/src/server/bind.rs +13 -5
- data/crates/itsi_server/src/server/byte_frame.rs +32 -0
- data/crates/itsi_server/src/server/cache_store.rs +74 -0
- data/crates/itsi_server/src/server/itsi_service.rs +172 -0
- data/crates/itsi_server/src/server/lifecycle_event.rs +3 -0
- data/crates/itsi_server/src/server/listener.rs +102 -2
- data/crates/itsi_server/src/server/middleware_stack/middleware.rs +153 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +47 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +58 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +321 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +139 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +300 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +287 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +48 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +127 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +191 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/grpc_service.rs +72 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +85 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +195 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +216 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +124 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +43 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +34 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +93 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +162 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +158 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
- data/crates/itsi_server/src/server/middleware_stack/mod.rs +315 -0
- data/crates/itsi_server/src/server/mod.rs +8 -1
- data/crates/itsi_server/src/server/process_worker.rs +38 -12
- data/crates/itsi_server/src/server/rate_limiter.rs +565 -0
- data/crates/itsi_server/src/server/request_job.rs +11 -0
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +119 -42
- data/crates/itsi_server/src/server/serve_strategy/mod.rs +9 -6
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +256 -111
- data/crates/itsi_server/src/server/signal.rs +19 -0
- data/crates/itsi_server/src/server/static_file_server.rs +984 -0
- data/crates/itsi_server/src/server/thread_worker.rs +139 -94
- data/crates/itsi_server/src/server/types.rs +43 -0
- data/crates/itsi_server/test.md +14 -0
- data/crates/itsi_tracing/Cargo.toml +1 -0
- data/crates/itsi_tracing/src/lib.rs +216 -45
- data/docs/.gitignore +7 -0
- data/docs/.gitpod.yml +15 -0
- data/docs/Itsi.rb +17 -0
- data/docs/content/_index.md +17 -0
- data/docs/content/about.md +6 -0
- data/docs/content/docs/_index.md +18 -0
- data/docs/content/docs/first-page.md +9 -0
- data/docs/content/docs/folder/_index.md +10 -0
- data/docs/content/docs/folder/leaf.md +7 -0
- data/docs/go.mod +5 -0
- data/docs/go.sum +2 -0
- data/docs/hugo.yaml +77 -0
- data/examples/static_assets_example.rb +83 -0
- data/gems/_index.md +18 -0
- data/gems/scheduler/CODE_OF_CONDUCT.md +7 -0
- data/gems/scheduler/Cargo.lock +75 -14
- data/gems/scheduler/README.md +5 -0
- data/gems/scheduler/_index.md +7 -0
- data/gems/scheduler/itsi-scheduler.gemspec +4 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/scheduler/lib/itsi/scheduler.rb +2 -2
- data/gems/scheduler/test/test_file_io.rb +0 -1
- data/gems/scheduler/test/test_itsi_scheduler.rb +1 -1
- data/gems/server/CHANGELOG.md +5 -0
- data/gems/server/CODE_OF_CONDUCT.md +7 -0
- data/gems/server/Cargo.lock +1536 -45
- data/gems/server/README.md +4 -0
- data/gems/server/_index.md +6 -0
- data/gems/server/exe/itsi +33 -74
- data/gems/server/itsi-server.gemspec +3 -2
- data/gems/server/lib/itsi/{request.rb → http_request.rb} +29 -5
- data/gems/server/lib/itsi/http_response.rb +39 -0
- data/gems/server/lib/itsi/server/Itsi.rb +11 -19
- data/gems/server/lib/itsi/server/config/dsl.rb +506 -0
- data/gems/server/lib/itsi/server/config.rb +103 -8
- data/gems/server/lib/itsi/server/default_app/default_app.rb +38 -0
- data/gems/server/lib/itsi/server/grpc_interface.rb +213 -0
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +8 -17
- data/gems/server/lib/itsi/server/rack_interface.rb +23 -4
- data/gems/server/lib/itsi/server/scheduler_interface.rb +1 -1
- data/gems/server/lib/itsi/server/scheduler_mode.rb +4 -0
- data/gems/server/lib/itsi/server/signal_trap.rb +7 -1
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +74 -63
- data/gems/server/lib/itsi/standard_headers.rb +86 -0
- data/gems/server/test/helpers/test_helper.rb +12 -12
- data/gems/server/test/test_itsi_server.rb +2 -2
- data/lib/itsi/version.rb +1 -1
- data/sandbox/itsi_file/Gemfile +11 -0
- data/sandbox/itsi_file/Gemfile.lock +69 -0
- data/sandbox/itsi_file/Itsi.rb +276 -0
- data/sandbox/itsi_file/error.html +2 -0
- data/sandbox/itsi_file/organisations_controller.rb +20 -0
- data/sandbox/itsi_file/public/assets/image.png +0 -0
- data/sandbox/itsi_file/public/assets/index.html +1 -0
- data/sandbox/itsi_sandbox_hanami/Gemfile.lock +2 -2
- data/sandbox/itsi_sandbox_rack/Gemfile.lock +2 -2
- data/sandbox/itsi_sandbox_rack/config.ru +2 -15
- data/sandbox/itsi_sandbox_rails/.dockerignore +2 -5
- data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +1 -1
- data/sandbox/itsi_sandbox_rails/.gitignore +2 -1
- data/sandbox/itsi_sandbox_rails/Dockerfile +6 -9
- data/sandbox/itsi_sandbox_rails/Gemfile +16 -22
- data/sandbox/itsi_sandbox_rails/Gemfile.lock +100 -225
- data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +4 -0
- data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +11 -6
- data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +4 -0
- data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +4 -0
- data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +7 -8
- data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -3
- data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +2 -7
- data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +3 -4
- data/sandbox/itsi_sandbox_rails/bin/setup +8 -5
- data/sandbox/itsi_sandbox_rails/config/application.rb +1 -35
- data/sandbox/itsi_sandbox_rails/config/cable.yml +3 -10
- data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -1
- data/sandbox/itsi_sandbox_rails/config/database.yml +9 -19
- data/sandbox/itsi_sandbox_rails/config/environment.rb +1 -1
- data/sandbox/itsi_sandbox_rails/config/environments/development.rb +21 -12
- data/sandbox/itsi_sandbox_rails/config/environments/production.rb +49 -34
- data/sandbox/itsi_sandbox_rails/config/environments/test.rb +19 -5
- data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +5 -0
- data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +1 -1
- data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +13 -0
- data/sandbox/itsi_sandbox_rails/config/puma.rb +2 -9
- data/sandbox/itsi_sandbox_rails/config.ru +0 -1
- data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +1 -1
- data/sandbox/itsi_sandbox_rails/db/schema.rb +2 -2
- data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
- data/sandbox/itsi_sandbox_rails/public/404.html +66 -113
- data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +65 -113
- data/sandbox/itsi_sandbox_rails/public/422.html +66 -113
- data/sandbox/itsi_sandbox_rails/public/500.html +65 -113
- data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
- data/sandbox/itsi_sandbox_rails/public/icon.svg +2 -2
- data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +13 -0
- data/sandbox/itsi_sandbox_roda/Gemfile.lock +3 -10
- data/tasks.txt +72 -35
- metadata +89 -139
- data/crates/itsi_server/src/body_proxy/mod.rs +0 -2
- data/crates/itsi_server/src/request/itsi_request.rs +0 -298
- data/crates/itsi_server/src/request/mod.rs +0 -1
- data/crates/itsi_server/src/response/mod.rs +0 -1
- data/crates/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/scheduler/ext/itsi_error/Cargo.lock +0 -368
- data/gems/scheduler/ext/itsi_error/Cargo.toml +0 -11
- data/gems/scheduler/ext/itsi_error/src/from.rs +0 -68
- data/gems/scheduler/ext/itsi_error/src/lib.rs +0 -24
- data/gems/scheduler/ext/itsi_instrument_entry/Cargo.toml +0 -15
- data/gems/scheduler/ext/itsi_instrument_entry/src/lib.rs +0 -31
- data/gems/scheduler/ext/itsi_rb_helpers/Cargo.lock +0 -355
- data/gems/scheduler/ext/itsi_rb_helpers/Cargo.toml +0 -10
- data/gems/scheduler/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
- data/gems/scheduler/ext/itsi_rb_helpers/src/lib.rs +0 -201
- data/gems/scheduler/ext/itsi_scheduler/Cargo.toml +0 -24
- data/gems/scheduler/ext/itsi_scheduler/extconf.rb +0 -6
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
- data/gems/scheduler/ext/itsi_scheduler/src/lib.rs +0 -38
- data/gems/scheduler/ext/itsi_server/Cargo.lock +0 -2956
- data/gems/scheduler/ext/itsi_server/Cargo.toml +0 -50
- data/gems/scheduler/ext/itsi_server/extconf.rb +0 -6
- data/gems/scheduler/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
- data/gems/scheduler/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
- data/gems/scheduler/ext/itsi_server/src/body_proxy/mod.rs +0 -2
- data/gems/scheduler/ext/itsi_server/src/env.rs +0 -43
- data/gems/scheduler/ext/itsi_server/src/lib.rs +0 -180
- data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +0 -298
- data/gems/scheduler/ext/itsi_server/src/request/mod.rs +0 -1
- data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +0 -357
- data/gems/scheduler/ext/itsi_server/src/response/mod.rs +0 -1
- data/gems/scheduler/ext/itsi_server/src/server/bind.rs +0 -174
- data/gems/scheduler/ext/itsi_server/src/server/bind_protocol.rs +0 -37
- data/gems/scheduler/ext/itsi_server/src/server/io_stream.rs +0 -104
- data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/scheduler/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
- data/gems/scheduler/ext/itsi_server/src/server/listener.rs +0 -318
- data/gems/scheduler/ext/itsi_server/src/server/mod.rs +0 -11
- data/gems/scheduler/ext/itsi_server/src/server/process_worker.rs +0 -203
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
- data/gems/scheduler/ext/itsi_server/src/server/signal.rs +0 -74
- data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +0 -399
- data/gems/scheduler/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
- data/gems/scheduler/ext/itsi_server/src/server/tls.rs +0 -265
- data/gems/scheduler/ext/itsi_tracing/Cargo.lock +0 -274
- data/gems/scheduler/ext/itsi_tracing/Cargo.toml +0 -16
- data/gems/scheduler/ext/itsi_tracing/src/lib.rs +0 -58
- data/gems/server/ext/itsi_error/Cargo.lock +0 -368
- data/gems/server/ext/itsi_error/Cargo.toml +0 -11
- data/gems/server/ext/itsi_error/src/from.rs +0 -68
- data/gems/server/ext/itsi_error/src/lib.rs +0 -24
- data/gems/server/ext/itsi_instrument_entry/Cargo.toml +0 -15
- data/gems/server/ext/itsi_instrument_entry/src/lib.rs +0 -31
- data/gems/server/ext/itsi_rb_helpers/Cargo.lock +0 -355
- data/gems/server/ext/itsi_rb_helpers/Cargo.toml +0 -10
- data/gems/server/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
- data/gems/server/ext/itsi_rb_helpers/src/lib.rs +0 -201
- data/gems/server/ext/itsi_scheduler/Cargo.toml +0 -24
- data/gems/server/ext/itsi_scheduler/extconf.rb +0 -6
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
- data/gems/server/ext/itsi_scheduler/src/lib.rs +0 -38
- data/gems/server/ext/itsi_server/Cargo.lock +0 -2956
- data/gems/server/ext/itsi_server/Cargo.toml +0 -50
- data/gems/server/ext/itsi_server/extconf.rb +0 -6
- data/gems/server/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
- data/gems/server/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
- data/gems/server/ext/itsi_server/src/body_proxy/mod.rs +0 -2
- data/gems/server/ext/itsi_server/src/env.rs +0 -43
- data/gems/server/ext/itsi_server/src/lib.rs +0 -180
- data/gems/server/ext/itsi_server/src/request/mod.rs +0 -1
- data/gems/server/ext/itsi_server/src/response/itsi_response.rs +0 -357
- data/gems/server/ext/itsi_server/src/response/mod.rs +0 -1
- data/gems/server/ext/itsi_server/src/server/bind.rs +0 -174
- data/gems/server/ext/itsi_server/src/server/bind_protocol.rs +0 -37
- data/gems/server/ext/itsi_server/src/server/io_stream.rs +0 -104
- data/gems/server/ext/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/server/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
- data/gems/server/ext/itsi_server/src/server/listener.rs +0 -318
- data/gems/server/ext/itsi_server/src/server/mod.rs +0 -11
- data/gems/server/ext/itsi_server/src/server/process_worker.rs +0 -203
- data/gems/server/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
- data/gems/server/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
- data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
- data/gems/server/ext/itsi_server/src/server/signal.rs +0 -74
- data/gems/server/ext/itsi_server/src/server/thread_worker.rs +0 -399
- data/gems/server/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
- data/gems/server/ext/itsi_server/src/server/tls.rs +0 -265
- data/gems/server/ext/itsi_tracing/Cargo.lock +0 -274
- data/gems/server/ext/itsi_tracing/Cargo.toml +0 -16
- data/gems/server/ext/itsi_tracing/src/lib.rs +0 -58
- data/gems/server/lib/itsi/server/options_dsl.rb +0 -401
- data/gems/server/lib/itsi/stream_io.rb +0 -38
- data/location_dsl.rb +0 -381
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +0 -14
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +0 -51
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +0 -47
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +0 -109
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/secrets +0 -17
- data/sandbox/itsi_sandbox_rails/bin/dev +0 -2
- data/sandbox/itsi_sandbox_rails/bin/jobs +0 -6
- data/sandbox/itsi_sandbox_rails/bin/kamal +0 -27
- data/sandbox/itsi_sandbox_rails/bin/thrust +0 -5
- data/sandbox/itsi_sandbox_rails/config/cache.yml +0 -16
- data/sandbox/itsi_sandbox_rails/config/deploy.yml +0 -116
- data/sandbox/itsi_sandbox_rails/config/queue.yml +0 -18
- data/sandbox/itsi_sandbox_rails/config/recurring.yml +0 -10
- data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +0 -11
- data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +0 -14
- data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +0 -129
- data/sandbox/itsi_sandbox_rails/public/400.html +0 -114
- data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +0 -9
- data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +0 -7
- /data/{sandbox/itsi_sandbox_rails/script/.keep → crates/_index.md} +0 -0
- /data/gems/server/lib/itsi/{index.html → server/default_app/index.html} +0 -0
@@ -0,0 +1,506 @@
|
|
1
|
+
module Itsi
|
2
|
+
class Server
|
3
|
+
module Config
|
4
|
+
class DSL
|
5
|
+
attr_reader :parent, :children, :middleware, :controller_class, :routes, :methods, :protocols,
|
6
|
+
:hosts, :ports, :extensions, :content_types, :accepts, :options
|
7
|
+
|
8
|
+
def self.evaluate(config = Itsi::Server::Config.config_file_path)
|
9
|
+
new do
|
10
|
+
if config.is_a?(Proc)
|
11
|
+
instance_exec(&config)
|
12
|
+
else
|
13
|
+
code = IO.read(config)
|
14
|
+
instance_eval(code, config.to_s, 1)
|
15
|
+
end
|
16
|
+
end.options
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(
|
20
|
+
parent = nil,
|
21
|
+
routes: [],
|
22
|
+
methods: [],
|
23
|
+
protocols: [],
|
24
|
+
hosts: [],
|
25
|
+
ports: [],
|
26
|
+
extensions: [],
|
27
|
+
content_types: [],
|
28
|
+
accepts: [],
|
29
|
+
controller: self,
|
30
|
+
&block
|
31
|
+
)
|
32
|
+
@parent = parent
|
33
|
+
@children = []
|
34
|
+
@middleware = {}
|
35
|
+
@controller_class = nil
|
36
|
+
|
37
|
+
@controller = controller
|
38
|
+
# We'll store our array of route specs (strings or a single Regexp).
|
39
|
+
@routes = Array(routes).flatten
|
40
|
+
@methods = methods.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
41
|
+
@protocols = protocols.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
42
|
+
@hosts = hosts.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
43
|
+
@ports = ports.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
44
|
+
@extensions = extensions.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
45
|
+
@content_types = content_types.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
46
|
+
@accepts = accepts.map { |s| s.is_a?(Regexp) ? s : s.to_s }
|
47
|
+
|
48
|
+
@options = {
|
49
|
+
middleware_loaders: [],
|
50
|
+
middleware_loader: lambda do
|
51
|
+
@options[:middleware_loaders].each(&:call)
|
52
|
+
flatten_routes
|
53
|
+
end
|
54
|
+
}
|
55
|
+
|
56
|
+
instance_exec(&block)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
def workers(workers)
|
61
|
+
raise "Workers must be set at the root" unless @parent.nil?
|
62
|
+
|
63
|
+
@options[:workers] = [workers.to_i, 1].max
|
64
|
+
end
|
65
|
+
|
66
|
+
def threads(threads)
|
67
|
+
raise "Threads must be set at the root" unless @parent.nil?
|
68
|
+
|
69
|
+
@options[:threads] = [threads.to_i, 1].max
|
70
|
+
end
|
71
|
+
|
72
|
+
def oob_gc_responses_threshold(threshold)
|
73
|
+
raise "OOB GC responses threshold must be set at the root" unless @parent.nil?
|
74
|
+
|
75
|
+
@options[:oob_gc_responses_threshold] = threshold.to_i
|
76
|
+
end
|
77
|
+
|
78
|
+
def log_level(level)
|
79
|
+
raise "Log level must be set at the root" unless @parent.nil?
|
80
|
+
|
81
|
+
@options[:log_level] = level.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
def log_format(format)
|
85
|
+
raise "Log format must be set at the root" unless @parent.nil?
|
86
|
+
|
87
|
+
case format.to_s
|
88
|
+
when "auto" then nil
|
89
|
+
when "ansi" then ENV["ITSI_LOG_ANSI"] = "true"
|
90
|
+
when "json", "plain" then ENV["ITSI_LOG_PLAIN"] = "true"
|
91
|
+
else raise "Invalid log format '#{format}'"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def get(route, app_proc = nil, &blk)
|
96
|
+
endpoint(route, :get, app_proc, &blk)
|
97
|
+
end
|
98
|
+
|
99
|
+
def post(route, app_proc = nil, &blk)
|
100
|
+
endpoint(route, :post, app_proc, &blk)
|
101
|
+
end
|
102
|
+
|
103
|
+
def put(route, app_proc = nil, &blk)
|
104
|
+
endpoint(route, :put, app_proc, &blk)
|
105
|
+
end
|
106
|
+
|
107
|
+
def delete(route, app_proc = nil, &blk)
|
108
|
+
endpoint(route, :delete, app_proc, &blk)
|
109
|
+
end
|
110
|
+
|
111
|
+
def patch(route, app_proc = nil, &blk)
|
112
|
+
endpoint(route, :patch, app_proc, &blk)
|
113
|
+
end
|
114
|
+
|
115
|
+
def endpoint(route, method, app_proc = nil, &blk)
|
116
|
+
raise "You can't use both a block and an explicit handler in the same endpoint" if blk && app_proc
|
117
|
+
raise "You must provide either a block or an explicit handler for the endpoint" if app_proc.nil? && blk.nil?
|
118
|
+
|
119
|
+
app_proc = @controller.method(app_proc).to_proc if app_proc.is_a?(Symbol)
|
120
|
+
|
121
|
+
app_proc ||= blk
|
122
|
+
|
123
|
+
location(route, methods: [method]) do
|
124
|
+
@middleware[:app] = { app_proc: app_proc }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def grpc(handler, **)
|
129
|
+
if @middleware[:app] && @middleware[:app][:request_type].to_s != "grpc"
|
130
|
+
raise "App has already been set. You can use only one of `run` and `rackup_file` or `grpc` per location"
|
131
|
+
end
|
132
|
+
|
133
|
+
@middleware[:app] ||= {
|
134
|
+
request_type: "grpc",
|
135
|
+
impls: []
|
136
|
+
}
|
137
|
+
@middleware[:app][:impls] << handler
|
138
|
+
@middleware[:app][:app_proc] = Itsi::Server::GrpcInterface.for(@middleware[:app][:impls])
|
139
|
+
end
|
140
|
+
|
141
|
+
def run(app, sendfile: true)
|
142
|
+
if @options[:app_loader]
|
143
|
+
raise "App has already been set. You can use only one of `run` and `rackup_file` per location"
|
144
|
+
end
|
145
|
+
|
146
|
+
if @parent.nil?
|
147
|
+
@options[:app_loader] = -> { { "app_proc" => Itsi::Server::RackInterface.for(app) } }
|
148
|
+
else
|
149
|
+
@middleware[:app] = { app_proc: Itsi::Server::RackInterface.for(app), sendfile: sendfile }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def rackup_file(rackup_file)
|
154
|
+
if @options[:app_loader]
|
155
|
+
raise "App has already been set. You can use only one of `run` and `rackup_file` per location"
|
156
|
+
end
|
157
|
+
|
158
|
+
raise "Rackup file #{rackup_file} doesn't exist" unless File.exist?(rackup_file)
|
159
|
+
|
160
|
+
if @parent.nil?
|
161
|
+
@options[:app_loader] = -> { { "app_proc" => Itsi::Server::RackInterface.for(rackup_file) } }
|
162
|
+
else
|
163
|
+
@middleware[:app] = { app_proc: Itsi::Server::RackInterface.for(rackup_file) }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def include(path)
|
168
|
+
code = IO.read("#{path}.rb")
|
169
|
+
instance_eval(code, "#{path}.rb", 1)
|
170
|
+
end
|
171
|
+
|
172
|
+
def bind(bind_str)
|
173
|
+
raise "Bind must be set at the root" unless @parent.nil?
|
174
|
+
|
175
|
+
@options[:binds] ||= []
|
176
|
+
@options[:binds] << bind_str.to_s
|
177
|
+
end
|
178
|
+
|
179
|
+
def after_fork(&block)
|
180
|
+
raise "After fork must be set at the root" unless @parent.nil?
|
181
|
+
|
182
|
+
@options[:hooks] ||= {}
|
183
|
+
@options[:hooks][:after_fork] = block
|
184
|
+
end
|
185
|
+
|
186
|
+
def before_fork(&block)
|
187
|
+
raise "Before fork must be set at the root" unless @parent.nil?
|
188
|
+
|
189
|
+
@options[:hooks] ||= {}
|
190
|
+
@options[:hooks][:before_fork] = block
|
191
|
+
end
|
192
|
+
|
193
|
+
def after_memory_threshold_reached(&block)
|
194
|
+
raise "Before fork must be set at the root" unless @parent.nil?
|
195
|
+
|
196
|
+
@options[:hooks] ||= {}
|
197
|
+
@options[:hooks][:after_memory_threshold_reached] = block
|
198
|
+
end
|
199
|
+
|
200
|
+
def worker_memory_limit(memory_limit)
|
201
|
+
raise "Worker memory limit must be set at the root" unless @parent.nil?
|
202
|
+
|
203
|
+
@options[:worker_memory_limit] = memory_limit
|
204
|
+
end
|
205
|
+
|
206
|
+
def multithreaded_reactor(multithreaded)
|
207
|
+
raise "Multithreaded reactor must be set at the root" unless @parent.nil?
|
208
|
+
|
209
|
+
@options[:multithreaded_reactor] = !!multithreaded
|
210
|
+
end
|
211
|
+
|
212
|
+
def watch(path, commands)
|
213
|
+
raise "Watch be set at the root" unless @parent.nil?
|
214
|
+
|
215
|
+
@options[:notify_watchers] ||= []
|
216
|
+
@options[:notify_watchers] << [path, commands]
|
217
|
+
end
|
218
|
+
|
219
|
+
def fiber_scheduler(klass_name = true)
|
220
|
+
raise "Fiber scheduler must be set at the root" unless @parent.nil?
|
221
|
+
|
222
|
+
klass_name = "Itsi::Scheduler" if klass_name == true
|
223
|
+
@options[:scheduler_class] = klass_name if klass_name
|
224
|
+
end
|
225
|
+
|
226
|
+
def preload(preload)
|
227
|
+
raise "Preload must be set at the root" unless @parent.nil?
|
228
|
+
|
229
|
+
@options[:preload] = preload
|
230
|
+
end
|
231
|
+
|
232
|
+
def shutdown_timeout(shutdown_timeout)
|
233
|
+
raise "Shutdown timeout must be set at the root" unless @parent.nil?
|
234
|
+
|
235
|
+
@options[:shutdown_timeout] = shutdown_timeout.to_f
|
236
|
+
end
|
237
|
+
|
238
|
+
def script_name(script_name)
|
239
|
+
raise "Script name must be set at the root" unless @parent.nil?
|
240
|
+
|
241
|
+
@options[:script_name] = script_name.to_s
|
242
|
+
end
|
243
|
+
|
244
|
+
def stream_body(stream_body)
|
245
|
+
raise "Stream body must be set at the root" unless @parent.nil?
|
246
|
+
|
247
|
+
@options[:stream_body] = !!stream_body
|
248
|
+
end
|
249
|
+
|
250
|
+
def location(*routes, methods: [], protocols: [], hosts: [], ports: [], extensions: [], content_types: [],
|
251
|
+
accepts: [], &block)
|
252
|
+
build_child = lambda {
|
253
|
+
@children << DSL.new(
|
254
|
+
self,
|
255
|
+
routes: routes,
|
256
|
+
methods: Array(methods) | self.methods,
|
257
|
+
protocols: Array(protocols) | self.protocols,
|
258
|
+
hosts: Array(hosts) | self.hosts,
|
259
|
+
ports: Array(ports) | self.ports,
|
260
|
+
extensions: Array(extensions) | self.extensions,
|
261
|
+
content_types: Array(content_types) | self.content_types,
|
262
|
+
accepts: Array(accepts) | self.accepts,
|
263
|
+
controller: @controller,
|
264
|
+
&block
|
265
|
+
)
|
266
|
+
}
|
267
|
+
if @parent.nil?
|
268
|
+
@options[:middleware_loaders] << build_child
|
269
|
+
else
|
270
|
+
build_child[]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def log_requests(**args)
|
275
|
+
@middleware[:log_requests] = args
|
276
|
+
end
|
277
|
+
|
278
|
+
def allow_list(**args)
|
279
|
+
args[:allowed_patterns] = Array(args[:allowed_patterns]).map do |pattern|
|
280
|
+
if pattern.is_a?(Regexp)
|
281
|
+
pattern.source
|
282
|
+
else
|
283
|
+
pattern
|
284
|
+
end
|
285
|
+
end
|
286
|
+
@middleware[:allow_list] = args
|
287
|
+
end
|
288
|
+
|
289
|
+
def deny_list(**args)
|
290
|
+
args[:denied_patterns] = Array(args[:denied_patterns]).map do |pattern|
|
291
|
+
if pattern.is_a?(Regexp)
|
292
|
+
pattern.source
|
293
|
+
else
|
294
|
+
pattern
|
295
|
+
end
|
296
|
+
end
|
297
|
+
@middleware[:deny_list] = args
|
298
|
+
end
|
299
|
+
|
300
|
+
def controller(controller)
|
301
|
+
raise "`controller` must be set inside a location block" if @parent.nil?
|
302
|
+
|
303
|
+
@controller = controller
|
304
|
+
end
|
305
|
+
|
306
|
+
def auth_basic(**args)
|
307
|
+
raise "`auth_basic` must be set inside a location block" if @parent.nil?
|
308
|
+
|
309
|
+
@middleware[:auth_basic] = args
|
310
|
+
end
|
311
|
+
|
312
|
+
def redirect(**args)
|
313
|
+
raise "`redirect` must be set inside a location block" if @parent.nil?
|
314
|
+
|
315
|
+
@middleware[:redirect] = args
|
316
|
+
end
|
317
|
+
|
318
|
+
def proxy(**args)
|
319
|
+
raise "`proxy` must be set inside a location block" if @parent.nil?
|
320
|
+
|
321
|
+
@middleware[:proxy] = args
|
322
|
+
end
|
323
|
+
|
324
|
+
def auth_jwt(**args)
|
325
|
+
raise "`auth_jwt` must be set inside a location block" if @parent.nil?
|
326
|
+
|
327
|
+
@middleware[:auth_jwt] = args
|
328
|
+
end
|
329
|
+
|
330
|
+
def auth_api_key(**args)
|
331
|
+
raise "`auth_api_key` must be set inside a location block" if @parent.nil?
|
332
|
+
|
333
|
+
@middleware[:auth_api_key] = args
|
334
|
+
end
|
335
|
+
|
336
|
+
def compress(**args)
|
337
|
+
raise "`compress` must be set inside a location block" if @parent.nil?
|
338
|
+
|
339
|
+
@middleware[:compression] = args
|
340
|
+
end
|
341
|
+
|
342
|
+
def request_headers(**args)
|
343
|
+
raise "`request_headers` must be set inside a location block" if @parent.nil?
|
344
|
+
|
345
|
+
@middleware[:request_headers] = args
|
346
|
+
end
|
347
|
+
|
348
|
+
def response_headers(**args)
|
349
|
+
raise "`response_headers` must be set inside a location block" if @parent.nil?
|
350
|
+
|
351
|
+
@middleware[:response_headers] = args
|
352
|
+
end
|
353
|
+
|
354
|
+
def rate_limit(**args)
|
355
|
+
raise "`rate_limit` must be set inside a location block" if @parent.nil?
|
356
|
+
|
357
|
+
@middleware[:rate_limit] = args
|
358
|
+
end
|
359
|
+
|
360
|
+
def cache_control(**args)
|
361
|
+
raise "`cache_control` must be set inside a location block" if @parent.nil?
|
362
|
+
|
363
|
+
@middleware[:cache_control] = args
|
364
|
+
end
|
365
|
+
|
366
|
+
def etag(**args)
|
367
|
+
raise "`etag` must be set inside a location block" if @parent.nil?
|
368
|
+
|
369
|
+
@middleware[:etag] = args
|
370
|
+
end
|
371
|
+
|
372
|
+
def intrusion_protection(**args)
|
373
|
+
raise "`intrusion_protection` must be set inside a location block" if @parent.nil?
|
374
|
+
|
375
|
+
args[:banned_url_patterns] = Array(args[:banned_url_patterns]).map do |pattern|
|
376
|
+
if pattern.is_a?(Regexp)
|
377
|
+
pattern.source
|
378
|
+
else
|
379
|
+
pattern
|
380
|
+
end
|
381
|
+
end
|
382
|
+
@middleware[:intrusion_protection] = args
|
383
|
+
end
|
384
|
+
|
385
|
+
def cors(**args)
|
386
|
+
raise "`cors` must be set inside a location block" if @parent.nil?
|
387
|
+
|
388
|
+
@middleware[:cors] = args
|
389
|
+
end
|
390
|
+
|
391
|
+
def static_assets(**args)
|
392
|
+
raise "`static_assets` must be set inside a location block" if @parent.nil?
|
393
|
+
|
394
|
+
root_dir = args[:root_dir] || "."
|
395
|
+
|
396
|
+
if !File.exist?(root_dir)
|
397
|
+
warn "Warning: static_assets root_dir '#{root_dir}' does not exist!"
|
398
|
+
elsif !File.directory?(root_dir)
|
399
|
+
warn "Warning: static_assets root_dir '#{root_dir}' is not a directory!"
|
400
|
+
end
|
401
|
+
|
402
|
+
args[:relative_path] = true unless args.key?(:relative_path)
|
403
|
+
|
404
|
+
location(/(?<path_suffix>.*)/, extensions: args[:allowed_extensions] || []) do
|
405
|
+
@middleware[:static_assets] = args
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def file_server(**args)
|
410
|
+
raise "`file_server` must be set inside a location block" if @parent.nil?
|
411
|
+
|
412
|
+
# Forward to static_assets for implementation
|
413
|
+
puts "Note: file_server is an alias for static_assets"
|
414
|
+
static_assets(**args)
|
415
|
+
end
|
416
|
+
|
417
|
+
def flatten_routes
|
418
|
+
result = []
|
419
|
+
result.concat(@children.flat_map(&:flatten_routes))
|
420
|
+
route_options = paths_from_parent
|
421
|
+
if route_options
|
422
|
+
result << deep_stringify_keys(
|
423
|
+
{
|
424
|
+
route: Regexp.new("^#{route_options}$"),
|
425
|
+
methods: @methods.any? ? @methods : nil,
|
426
|
+
protocols: @protocols.any? ? @protocols : nil,
|
427
|
+
hosts: @hosts.any? ? @hosts : nil,
|
428
|
+
ports: @ports.any? ? @ports : nil,
|
429
|
+
extensions: @extensions.any? ? @extensions : nil,
|
430
|
+
content_types: @content_types.any? ? @content_types : nil,
|
431
|
+
accepts: @accepts.any? ? @accepts : nil,
|
432
|
+
middleware: effective_middleware
|
433
|
+
}
|
434
|
+
)
|
435
|
+
end
|
436
|
+
result
|
437
|
+
end
|
438
|
+
|
439
|
+
def paths_from_parent
|
440
|
+
return nil unless @routes.any?
|
441
|
+
|
442
|
+
route_or_str = @routes.map do |seg|
|
443
|
+
case seg
|
444
|
+
when Regexp
|
445
|
+
seg.source
|
446
|
+
when /^:([A-Za-z_]\w*)(?:\(([^)]*)\))?$/
|
447
|
+
param_name = Regexp.last_match(1)
|
448
|
+
custom = Regexp.last_match(2)
|
449
|
+
if custom && !custom.empty?
|
450
|
+
"(?<#{param_name}>#{custom})"
|
451
|
+
else
|
452
|
+
"(?<#{param_name}>[^/]+)"
|
453
|
+
end
|
454
|
+
when /\*/
|
455
|
+
seg.gsub(/\*/, ".*")
|
456
|
+
else
|
457
|
+
Regexp.escape(seg).gsub(%r{/$}, ".*")
|
458
|
+
end
|
459
|
+
end.join("|")
|
460
|
+
|
461
|
+
if parent.paths_from_parent && parent.paths_from_parent != "(?:/.*)"
|
462
|
+
"#{parent.paths_from_parent}#{route_or_str != "" ? "(?:#{route_or_str})" : ""}"
|
463
|
+
else
|
464
|
+
route_or_str = "/#{route_or_str}" unless route_or_str.start_with?("/")
|
465
|
+
"(?:#{route_or_str})"
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
def effective_middleware
|
470
|
+
merged = merge_ancestor_middleware
|
471
|
+
merged.map { |k, v| { type: k.to_s, parameters: v } }
|
472
|
+
end
|
473
|
+
|
474
|
+
def merge_ancestor_middleware
|
475
|
+
chain = []
|
476
|
+
node = self
|
477
|
+
while node
|
478
|
+
chain << node
|
479
|
+
node = node.parent
|
480
|
+
end
|
481
|
+
chain.reverse!
|
482
|
+
|
483
|
+
merged = {}
|
484
|
+
chain.each do |n|
|
485
|
+
n.middleware.each do |k, v|
|
486
|
+
merged[k] = v
|
487
|
+
end
|
488
|
+
end
|
489
|
+
merged
|
490
|
+
end
|
491
|
+
|
492
|
+
def deep_stringify_keys(obj)
|
493
|
+
case obj
|
494
|
+
when Hash
|
495
|
+
obj.transform_keys!(&:to_s)
|
496
|
+
obj.transform_values! { |v| deep_stringify_keys(v) }
|
497
|
+
when Array
|
498
|
+
obj.map { |v| deep_stringify_keys(v) }
|
499
|
+
else
|
500
|
+
obj
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
506
|
+
end
|
@@ -1,26 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Itsi
|
2
4
|
class Server
|
3
5
|
module Config
|
4
|
-
|
6
|
+
require_relative "config/dsl"
|
7
|
+
require_relative "default_app/default_app"
|
8
|
+
require "debug"
|
5
9
|
|
6
10
|
ITSI_DEFAULT_CONFIG_FILE = "Itsi.rb"
|
7
11
|
|
8
|
-
def
|
9
|
-
|
12
|
+
def self.save_argv!
|
13
|
+
@argv ||= ARGV[0...ARGV.index("--listeners")]
|
14
|
+
end
|
15
|
+
|
16
|
+
# The configuration used when launching the Itsi server are evaluated in the following precedence:
|
17
|
+
# 1. CLI Args.
|
18
|
+
# 2. Itsi.rb file.
|
19
|
+
# 3. Default values.
|
20
|
+
def self.build_config(args, config_file_path, builder_proc)
|
21
|
+
itsifile_config = \
|
22
|
+
if builder_proc
|
23
|
+
DSL.evaluate(builder_proc)
|
24
|
+
elsif File.exist?(config_file_path.to_s)
|
25
|
+
DSL.evaluate(config_file_path)
|
26
|
+
else
|
27
|
+
{}
|
28
|
+
end
|
29
|
+
args.transform_keys!(&:to_sym)
|
30
|
+
itsifile_config.transform_keys!(&:to_sym)
|
31
|
+
|
32
|
+
# We'll preload while we load config, if enabled.
|
33
|
+
middleware_loader = itsifile_config.fetch(:middleware_loader, -> {})
|
34
|
+
default_app_loader = itsifile_config.fetch(:app_loader) do
|
35
|
+
rackup_file_path = args.fetch(:rackup_file, "./config.ru")
|
36
|
+
if File.exist?(rackup_file_path)
|
37
|
+
lambda {
|
38
|
+
{ "app_proc" => Itsi::Server::RackInterface.for(rackup_file_path) }
|
39
|
+
}
|
40
|
+
else
|
41
|
+
DEFAULT_APP
|
42
|
+
end
|
43
|
+
end
|
44
|
+
preload = args.fetch(:preload) { itsifile_config.fetch(:preload, false) }
|
45
|
+
|
46
|
+
case preload
|
47
|
+
# If we preload everything, then we'll load middleware and default rack app ahead of time
|
48
|
+
when true
|
49
|
+
preloaded_middleware = middleware_loader.call
|
50
|
+
preloaded_app = default_app_loader.call
|
51
|
+
middleware_loader = -> { preloaded_middleware }
|
52
|
+
default_app_loader = -> { preloaded_app }
|
53
|
+
# If we're just preloading a specific gem group, we'll do that here too
|
54
|
+
when Symbol
|
55
|
+
Bundler.require(preload)
|
56
|
+
end
|
57
|
+
|
58
|
+
{
|
59
|
+
workers: args.fetch(:workers) { itsifile_config.fetch(:workers, Etc.nprocessors) },
|
60
|
+
worker_memory_limit: args.fetch(:worker_memory_limit) { itsifile_config.fetch(:worker_memory_limit, nil) },
|
61
|
+
silence: args.fetch(:silence) { itsifile_config.fetch(:silence, false) },
|
62
|
+
shutdown_timeout: args.fetch(:shutdown_timeout) { itsifile_config.fetch(:shutdown_timeout, 5) },
|
63
|
+
hooks: itsifile_config.fetch(:hooks, nil),
|
64
|
+
preload: !!preload,
|
65
|
+
notify_watchers: itsifile_config.fetch(:notify_watchers, nil),
|
66
|
+
threads: args.fetch(:threads) { itsifile_config.fetch(:threads, 1) },
|
67
|
+
script_name: args.fetch(:script_name) { itsifile_config.fetch(:script_name, "") },
|
68
|
+
streamable_body: args.fetch(:streamable_body) { itsifile_config.fetch(:streamable_body, false) },
|
69
|
+
multithreaded_reactor: args.fetch(:multithreaded_reactor) do
|
70
|
+
itsifile_config.fetch(:multithreaded_reactor, true)
|
71
|
+
end,
|
72
|
+
scheduler_class: args.fetch(:scheduler_class) { itsifile_config.fetch(:scheduler_class, nil) },
|
73
|
+
oob_gc_responses_threshold: args.fetch(:oob_gc_responses_threshold) do
|
74
|
+
itsifile_config.fetch(:oob_gc_responses_threshold, nil)
|
75
|
+
end,
|
76
|
+
log_level: args.fetch(:log_level) { itsifile_config.fetch(:log_level, nil) },
|
77
|
+
binds: args.fetch(:binds) { itsifile_config.fetch(:binds, ["http://0.0.0.0:3000"]) },
|
78
|
+
middleware_loader: middleware_loader,
|
79
|
+
default_app_loader: default_app_loader,
|
80
|
+
listeners: args.fetch(:listeners) { nil }
|
81
|
+
}.transform_keys(&:to_s)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Reloads the entire process
|
85
|
+
# using exec, passing in any active file descriptors
|
86
|
+
# and previous invocation arguments
|
87
|
+
def self.reload_exec(listener_info)
|
88
|
+
if ENV["BUNDLE_BIN_PATH"]
|
89
|
+
exec "bundle", "exec", $PROGRAM_NAME, *@argv, "--listeners", listener_info
|
90
|
+
else
|
91
|
+
exec $PROGRAM_NAME, *@argv, "--listeners", listener_info
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Find config file path, if it exists.
|
96
|
+
def self.config_file_path(config_file_path = nil)
|
97
|
+
config_file_path ||= \
|
10
98
|
if File.exist?(ITSI_DEFAULT_CONFIG_FILE)
|
11
99
|
ITSI_DEFAULT_CONFIG_FILE
|
12
100
|
elsif File.exist?("config/#{ITSI_DEFAULT_CONFIG_FILE}")
|
13
101
|
"config/#{ITSI_DEFAULT_CONFIG_FILE}"
|
14
102
|
end
|
15
|
-
|
16
103
|
# Options simply pass through unless we've specified a config file
|
17
|
-
return
|
104
|
+
return unless File.exist?(config_file_path.to_s)
|
105
|
+
|
106
|
+
config_file_path
|
107
|
+
end
|
18
108
|
|
19
|
-
|
20
|
-
|
109
|
+
def self.pid_file_path
|
110
|
+
if Dir.exist?("tmp")
|
111
|
+
File.join("tmp", "itsi.pid")
|
112
|
+
else
|
113
|
+
".itsi.pid"
|
114
|
+
end
|
21
115
|
end
|
22
116
|
|
23
|
-
|
117
|
+
# Write a default config file, if one doesn't exist.
|
118
|
+
def self.write_default
|
24
119
|
if File.exist?(ITSI_DEFAULT_CONFIG_FILE)
|
25
120
|
puts "#{ITSI_DEFAULT_CONFIG_FILE} already exists."
|
26
121
|
return
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# When you Run Itsi without a Rack app,
|
2
|
+
# we start a tiny little echo server, just so you can see it in action.
|
3
|
+
DEFAULT_INDEX = IO.read("#{__dir__}/index.html").freeze
|
4
|
+
DEFAULT_BINDS = ["http://0.0.0.0:3000"].freeze
|
5
|
+
DEFAULT_APP = lambda {
|
6
|
+
require "json"
|
7
|
+
require "itsi/scheduler"
|
8
|
+
Itsi.log_warn "No config.ru or Itsi.rb app detected. Running default app."
|
9
|
+
{
|
10
|
+
"app_proc" => Itsi::Server::RackInterface.for(lambda do |env|
|
11
|
+
headers, body = \
|
12
|
+
if env["itsi.response"].json?
|
13
|
+
[
|
14
|
+
{ "Content-Type" => "application/json" },
|
15
|
+
[{ "message" => "You're running on Itsi!", "rack_env" => env,
|
16
|
+
"version" => Itsi::Server::VERSION }.to_json]
|
17
|
+
]
|
18
|
+
else
|
19
|
+
[
|
20
|
+
{ "Content-Type" => "text/html" },
|
21
|
+
[
|
22
|
+
format(
|
23
|
+
DEFAULT_INDEX,
|
24
|
+
REQUEST_METHOD: env["REQUEST_METHOD"],
|
25
|
+
PATH_INFO: env["PATH_INFO"],
|
26
|
+
SERVER_NAME: env["SERVER_NAME"],
|
27
|
+
SERVER_PORT: env["SERVER_PORT"],
|
28
|
+
REMOTE_ADDR: env["REMOTE_ADDR"],
|
29
|
+
HTTP_USER_AGENT: env["HTTP_USER_AGENT"]
|
30
|
+
)
|
31
|
+
]
|
32
|
+
]
|
33
|
+
end
|
34
|
+
[200, headers, body]
|
35
|
+
end)
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|