itsi 0.2.3 → 0.2.4
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 +2 -2
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/crates/itsi_scheduler/Cargo.toml +1 -1
- data/crates/itsi_server/Cargo.toml +1 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +28 -11
- data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +1 -1
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +1 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +14 -2
- data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +86 -41
- data/crates/itsi_server/src/services/itsi_http_service.rs +46 -35
- data/crates/itsi_server/src/services/static_file_server.rs +31 -3
- data/examples/api_with_schema_and_controllers/Itsi.rb +35 -0
- data/examples/api_with_schema_and_controllers/README.md +10 -0
- data/examples/api_with_schema_and_controllers/controllers.rb +66 -0
- data/examples/api_with_schema_and_controllers/schemas.rb +25 -0
- data/examples/file_server/Itsi.rb +30 -0
- data/examples/file_server/README.md +3 -0
- data/examples/file_server/about.html +80 -0
- data/examples/file_server/admin/secrets.txt +1 -0
- data/examples/file_server/fairytale.txt +33 -0
- data/examples/file_server/itsi-server-100.png +0 -0
- data/examples/file_server/subdirectory/movies.csv +21 -0
- data/examples/helpers/datastore.rb +84 -0
- data/examples/media_server/Itsi.rb +5 -0
- data/examples/media_server/README.md +3 -0
- data/examples/media_server/images/itsi-server-100.png +0 -0
- data/examples/media_server/index.html +82 -0
- data/examples/multi_rack_rails_sinatra/Gemfile +66 -0
- data/examples/multi_rack_rails_sinatra/Gemfile.lock +416 -0
- data/examples/multi_rack_rails_sinatra/Itsi.rb +44 -0
- data/examples/multi_rack_rails_sinatra/README.md +7 -0
- data/examples/multi_rack_rails_sinatra/index.html +119 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.dockerignore +51 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.gitattributes +9 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.github/dependabot.yml +12 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.github/workflows/ci.yml +90 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.gitignore +34 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/docker-setup.sample +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/post-app-boot.sample +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/post-deploy.sample +14 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/pre-app-boot.sample +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/pre-build.sample +51 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/pre-connect.sample +47 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/pre-deploy.sample +109 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.kamal/secrets +17 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.rubocop.yml +8 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/.ruby-version +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/Dockerfile +72 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/Gemfile +66 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/Gemfile.lock +416 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/README.md +24 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/Rakefile +6 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/assets/images/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/assets/stylesheets/application.css +161 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/controllers/application_controller.rb +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/controllers/articles_controller.rb +70 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/controllers/concerns/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/controllers/home_controller.rb +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/helpers/application_helper.rb +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/helpers/articles_helper.rb +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/helpers/home_helper.rb +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/javascript/application.js +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/javascript/controllers/application.js +9 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/javascript/controllers/hello_controller.js +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/javascript/controllers/index.js +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/jobs/application_job.rb +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/mailers/application_mailer.rb +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/models/application_record.rb +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/models/article.rb +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/models/concerns/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/_article.html.erb +14 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/_article.json.jbuilder +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/_form.html.erb +30 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/edit.html.erb +12 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/index.html.erb +29 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/index.json.jbuilder +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/new.html.erb +11 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/show.html.erb +10 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/articles/show.json.jbuilder +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/home/index.html.erb +8 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/layouts/application.html.erb +34 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/layouts/mailer.html.erb +13 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/layouts/mailer.text.erb +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/pwa/manifest.json.erb +22 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/app/views/pwa/service-worker.js +26 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/brakeman +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/bundle +109 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/dev +2 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/docker-entrypoint +14 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/importmap +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/jobs +6 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/kamal +27 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/rails +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/rake +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/rubocop +8 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/setup +34 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/bin/thrust +5 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/application.rb +27 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/boot.rb +4 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/cable.yml +17 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/cache.yml +16 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/credentials.yml.enc +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/database.yml +41 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/deploy.yml +116 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/environment.rb +5 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/environments/development.rb +72 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/environments/production.rb +90 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/environments/test.rb +53 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/importmap.rb +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/initializers/assets.rb +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/initializers/content_security_policy.rb +25 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/initializers/inflections.rb +16 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/locales/en.yml +31 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/puma.rb +41 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/queue.yml +18 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/recurring.yml +10 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/routes.rb +17 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config/storage.yml +34 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/config.ru +6 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/cable_schema.rb +11 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/cache_schema.rb +14 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/migrate/20250422211855_create_articles.rb +10 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/queue_schema.rb +129 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/schema.rb +20 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/db/seeds.rb +9 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/lib/tasks/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/log/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/400.html +114 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/404.html +114 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/406-unsupported-browser.html +114 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/422.html +114 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/500.html +114 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/icon.png +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/icon.svg +3 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/public/robots.txt +1 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/script/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/storage/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/application_system_test_case.rb +5 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/controllers/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/controllers/articles_controller_test.rb +48 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/controllers/home_controller_test.rb +8 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/fixtures/articles.yml +9 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/fixtures/files/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/helpers/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/integration/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/mailers/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/models/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/models/article_test.rb +7 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/system/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/system/articles_test.rb +43 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/test/test_helper.rb +15 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/tmp/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/tmp/pids/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/tmp/storage/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/vendor/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/rails_subapp/vendor/javascript/.keep +0 -0
- data/examples/multi_rack_rails_sinatra/sinatra_subapp/config.ru +2 -0
- data/examples/multi_rack_rails_sinatra/sinatra_subapp/my_app.rb +96 -0
- data/examples/rails_with_static_assets/.dockerignore +51 -0
- data/examples/rails_with_static_assets/.gitattributes +9 -0
- data/examples/rails_with_static_assets/.github/dependabot.yml +12 -0
- data/examples/rails_with_static_assets/.github/workflows/ci.yml +90 -0
- data/examples/rails_with_static_assets/.gitignore +34 -0
- data/examples/rails_with_static_assets/.kamal/hooks/docker-setup.sample +3 -0
- data/examples/rails_with_static_assets/.kamal/hooks/post-app-boot.sample +3 -0
- data/examples/rails_with_static_assets/.kamal/hooks/post-deploy.sample +14 -0
- data/examples/rails_with_static_assets/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/examples/rails_with_static_assets/.kamal/hooks/pre-app-boot.sample +3 -0
- data/examples/rails_with_static_assets/.kamal/hooks/pre-build.sample +51 -0
- data/examples/rails_with_static_assets/.kamal/hooks/pre-connect.sample +47 -0
- data/examples/rails_with_static_assets/.kamal/hooks/pre-deploy.sample +109 -0
- data/examples/rails_with_static_assets/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/examples/rails_with_static_assets/.kamal/secrets +17 -0
- data/examples/rails_with_static_assets/.rubocop.yml +8 -0
- data/examples/rails_with_static_assets/.ruby-version +1 -0
- data/examples/rails_with_static_assets/Dockerfile +72 -0
- data/examples/rails_with_static_assets/Gemfile +66 -0
- data/examples/rails_with_static_assets/Gemfile.lock +416 -0
- data/examples/rails_with_static_assets/Itsi.rb +10 -0
- data/examples/rails_with_static_assets/README.md +14 -0
- data/examples/rails_with_static_assets/Rakefile +6 -0
- data/examples/rails_with_static_assets/app/assets/images/.keep +0 -0
- data/examples/rails_with_static_assets/app/assets/stylesheets/application.css +161 -0
- data/examples/rails_with_static_assets/app/controllers/application_controller.rb +4 -0
- data/examples/rails_with_static_assets/app/controllers/articles_controller.rb +70 -0
- data/examples/rails_with_static_assets/app/controllers/concerns/.keep +0 -0
- data/examples/rails_with_static_assets/app/controllers/home_controller.rb +4 -0
- data/examples/rails_with_static_assets/app/helpers/application_helper.rb +2 -0
- data/examples/rails_with_static_assets/app/helpers/articles_helper.rb +2 -0
- data/examples/rails_with_static_assets/app/helpers/home_helper.rb +2 -0
- data/examples/rails_with_static_assets/app/javascript/application.js +3 -0
- data/examples/rails_with_static_assets/app/javascript/controllers/application.js +9 -0
- data/examples/rails_with_static_assets/app/javascript/controllers/hello_controller.js +7 -0
- data/examples/rails_with_static_assets/app/javascript/controllers/index.js +4 -0
- data/examples/rails_with_static_assets/app/jobs/application_job.rb +7 -0
- data/examples/rails_with_static_assets/app/mailers/application_mailer.rb +4 -0
- data/examples/rails_with_static_assets/app/models/application_record.rb +3 -0
- data/examples/rails_with_static_assets/app/models/article.rb +2 -0
- data/examples/rails_with_static_assets/app/models/concerns/.keep +0 -0
- data/examples/rails_with_static_assets/app/views/articles/_article.html.erb +14 -0
- data/examples/rails_with_static_assets/app/views/articles/_article.json.jbuilder +2 -0
- data/examples/rails_with_static_assets/app/views/articles/_form.html.erb +30 -0
- data/examples/rails_with_static_assets/app/views/articles/edit.html.erb +12 -0
- data/examples/rails_with_static_assets/app/views/articles/index.html.erb +29 -0
- data/examples/rails_with_static_assets/app/views/articles/index.json.jbuilder +1 -0
- data/examples/rails_with_static_assets/app/views/articles/new.html.erb +11 -0
- data/examples/rails_with_static_assets/app/views/articles/show.html.erb +10 -0
- data/examples/rails_with_static_assets/app/views/articles/show.json.jbuilder +1 -0
- data/examples/rails_with_static_assets/app/views/home/index.html.erb +8 -0
- data/examples/rails_with_static_assets/app/views/layouts/application.html.erb +34 -0
- data/examples/rails_with_static_assets/app/views/layouts/mailer.html.erb +13 -0
- data/examples/rails_with_static_assets/app/views/layouts/mailer.text.erb +1 -0
- data/examples/rails_with_static_assets/app/views/pwa/manifest.json.erb +22 -0
- data/examples/rails_with_static_assets/app/views/pwa/service-worker.js +26 -0
- data/examples/rails_with_static_assets/bin/brakeman +7 -0
- data/examples/rails_with_static_assets/bin/bundle +109 -0
- data/examples/rails_with_static_assets/bin/dev +2 -0
- data/examples/rails_with_static_assets/bin/docker-entrypoint +14 -0
- data/examples/rails_with_static_assets/bin/importmap +4 -0
- data/examples/rails_with_static_assets/bin/jobs +6 -0
- data/examples/rails_with_static_assets/bin/kamal +27 -0
- data/examples/rails_with_static_assets/bin/rails +4 -0
- data/examples/rails_with_static_assets/bin/rake +4 -0
- data/examples/rails_with_static_assets/bin/rubocop +8 -0
- data/examples/rails_with_static_assets/bin/setup +34 -0
- data/examples/rails_with_static_assets/bin/thrust +5 -0
- data/examples/rails_with_static_assets/config/application.rb +26 -0
- data/examples/rails_with_static_assets/config/boot.rb +4 -0
- data/examples/rails_with_static_assets/config/cable.yml +17 -0
- data/examples/rails_with_static_assets/config/cache.yml +16 -0
- data/examples/rails_with_static_assets/config/credentials.yml.enc +1 -0
- data/examples/rails_with_static_assets/config/database.yml +41 -0
- data/examples/rails_with_static_assets/config/deploy.yml +116 -0
- data/examples/rails_with_static_assets/config/environment.rb +5 -0
- data/examples/rails_with_static_assets/config/environments/development.rb +74 -0
- data/examples/rails_with_static_assets/config/environments/production.rb +90 -0
- data/examples/rails_with_static_assets/config/environments/test.rb +53 -0
- data/examples/rails_with_static_assets/config/importmap.rb +7 -0
- data/examples/rails_with_static_assets/config/initializers/assets.rb +7 -0
- data/examples/rails_with_static_assets/config/initializers/content_security_policy.rb +25 -0
- data/examples/rails_with_static_assets/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/rails_with_static_assets/config/initializers/inflections.rb +16 -0
- data/examples/rails_with_static_assets/config/locales/en.yml +31 -0
- data/examples/rails_with_static_assets/config/puma.rb +41 -0
- data/examples/rails_with_static_assets/config/queue.yml +18 -0
- data/examples/rails_with_static_assets/config/recurring.yml +10 -0
- data/examples/rails_with_static_assets/config/routes.rb +17 -0
- data/examples/rails_with_static_assets/config/storage.yml +34 -0
- data/examples/rails_with_static_assets/config.ru +6 -0
- data/examples/rails_with_static_assets/db/cable_schema.rb +11 -0
- data/examples/rails_with_static_assets/db/cache_schema.rb +14 -0
- data/examples/rails_with_static_assets/db/migrate/20250422211855_create_articles.rb +10 -0
- data/examples/rails_with_static_assets/db/queue_schema.rb +129 -0
- data/examples/rails_with_static_assets/db/schema.rb +20 -0
- data/examples/rails_with_static_assets/db/seeds.rb +9 -0
- data/examples/rails_with_static_assets/lib/tasks/.keep +0 -0
- data/examples/rails_with_static_assets/log/.keep +0 -0
- data/examples/rails_with_static_assets/public/400.html +114 -0
- data/examples/rails_with_static_assets/public/404.html +114 -0
- data/examples/rails_with_static_assets/public/406-unsupported-browser.html +114 -0
- data/examples/rails_with_static_assets/public/422.html +114 -0
- data/examples/rails_with_static_assets/public/500.html +114 -0
- data/examples/rails_with_static_assets/public/icon.png +0 -0
- data/examples/rails_with_static_assets/public/icon.svg +3 -0
- data/examples/rails_with_static_assets/public/robots.txt +1 -0
- data/examples/rails_with_static_assets/script/.keep +0 -0
- data/examples/rails_with_static_assets/storage/.keep +0 -0
- data/examples/rails_with_static_assets/test/application_system_test_case.rb +5 -0
- data/examples/rails_with_static_assets/test/controllers/.keep +0 -0
- data/examples/rails_with_static_assets/test/controllers/articles_controller_test.rb +48 -0
- data/examples/rails_with_static_assets/test/controllers/home_controller_test.rb +8 -0
- data/examples/rails_with_static_assets/test/fixtures/articles.yml +9 -0
- data/examples/rails_with_static_assets/test/fixtures/files/.keep +0 -0
- data/examples/rails_with_static_assets/test/helpers/.keep +0 -0
- data/examples/rails_with_static_assets/test/integration/.keep +0 -0
- data/examples/rails_with_static_assets/test/mailers/.keep +0 -0
- data/examples/rails_with_static_assets/test/models/.keep +0 -0
- data/examples/rails_with_static_assets/test/models/article_test.rb +7 -0
- data/examples/rails_with_static_assets/test/system/.keep +0 -0
- data/examples/rails_with_static_assets/test/system/articles_test.rb +43 -0
- data/examples/rails_with_static_assets/test/test_helper.rb +15 -0
- data/examples/rails_with_static_assets/tmp/.keep +0 -0
- data/examples/rails_with_static_assets/tmp/pids/.keep +0 -0
- data/examples/rails_with_static_assets/tmp/storage/.keep +0 -0
- data/examples/rails_with_static_assets/vendor/.keep +0 -0
- data/examples/rails_with_static_assets/vendor/javascript/.keep +0 -0
- data/examples/reverse_proxy/Itsi.rb +28 -0
- data/examples/reverse_proxy/README.md +14 -0
- data/examples/reverse_proxy/index.html +119 -0
- data/examples/reverse_proxy/rails_subapp/.dockerignore +51 -0
- data/examples/reverse_proxy/rails_subapp/.gitattributes +9 -0
- data/examples/reverse_proxy/rails_subapp/.github/dependabot.yml +12 -0
- data/examples/reverse_proxy/rails_subapp/.github/workflows/ci.yml +90 -0
- data/examples/reverse_proxy/rails_subapp/.gitignore +34 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/docker-setup.sample +3 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/post-app-boot.sample +3 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/post-deploy.sample +14 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/pre-app-boot.sample +3 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/pre-build.sample +51 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/pre-connect.sample +47 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/pre-deploy.sample +109 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/examples/reverse_proxy/rails_subapp/.kamal/secrets +17 -0
- data/examples/reverse_proxy/rails_subapp/.rubocop.yml +8 -0
- data/examples/reverse_proxy/rails_subapp/.ruby-version +1 -0
- data/examples/reverse_proxy/rails_subapp/Dockerfile +72 -0
- data/examples/reverse_proxy/rails_subapp/Gemfile +66 -0
- data/examples/reverse_proxy/rails_subapp/Gemfile.lock +416 -0
- data/examples/reverse_proxy/rails_subapp/README.md +24 -0
- data/examples/reverse_proxy/rails_subapp/Rakefile +6 -0
- data/examples/reverse_proxy/rails_subapp/app/assets/images/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/app/assets/stylesheets/application.css +161 -0
- data/examples/reverse_proxy/rails_subapp/app/controllers/application_controller.rb +4 -0
- data/examples/reverse_proxy/rails_subapp/app/controllers/articles_controller.rb +70 -0
- data/examples/reverse_proxy/rails_subapp/app/controllers/concerns/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/app/controllers/home_controller.rb +4 -0
- data/examples/reverse_proxy/rails_subapp/app/helpers/application_helper.rb +2 -0
- data/examples/reverse_proxy/rails_subapp/app/helpers/articles_helper.rb +2 -0
- data/examples/reverse_proxy/rails_subapp/app/helpers/home_helper.rb +2 -0
- data/examples/reverse_proxy/rails_subapp/app/javascript/application.js +3 -0
- data/examples/reverse_proxy/rails_subapp/app/javascript/controllers/application.js +9 -0
- data/examples/reverse_proxy/rails_subapp/app/javascript/controllers/hello_controller.js +7 -0
- data/examples/reverse_proxy/rails_subapp/app/javascript/controllers/index.js +4 -0
- data/examples/reverse_proxy/rails_subapp/app/jobs/application_job.rb +7 -0
- data/examples/reverse_proxy/rails_subapp/app/mailers/application_mailer.rb +4 -0
- data/examples/reverse_proxy/rails_subapp/app/models/application_record.rb +3 -0
- data/examples/reverse_proxy/rails_subapp/app/models/article.rb +2 -0
- data/examples/reverse_proxy/rails_subapp/app/models/concerns/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/_article.html.erb +14 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/_article.json.jbuilder +2 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/_form.html.erb +30 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/edit.html.erb +12 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/index.html.erb +29 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/index.json.jbuilder +1 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/new.html.erb +11 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/show.html.erb +10 -0
- data/examples/reverse_proxy/rails_subapp/app/views/articles/show.json.jbuilder +1 -0
- data/examples/reverse_proxy/rails_subapp/app/views/home/index.html.erb +8 -0
- data/examples/reverse_proxy/rails_subapp/app/views/layouts/application.html.erb +34 -0
- data/examples/reverse_proxy/rails_subapp/app/views/layouts/mailer.html.erb +13 -0
- data/examples/reverse_proxy/rails_subapp/app/views/layouts/mailer.text.erb +1 -0
- data/examples/reverse_proxy/rails_subapp/app/views/pwa/manifest.json.erb +22 -0
- data/examples/reverse_proxy/rails_subapp/app/views/pwa/service-worker.js +26 -0
- data/examples/reverse_proxy/rails_subapp/bin/brakeman +7 -0
- data/examples/reverse_proxy/rails_subapp/bin/bundle +109 -0
- data/examples/reverse_proxy/rails_subapp/bin/dev +2 -0
- data/examples/reverse_proxy/rails_subapp/bin/docker-entrypoint +14 -0
- data/examples/reverse_proxy/rails_subapp/bin/importmap +4 -0
- data/examples/reverse_proxy/rails_subapp/bin/jobs +6 -0
- data/examples/reverse_proxy/rails_subapp/bin/kamal +27 -0
- data/examples/reverse_proxy/rails_subapp/bin/rails +4 -0
- data/examples/reverse_proxy/rails_subapp/bin/rake +4 -0
- data/examples/reverse_proxy/rails_subapp/bin/rubocop +8 -0
- data/examples/reverse_proxy/rails_subapp/bin/setup +34 -0
- data/examples/reverse_proxy/rails_subapp/bin/thrust +5 -0
- data/examples/reverse_proxy/rails_subapp/config/application.rb +26 -0
- data/examples/reverse_proxy/rails_subapp/config/boot.rb +4 -0
- data/examples/reverse_proxy/rails_subapp/config/cable.yml +17 -0
- data/examples/reverse_proxy/rails_subapp/config/cache.yml +16 -0
- data/examples/reverse_proxy/rails_subapp/config/credentials.yml.enc +1 -0
- data/examples/reverse_proxy/rails_subapp/config/database.yml +41 -0
- data/examples/reverse_proxy/rails_subapp/config/deploy.yml +116 -0
- data/examples/reverse_proxy/rails_subapp/config/environment.rb +5 -0
- data/examples/reverse_proxy/rails_subapp/config/environments/development.rb +72 -0
- data/examples/reverse_proxy/rails_subapp/config/environments/production.rb +90 -0
- data/examples/reverse_proxy/rails_subapp/config/environments/test.rb +53 -0
- data/examples/reverse_proxy/rails_subapp/config/importmap.rb +7 -0
- data/examples/reverse_proxy/rails_subapp/config/initializers/assets.rb +7 -0
- data/examples/reverse_proxy/rails_subapp/config/initializers/content_security_policy.rb +25 -0
- data/examples/reverse_proxy/rails_subapp/config/initializers/filter_parameter_logging.rb +8 -0
- data/examples/reverse_proxy/rails_subapp/config/initializers/inflections.rb +16 -0
- data/examples/reverse_proxy/rails_subapp/config/locales/en.yml +31 -0
- data/examples/reverse_proxy/rails_subapp/config/puma.rb +41 -0
- data/examples/reverse_proxy/rails_subapp/config/queue.yml +18 -0
- data/examples/reverse_proxy/rails_subapp/config/recurring.yml +10 -0
- data/examples/reverse_proxy/rails_subapp/config/routes.rb +17 -0
- data/examples/reverse_proxy/rails_subapp/config/storage.yml +34 -0
- data/examples/reverse_proxy/rails_subapp/config.ru +6 -0
- data/examples/reverse_proxy/rails_subapp/db/cable_schema.rb +11 -0
- data/examples/reverse_proxy/rails_subapp/db/cache_schema.rb +14 -0
- data/examples/reverse_proxy/rails_subapp/db/migrate/20250422211855_create_articles.rb +10 -0
- data/examples/reverse_proxy/rails_subapp/db/queue_schema.rb +129 -0
- data/examples/reverse_proxy/rails_subapp/db/schema.rb +20 -0
- data/examples/reverse_proxy/rails_subapp/db/seeds.rb +9 -0
- data/examples/reverse_proxy/rails_subapp/lib/tasks/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/log/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/public/400.html +114 -0
- data/examples/reverse_proxy/rails_subapp/public/404.html +114 -0
- data/examples/reverse_proxy/rails_subapp/public/406-unsupported-browser.html +114 -0
- data/examples/reverse_proxy/rails_subapp/public/422.html +114 -0
- data/examples/reverse_proxy/rails_subapp/public/500.html +114 -0
- data/examples/reverse_proxy/rails_subapp/public/icon.png +0 -0
- data/examples/reverse_proxy/rails_subapp/public/icon.svg +3 -0
- data/examples/reverse_proxy/rails_subapp/public/robots.txt +1 -0
- data/examples/reverse_proxy/rails_subapp/script/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/storage/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/application_system_test_case.rb +5 -0
- data/examples/reverse_proxy/rails_subapp/test/controllers/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/controllers/articles_controller_test.rb +48 -0
- data/examples/reverse_proxy/rails_subapp/test/controllers/home_controller_test.rb +8 -0
- data/examples/reverse_proxy/rails_subapp/test/fixtures/articles.yml +9 -0
- data/examples/reverse_proxy/rails_subapp/test/fixtures/files/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/helpers/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/integration/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/mailers/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/models/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/models/article_test.rb +7 -0
- data/examples/reverse_proxy/rails_subapp/test/system/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/test/system/articles_test.rb +43 -0
- data/examples/reverse_proxy/rails_subapp/test/test_helper.rb +15 -0
- data/examples/reverse_proxy/rails_subapp/tmp/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/tmp/pids/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/tmp/storage/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/vendor/.keep +0 -0
- data/examples/reverse_proxy/rails_subapp/vendor/javascript/.keep +0 -0
- data/examples/reverse_proxy/sinatra_subapp/Gemfile +2 -0
- data/examples/reverse_proxy/sinatra_subapp/Gemfile.lock +46 -0
- data/examples/reverse_proxy/sinatra_subapp/config.ru +2 -0
- data/examples/reverse_proxy/sinatra_subapp/my_app.rb +96 -0
- data/examples/simple_api/Itsi.rb +127 -0
- data/examples/simple_api_no_schema/Itsi.rb +86 -0
- data/examples/spa/Itsi.rb +5 -0
- data/examples/spa/README.md +3 -0
- data/examples/spa/dist/assets/index-2cf7be43.js +40 -0
- data/examples/spa/dist/index.html +13 -0
- data/examples/spa/index.html +12 -0
- data/examples/spa/package-lock.json +1265 -0
- data/examples/spa/package.json +18 -0
- data/examples/spa/src/App.jsx +49 -0
- data/examples/spa/src/main.jsx +6 -0
- data/examples/spa/src/pages/About.jsx +9 -0
- data/examples/spa/src/pages/Home.jsx +9 -0
- data/examples/spa/vite.config.js +9 -0
- data/gems/scheduler/Cargo.lock +1 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/server/Cargo.lock +1 -1
- data/gems/server/lib/itsi/server/config/dsl.rb +2 -2
- data/gems/server/lib/itsi/server/config/middleware/endpoint/endpoint.rb +0 -4
- data/gems/server/lib/itsi/server/config/middleware/location.rb +25 -21
- data/gems/server/lib/itsi/server/config/middleware/proxy.rb +15 -14
- data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +7 -10
- data/gems/server/lib/itsi/server/config/middleware/static_assets.rb +8 -4
- data/gems/server/lib/itsi/server/config/middleware/string_rewrite.md +14 -0
- data/gems/server/lib/itsi/server/config/options/include.rb +1 -1
- data/gems/server/lib/itsi/server/rack_interface.rb +1 -1
- data/gems/server/lib/itsi/server/route_tester.rb +1 -1
- data/gems/server/lib/itsi/server/typed_handlers/param_parser.rb +25 -0
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +1 -1
- data/gems/server/test/middleware/static_assets.rb +6 -4
- data/gems/server/test/middleware/string_rewrite.rb +54 -0
- data/gems/server/test/middleware/test_log_requests.rb +13 -1
- data/lib/itsi/version.rb +1 -1
- metadata +431 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c0f48a4cf96ec2afd196a828cd9b264a019673ce1cb690229c57a4f113f47e52
|
|
4
|
+
data.tar.gz: 6119bc422b0ec00e7d4d9c52314d725c441e2117275402c838f1ee47166b000a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7d572b3bad1e3156eb2e0c5da02d9ac5b988f37b19d33fdac7f475cd6161563c4d5befaae7d5776fc30e1089fe8f2d025e9557978f618980260e6d1715f2783c
|
|
7
|
+
data.tar.gz: 3913fb88decca4a0fc83e2c0136056d5eff6b703c498cb0d160c9bf2accadbe50a01c23d6380eb0a87a41e7901f2dbac6cf1050c566f2250a91fc51991a4749d
|
data/Cargo.lock
CHANGED
|
@@ -1644,7 +1644,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
|
|
1644
1644
|
|
|
1645
1645
|
[[package]]
|
|
1646
1646
|
name = "itsi-scheduler"
|
|
1647
|
-
version = "0.2.
|
|
1647
|
+
version = "0.2.4"
|
|
1648
1648
|
dependencies = [
|
|
1649
1649
|
"bytes",
|
|
1650
1650
|
"derive_more",
|
|
@@ -1662,7 +1662,7 @@ dependencies = [
|
|
|
1662
1662
|
|
|
1663
1663
|
[[package]]
|
|
1664
1664
|
name = "itsi-server"
|
|
1665
|
-
version = "0.2.
|
|
1665
|
+
version = "0.2.4"
|
|
1666
1666
|
dependencies = [
|
|
1667
1667
|
"argon2",
|
|
1668
1668
|
"async-channel",
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
> The Serious Web Server, for Serious People
|
|
5
5
|
|
|
6
6
|
[](https://github.com/wouterken/itsi/actions/workflows/test.yml)
|
|
7
|
-
[](https://rubygems.org/gems/itsi)
|
|
8
8
|
|
|
9
9
|
Itsi is a feature-packed, high performance web and application server, with first-class support for Ruby applications.
|
|
10
10
|
It's a compliant Rack server. It’s also a well-equipped reverse proxy, API gateway, and static file server, controlled by an intuitive and elegant configuration API and DSL.
|
data/Rakefile
CHANGED
|
@@ -84,11 +84,11 @@ task :build_all do
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
task :test_env_up do
|
|
87
|
-
system('terraform -chdir=sandbox/deploy apply')
|
|
87
|
+
system('terraform -chdir=tmp/sandbox/deploy apply')
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
task :test_env_down do
|
|
91
|
-
system('terraform -chdir=sandbox/deploy destroy')
|
|
91
|
+
system('terraform -chdir=tmp/sandbox/deploy destroy')
|
|
92
92
|
end
|
|
93
93
|
%i[itsi puma iodine falcon unicorn].each do |server|
|
|
94
94
|
namespace server do
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
server::http_message_types::
|
|
2
|
+
server::http_message_types::{HttpRequest, HttpResponse},
|
|
3
|
+
services::itsi_http_service::HttpRequestContext,
|
|
3
4
|
};
|
|
4
5
|
|
|
5
6
|
use super::{
|
|
@@ -13,6 +14,7 @@ use async_compression::{
|
|
|
13
14
|
};
|
|
14
15
|
use async_trait::async_trait;
|
|
15
16
|
use bytes::{Bytes, BytesMut};
|
|
17
|
+
use either::Either;
|
|
16
18
|
use futures::TryStreamExt;
|
|
17
19
|
use http::{
|
|
18
20
|
header::{GetAll, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_TYPE},
|
|
@@ -20,6 +22,7 @@ use http::{
|
|
|
20
22
|
};
|
|
21
23
|
use http_body_util::{combinators::BoxBody, BodyExt, Full, StreamBody};
|
|
22
24
|
use hyper::body::{Body, Frame};
|
|
25
|
+
use magnus::error::Result;
|
|
23
26
|
use serde::{Deserialize, Serialize};
|
|
24
27
|
use std::convert::Infallible;
|
|
25
28
|
use tokio::io::{AsyncRead, AsyncReadExt, BufReader};
|
|
@@ -151,6 +154,15 @@ fn update_content_encoding(parts: &mut http::response::Parts, new_encoding: Head
|
|
|
151
154
|
|
|
152
155
|
#[async_trait]
|
|
153
156
|
impl MiddlewareLayer for Compression {
|
|
157
|
+
async fn before(
|
|
158
|
+
&self,
|
|
159
|
+
req: HttpRequest,
|
|
160
|
+
context: &mut HttpRequestContext,
|
|
161
|
+
) -> Result<Either<HttpRequest, HttpResponse>> {
|
|
162
|
+
context.set_supported_encoding_set(&req);
|
|
163
|
+
Ok(Either::Left(req))
|
|
164
|
+
}
|
|
165
|
+
|
|
154
166
|
/// We'll apply compression on the response, where appropriate.
|
|
155
167
|
/// This is if:
|
|
156
168
|
/// * The response body is larger than the minimum size.
|
|
@@ -207,16 +219,21 @@ impl MiddlewareLayer for Compression {
|
|
|
207
219
|
}
|
|
208
220
|
}
|
|
209
221
|
|
|
210
|
-
let compression_method =
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
222
|
+
let compression_method =
|
|
223
|
+
if let Some(supported_encoding_set) = context.supported_encoding_set() {
|
|
224
|
+
match find_first_supported(
|
|
225
|
+
supported_encoding_set,
|
|
226
|
+
self.algorithms.iter().map(|algo| algo.as_str()),
|
|
227
|
+
) {
|
|
228
|
+
Some("gzip") => CompressionAlgorithm::Gzip,
|
|
229
|
+
Some("br") => CompressionAlgorithm::Brotli,
|
|
230
|
+
Some("deflate") => CompressionAlgorithm::Deflate,
|
|
231
|
+
Some("zstd") => CompressionAlgorithm::Zstd,
|
|
232
|
+
_ => CompressionAlgorithm::Identity,
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
CompressionAlgorithm::Identity
|
|
236
|
+
};
|
|
220
237
|
|
|
221
238
|
debug!(
|
|
222
239
|
target: "middleware::compress",
|
|
@@ -62,7 +62,7 @@ impl MiddlewareLayer for LogRequests {
|
|
|
62
62
|
req: HttpRequest,
|
|
63
63
|
context: &mut HttpRequestContext,
|
|
64
64
|
) -> Result<Either<HttpRequest, HttpResponse>> {
|
|
65
|
-
context.
|
|
65
|
+
context.init_logging_params();
|
|
66
66
|
if let Some(LogConfig { level, format }) = self.before.as_ref() {
|
|
67
67
|
level.log(format.rewrite_request(&req, context));
|
|
68
68
|
}
|
|
@@ -33,7 +33,7 @@ use reqwest::{
|
|
|
33
33
|
Body, Client, Url,
|
|
34
34
|
};
|
|
35
35
|
use serde::Deserialize;
|
|
36
|
-
use tracing::
|
|
36
|
+
use tracing::debug;
|
|
37
37
|
|
|
38
38
|
#[derive(Debug, Clone, Deserialize)]
|
|
39
39
|
pub struct Proxy {
|
|
@@ -324,7 +324,6 @@ impl MiddlewareLayer for Proxy {
|
|
|
324
324
|
.unwrap_or("")
|
|
325
325
|
});
|
|
326
326
|
|
|
327
|
-
info!("Extracted host str is {}", host_str);
|
|
328
327
|
let req_info = RequestInfo {
|
|
329
328
|
method: req.method().clone(),
|
|
330
329
|
headers: req_headers.clone(),
|
|
@@ -12,10 +12,11 @@ use async_trait::async_trait;
|
|
|
12
12
|
use either::Either;
|
|
13
13
|
use http::{
|
|
14
14
|
header::{IF_MODIFIED_SINCE, RANGE},
|
|
15
|
-
HeaderMap, Method,
|
|
15
|
+
HeaderMap, HeaderValue, Method,
|
|
16
16
|
};
|
|
17
17
|
use itsi_error::ItsiError;
|
|
18
18
|
use magnus::error::Result;
|
|
19
|
+
use moka::sync::Cache;
|
|
19
20
|
use regex::Regex;
|
|
20
21
|
use serde::Deserialize;
|
|
21
22
|
use std::{collections::HashMap, path::PathBuf, sync::OnceLock, time::Duration};
|
|
@@ -75,6 +76,10 @@ impl MiddlewareLayer for StaticAssets {
|
|
|
75
76
|
recheck_interval: Duration::from_secs(self.file_check_interval),
|
|
76
77
|
serve_hidden_files: self.serve_hidden_files,
|
|
77
78
|
allowed_extensions: self.allowed_extensions.clone(),
|
|
79
|
+
miss_cache: Cache::builder()
|
|
80
|
+
.max_capacity(self.max_files_in_memory)
|
|
81
|
+
.time_to_live(Duration::from_secs(self.file_check_interval))
|
|
82
|
+
.build(),
|
|
78
83
|
})?)
|
|
79
84
|
.map_err(ItsiError::new)?;
|
|
80
85
|
Ok(())
|
|
@@ -90,6 +95,8 @@ impl MiddlewareLayer for StaticAssets {
|
|
|
90
95
|
debug!(target: "middleware::static_assets", "Refusing to handle non-GET/HEAD request");
|
|
91
96
|
return Ok(Either::Left(req));
|
|
92
97
|
}
|
|
98
|
+
|
|
99
|
+
context.set_supported_encoding_set(&req);
|
|
93
100
|
let abs_path = req.uri().path();
|
|
94
101
|
let rel_path = if !self.relative_path {
|
|
95
102
|
abs_path.trim_start_matches("/")
|
|
@@ -123,6 +130,10 @@ impl MiddlewareLayer for StaticAssets {
|
|
|
123
130
|
|
|
124
131
|
// Let the file server handle everything
|
|
125
132
|
let file_server = self.file_server.get().unwrap();
|
|
133
|
+
let encodings: &[HeaderValue] = context
|
|
134
|
+
.supported_encoding_set()
|
|
135
|
+
.map(Vec::as_slice)
|
|
136
|
+
.unwrap_or(&[] as &[HeaderValue]);
|
|
126
137
|
let response = file_server
|
|
127
138
|
.serve(
|
|
128
139
|
&req,
|
|
@@ -131,9 +142,10 @@ impl MiddlewareLayer for StaticAssets {
|
|
|
131
142
|
serve_range,
|
|
132
143
|
if_modified_since,
|
|
133
144
|
is_head_request,
|
|
134
|
-
|
|
145
|
+
encodings,
|
|
135
146
|
)
|
|
136
147
|
.await;
|
|
148
|
+
|
|
137
149
|
if response.is_none() {
|
|
138
150
|
Ok(Either::Left(req))
|
|
139
151
|
} else {
|
|
@@ -50,6 +50,35 @@ pub fn parse_template(template: &str) -> Vec<Segment> {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
impl StringRewrite {
|
|
53
|
+
/// Apply a single modifier of the form `op:arg` (or for replace `op:from,to`)
|
|
54
|
+
#[inline]
|
|
55
|
+
fn apply_modifier(s: &mut String, mod_str: &str) {
|
|
56
|
+
if let Some((op, arg)) = mod_str.split_once(':') {
|
|
57
|
+
match op {
|
|
58
|
+
"strip_prefix" => {
|
|
59
|
+
if s.starts_with(arg) {
|
|
60
|
+
let _ = s.drain(..arg.len());
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
"strip_suffix" => {
|
|
64
|
+
if s.ends_with(arg) {
|
|
65
|
+
let len = s.len();
|
|
66
|
+
let start = len.saturating_sub(arg.len());
|
|
67
|
+
let _ = s.drain(start..);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
"replace" => {
|
|
71
|
+
if let Some((from, to)) = arg.split_once(',') {
|
|
72
|
+
if s.contains(from) {
|
|
73
|
+
*s = s.replace(from, to);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
_ => {}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
53
82
|
pub fn rewrite_request(&self, req: &HttpRequest, context: &HttpRequestContext) -> String {
|
|
54
83
|
let segments = self
|
|
55
84
|
.segments
|
|
@@ -63,9 +92,17 @@ impl StringRewrite {
|
|
|
63
92
|
|
|
64
93
|
for segment in segments {
|
|
65
94
|
match segment {
|
|
66
|
-
Segment::Literal(text) =>
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
Segment::Literal(text) => {
|
|
96
|
+
result.push_str(text);
|
|
97
|
+
}
|
|
98
|
+
Segment::Placeholder(raw) => {
|
|
99
|
+
// split into key and optional modifier
|
|
100
|
+
let mut parts = raw.split('|');
|
|
101
|
+
let key = parts.next().unwrap();
|
|
102
|
+
let modifiers = parts; // zero o
|
|
103
|
+
|
|
104
|
+
// 1) lookup the raw replacement
|
|
105
|
+
let mut replacement = match key {
|
|
69
106
|
"request_id" => context.short_request_id(),
|
|
70
107
|
"request_id_full" => context.request_id(),
|
|
71
108
|
"method" => req.method().as_str().to_string(),
|
|
@@ -76,13 +113,13 @@ impl StringRewrite {
|
|
|
76
113
|
.uri()
|
|
77
114
|
.path_and_query()
|
|
78
115
|
.map(|pq| pq.to_string())
|
|
79
|
-
.
|
|
116
|
+
.unwrap_or_default(),
|
|
80
117
|
"query" => {
|
|
81
|
-
let
|
|
82
|
-
if
|
|
83
|
-
|
|
118
|
+
let q = req.uri().query().unwrap_or("");
|
|
119
|
+
if q.is_empty() {
|
|
120
|
+
"".to_string()
|
|
84
121
|
} else {
|
|
85
|
-
format!("?{}",
|
|
122
|
+
format!("?{}", q)
|
|
86
123
|
}
|
|
87
124
|
}
|
|
88
125
|
"port" => req
|
|
@@ -91,31 +128,34 @@ impl StringRewrite {
|
|
|
91
128
|
.map(|p| p.to_string())
|
|
92
129
|
.unwrap_or_else(|| "80".to_string()),
|
|
93
130
|
"start_time" => {
|
|
94
|
-
if let Some(
|
|
95
|
-
|
|
131
|
+
if let Some(ts) = context.start_time() {
|
|
132
|
+
ts.format("%Y-%m-%d:%H:%M:%S:%3f").to_string()
|
|
96
133
|
} else {
|
|
97
134
|
"N/A".to_string()
|
|
98
135
|
}
|
|
99
136
|
}
|
|
100
137
|
other => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
} else {
|
|
138
|
+
// headers first
|
|
139
|
+
if let Some(hv) = req.headers().get(other) {
|
|
140
|
+
hv.to_str().unwrap_or("").to_string()
|
|
141
|
+
}
|
|
142
|
+
// then any regex‐capture
|
|
143
|
+
else if let Some(caps) = &captures {
|
|
144
|
+
caps.name(other)
|
|
145
|
+
.map(|m| m.as_str().to_string())
|
|
146
|
+
.unwrap_or_else(|| format!("{{{}}}", other))
|
|
147
|
+
}
|
|
148
|
+
// fallback: leave placeholder intact
|
|
149
|
+
else {
|
|
115
150
|
format!("{{{}}}", other)
|
|
116
151
|
}
|
|
117
152
|
}
|
|
118
153
|
};
|
|
154
|
+
|
|
155
|
+
for m in modifiers {
|
|
156
|
+
Self::apply_modifier(&mut replacement, m);
|
|
157
|
+
}
|
|
158
|
+
|
|
119
159
|
result.push_str(&replacement);
|
|
120
160
|
}
|
|
121
161
|
}
|
|
@@ -132,37 +172,42 @@ impl StringRewrite {
|
|
|
132
172
|
let mut result = String::with_capacity(self.template_string.len());
|
|
133
173
|
for segment in segments {
|
|
134
174
|
match segment {
|
|
135
|
-
Segment::Literal(text) =>
|
|
136
|
-
|
|
137
|
-
|
|
175
|
+
Segment::Literal(text) => {
|
|
176
|
+
result.push_str(text);
|
|
177
|
+
}
|
|
178
|
+
Segment::Placeholder(raw) => {
|
|
179
|
+
let mut parts = raw.split('|');
|
|
180
|
+
let key = parts.next().unwrap();
|
|
181
|
+
let modifiers = parts; // zero o
|
|
182
|
+
|
|
183
|
+
let mut replacement = match key {
|
|
138
184
|
"request_id" => context.short_request_id(),
|
|
139
185
|
"request_id_full" => context.request_id(),
|
|
140
186
|
"status" => resp.status().as_str().to_string(),
|
|
141
187
|
"addr" => context.addr.to_owned(),
|
|
142
188
|
"response_time" => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
format!("{}ms", response_time.num_milliseconds())
|
|
148
|
-
}
|
|
189
|
+
let dur = context.get_response_time();
|
|
190
|
+
let micros = dur.as_micros();
|
|
191
|
+
if micros < 1_000 {
|
|
192
|
+
format!("{}µs", micros)
|
|
149
193
|
} else {
|
|
150
|
-
|
|
194
|
+
let ms = dur.as_secs_f64() * 1_000.0;
|
|
195
|
+
format!("{:.3}ms", ms)
|
|
151
196
|
}
|
|
152
197
|
}
|
|
153
198
|
other => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if let Ok(s) = val.to_str() {
|
|
157
|
-
s.to_string()
|
|
158
|
-
} else {
|
|
159
|
-
"".to_string()
|
|
160
|
-
}
|
|
199
|
+
if let Some(hv) = resp.headers().get(other) {
|
|
200
|
+
hv.to_str().unwrap_or("").to_string()
|
|
161
201
|
} else {
|
|
162
202
|
format!("{{{}}}", other)
|
|
163
203
|
}
|
|
164
204
|
}
|
|
165
205
|
};
|
|
206
|
+
|
|
207
|
+
for m in modifiers {
|
|
208
|
+
Self::apply_modifier(&mut replacement, m);
|
|
209
|
+
}
|
|
210
|
+
|
|
166
211
|
result.push_str(&replacement);
|
|
167
212
|
}
|
|
168
213
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
use crate::default_responses::{NOT_FOUND_RESPONSE, TIMEOUT_RESPONSE};
|
|
2
2
|
use crate::ruby_types::itsi_server::itsi_server_config::{ItsiServerTokenPreference, ServerParams};
|
|
3
3
|
use crate::server::binds::listener::ListenerInfo;
|
|
4
|
-
use crate::server::http_message_types::{
|
|
4
|
+
use crate::server::http_message_types::{
|
|
5
|
+
ConversionExt, HttpRequest, HttpResponse, RequestExt, ResponseFormat,
|
|
6
|
+
};
|
|
5
7
|
use crate::server::lifecycle_event::LifecycleEvent;
|
|
6
8
|
use crate::server::middleware_stack::MiddlewareLayer;
|
|
7
9
|
use crate::server::request_job::RequestJob;
|
|
8
10
|
use crate::server::serve_strategy::single_mode::RunningPhase;
|
|
9
11
|
use crate::server::signal::send_lifecycle_event;
|
|
10
|
-
use chrono;
|
|
11
|
-
use chrono::Local;
|
|
12
|
+
use chrono::{self, DateTime, Local};
|
|
12
13
|
use either::Either;
|
|
13
14
|
use http::header::ACCEPT_ENCODING;
|
|
14
15
|
use http::{HeaderValue, Request};
|
|
@@ -18,6 +19,7 @@ use itsi_error::ItsiError;
|
|
|
18
19
|
use regex::Regex;
|
|
19
20
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
20
21
|
use std::sync::OnceLock;
|
|
22
|
+
use std::time::{Duration, Instant};
|
|
21
23
|
use tracing::error;
|
|
22
24
|
|
|
23
25
|
use std::{future::Future, ops::Deref, pin::Pin, sync::Arc};
|
|
@@ -68,17 +70,16 @@ impl Deref for RequestContextInner {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
pub struct RequestContextInner {
|
|
71
|
-
pub request_id:
|
|
73
|
+
pub request_id: u64,
|
|
72
74
|
pub service: ItsiHttpService,
|
|
73
75
|
pub accept: ResponseFormat,
|
|
74
76
|
pub matching_pattern: Option<Arc<Regex>>,
|
|
75
77
|
pub origin: OnceLock<Option<String>>,
|
|
76
78
|
pub response_format: OnceLock<ResponseFormat>,
|
|
77
|
-
pub
|
|
78
|
-
pub
|
|
79
|
-
pub request_start_time: OnceLock<chrono::DateTime<Local>>,
|
|
79
|
+
pub request_start_time: OnceLock<DateTime<Local>>,
|
|
80
|
+
pub start_instant: Instant,
|
|
80
81
|
pub if_none_match: OnceLock<Option<String>>,
|
|
81
|
-
pub supported_encoding_set: Vec<HeaderValue
|
|
82
|
+
pub supported_encoding_set: OnceLock<Vec<HeaderValue>>,
|
|
82
83
|
pub is_ruby_request: Arc<AtomicBool>,
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -87,27 +88,38 @@ impl HttpRequestContext {
|
|
|
87
88
|
service: ItsiHttpService,
|
|
88
89
|
matching_pattern: Option<Arc<Regex>>,
|
|
89
90
|
accept: ResponseFormat,
|
|
90
|
-
supported_encoding_set: Vec<HeaderValue>,
|
|
91
91
|
is_ruby_request: Arc<AtomicBool>,
|
|
92
92
|
) -> Self {
|
|
93
93
|
HttpRequestContext {
|
|
94
94
|
inner: Arc::new(RequestContextInner {
|
|
95
|
-
request_id: rand::random::<
|
|
95
|
+
request_id: rand::random::<u64>(),
|
|
96
96
|
service,
|
|
97
97
|
matching_pattern,
|
|
98
98
|
accept,
|
|
99
99
|
origin: OnceLock::new(),
|
|
100
100
|
response_format: OnceLock::new(),
|
|
101
|
-
start_time: chrono::Utc::now(),
|
|
102
|
-
request: None,
|
|
103
101
|
request_start_time: OnceLock::new(),
|
|
102
|
+
start_instant: Instant::now(),
|
|
104
103
|
if_none_match: OnceLock::new(),
|
|
105
|
-
supported_encoding_set,
|
|
104
|
+
supported_encoding_set: OnceLock::new(),
|
|
106
105
|
is_ruby_request,
|
|
107
106
|
}),
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
|
|
110
|
+
pub fn set_supported_encoding_set(&self, req: &HttpRequest) {
|
|
111
|
+
let supported_encoding_set = req
|
|
112
|
+
.headers()
|
|
113
|
+
.get_all(ACCEPT_ENCODING)
|
|
114
|
+
.into_iter()
|
|
115
|
+
.cloned()
|
|
116
|
+
.collect::<Vec<_>>();
|
|
117
|
+
self.inner
|
|
118
|
+
.supported_encoding_set
|
|
119
|
+
.set(supported_encoding_set)
|
|
120
|
+
.unwrap();
|
|
121
|
+
}
|
|
122
|
+
|
|
111
123
|
pub fn set_origin(&self, origin: Option<String>) {
|
|
112
124
|
self.inner.origin.set(origin).unwrap();
|
|
113
125
|
}
|
|
@@ -121,28 +133,29 @@ impl HttpRequestContext {
|
|
|
121
133
|
}
|
|
122
134
|
|
|
123
135
|
pub fn short_request_id(&self) -> String {
|
|
124
|
-
format!("{:
|
|
136
|
+
format!("{:08x}", self.inner.request_id & 0xffff_ffff)
|
|
125
137
|
}
|
|
126
138
|
|
|
127
139
|
pub fn request_id(&self) -> String {
|
|
128
|
-
format!("{:
|
|
140
|
+
format!("{:08x}", self.inner.request_id)
|
|
129
141
|
}
|
|
130
142
|
|
|
131
|
-
pub fn
|
|
143
|
+
pub fn init_logging_params(&self) {
|
|
132
144
|
self.inner
|
|
133
145
|
.request_start_time
|
|
134
146
|
.get_or_init(chrono::Local::now);
|
|
135
147
|
}
|
|
136
148
|
|
|
137
|
-
pub fn
|
|
149
|
+
pub fn start_instant(&self) -> Instant {
|
|
150
|
+
self.inner.start_instant
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
pub fn start_time(&self) -> Option<DateTime<Local>> {
|
|
138
154
|
self.inner.request_start_time.get().cloned()
|
|
139
155
|
}
|
|
140
156
|
|
|
141
|
-
pub fn get_response_time(&self) ->
|
|
142
|
-
self.inner
|
|
143
|
-
.request_start_time
|
|
144
|
-
.get()
|
|
145
|
-
.map(|instant| Local::now() - instant)
|
|
157
|
+
pub fn get_response_time(&self) -> Duration {
|
|
158
|
+
self.inner.start_instant.elapsed()
|
|
146
159
|
}
|
|
147
160
|
|
|
148
161
|
pub fn set_response_format(&self, format: ResponseFormat) {
|
|
@@ -152,6 +165,10 @@ impl HttpRequestContext {
|
|
|
152
165
|
pub fn response_format(&self) -> &ResponseFormat {
|
|
153
166
|
self.inner.response_format.get().unwrap()
|
|
154
167
|
}
|
|
168
|
+
|
|
169
|
+
pub fn supported_encoding_set(&self) -> Option<&Vec<HeaderValue>> {
|
|
170
|
+
self.inner.supported_encoding_set.get()
|
|
171
|
+
}
|
|
155
172
|
}
|
|
156
173
|
|
|
157
174
|
const SERVER_TOKEN_VERSION: HeaderValue =
|
|
@@ -170,12 +187,7 @@ impl Service<Request<Incoming>> for ItsiHttpService {
|
|
|
170
187
|
let accept: ResponseFormat = req.accept().into();
|
|
171
188
|
let accept_clone = accept.clone();
|
|
172
189
|
let is_single_mode = self.server_params.workers == 1;
|
|
173
|
-
|
|
174
|
-
.headers()
|
|
175
|
-
.get_all(ACCEPT_ENCODING)
|
|
176
|
-
.into_iter()
|
|
177
|
-
.cloned()
|
|
178
|
-
.collect::<Vec<_>>();
|
|
190
|
+
|
|
179
191
|
let request_timeout = self.server_params.request_timeout;
|
|
180
192
|
let is_ruby_request = Arc::new(AtomicBool::new(false));
|
|
181
193
|
let irr_clone = is_ruby_request.clone();
|
|
@@ -187,7 +199,6 @@ impl Service<Request<Incoming>> for ItsiHttpService {
|
|
|
187
199
|
self_clone,
|
|
188
200
|
matching_pattern,
|
|
189
201
|
accept_clone.clone(),
|
|
190
|
-
supported_encoding_set,
|
|
191
202
|
irr_clone,
|
|
192
203
|
);
|
|
193
204
|
let mut depth = 0;
|
|
@@ -229,8 +240,8 @@ impl Service<Request<Incoming>> for ItsiHttpService {
|
|
|
229
240
|
Ok(resp)
|
|
230
241
|
};
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
|
|
243
|
+
if let Some(timeout_duration) = request_timeout {
|
|
244
|
+
Box::pin(async move {
|
|
234
245
|
match timeout(timeout_duration, service_future).await {
|
|
235
246
|
Ok(result) => result,
|
|
236
247
|
Err(_) => {
|
|
@@ -249,9 +260,9 @@ impl Service<Request<Incoming>> for ItsiHttpService {
|
|
|
249
260
|
Ok(TIMEOUT_RESPONSE.to_http_response(accept).await)
|
|
250
261
|
}
|
|
251
262
|
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
263
|
+
})
|
|
264
|
+
} else {
|
|
265
|
+
Box::pin(service_future)
|
|
266
|
+
}
|
|
256
267
|
}
|
|
257
268
|
}
|