Remove Rack::Runtime and deprecate referencing it
Previous discussion: #38412, #38325, 37423e4, 24f9c03 - Rack::Runtime is replaced by FakeRuntime, which is a dummy middleware that just passes requests on and cannot be used in middleware operations - Using Rack::Runtime in middleware operations (relative inserts, moves, etc.) throws a deprecation warning and uses FakeRuntime instead - if an application adds Rack::Runtime explicitly (use, unshift, etc.), then the deprecation warning does not happen and FakeRuntime is ignored - docs are updated to no longer reference Rack::Runtime
This commit is contained in:
parent
9aed3dcdfe
commit
7bfcf4b313
@ -5,6 +5,16 @@
|
|||||||
|
|
||||||
module ActionDispatch
|
module ActionDispatch
|
||||||
class MiddlewareStack
|
class MiddlewareStack
|
||||||
|
class FakeRuntime
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class Middleware
|
class Middleware
|
||||||
attr_reader :args, :block, :klass
|
attr_reader :args, :block, :klass
|
||||||
|
|
||||||
@ -69,6 +79,7 @@ def call(env)
|
|||||||
|
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
@middlewares = []
|
@middlewares = []
|
||||||
|
@rack_runtime_deprecated = true
|
||||||
yield(self) if block_given?
|
yield(self) if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -153,13 +164,31 @@ def build(app = nil, &block)
|
|||||||
|
|
||||||
private
|
private
|
||||||
def assert_index(index, where)
|
def assert_index(index, where)
|
||||||
i = index.is_a?(Integer) ? index : middlewares.index { |m| m.klass == index }
|
i = index.is_a?(Integer) ? index : index_of(index)
|
||||||
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
raise "No such middleware to insert #{where}: #{index.inspect}" unless i
|
||||||
i
|
i
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_middleware(klass, args, block)
|
def build_middleware(klass, args, block)
|
||||||
|
@rack_runtime_deprecated = false if klass == Rack::Runtime
|
||||||
|
|
||||||
Middleware.new(klass, args, block)
|
Middleware.new(klass, args, block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index_of(index)
|
||||||
|
raise "ActionDispatch::MiddlewareStack::FakeRuntime can not be referenced in middleware operations" if index == FakeRuntime
|
||||||
|
|
||||||
|
if index == Rack::Runtime && @rack_runtime_deprecated
|
||||||
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
||||||
|
Rack::Runtime is removed from the default middleware stack in Rails
|
||||||
|
and referencing it in middleware operations without adding it back
|
||||||
|
is deprecated and will throw an error in Rails 7.1
|
||||||
|
MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
middlewares.index do |m|
|
||||||
|
m.klass == index || (@rack_runtime_deprecated && m.klass == FakeRuntime && index == Rack::Runtime)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -195,4 +195,27 @@ def test_delete_works
|
|||||||
test "includes a middleware" do
|
test "includes a middleware" do
|
||||||
assert_equal true, @stack.include?(ActionDispatch::MiddlewareStack::Middleware.new(BarMiddleware, nil, nil))
|
assert_equal true, @stack.include?(ActionDispatch::MiddlewareStack::Middleware.new(BarMiddleware, nil, nil))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "referencing Rack::Runtime is deprecated" do
|
||||||
|
@stack.use ActionDispatch::MiddlewareStack::FakeRuntime
|
||||||
|
|
||||||
|
assert_deprecated(/Rack::Runtime is removed/) do
|
||||||
|
@stack.insert_after(Rack::Runtime, BazMiddleware)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "referencing Rack::Runtime is not deprecated if added" do
|
||||||
|
assert_not_deprecated do
|
||||||
|
@stack.use Rack::Runtime
|
||||||
|
@stack.insert_before(Rack::Runtime, BazMiddleware)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "referencing FakeRuntime throws an error" do
|
||||||
|
@stack.use ActionDispatch::MiddlewareStack::FakeRuntime
|
||||||
|
|
||||||
|
assert_raises RuntimeError do
|
||||||
|
@stack.insert_after ActionDispatch::MiddlewareStack::FakeRuntime, BazMiddleware
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -204,7 +204,6 @@ An API application comes with the following middleware by default:
|
|||||||
- `ActionDispatch::Static`
|
- `ActionDispatch::Static`
|
||||||
- `ActionDispatch::Executor`
|
- `ActionDispatch::Executor`
|
||||||
- `ActiveSupport::Cache::Strategy::LocalCache::Middleware`
|
- `ActiveSupport::Cache::Strategy::LocalCache::Middleware`
|
||||||
- `Rack::Runtime`
|
|
||||||
- `ActionDispatch::RequestId`
|
- `ActionDispatch::RequestId`
|
||||||
- `ActionDispatch::RemoteIp`
|
- `ActionDispatch::RemoteIp`
|
||||||
- `Rails::Rack::Logger`
|
- `Rails::Rack::Logger`
|
||||||
|
@ -458,7 +458,7 @@ Ruby version 2.7.0 (x86_64-linux)
|
|||||||
RubyGems version 2.7.3
|
RubyGems version 2.7.3
|
||||||
Rack version 2.0.4
|
Rack version 2.0.4
|
||||||
JavaScript Runtime Node.js (V8)
|
JavaScript Runtime Node.js (V8)
|
||||||
Middleware: Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, ActionDispatch::RemoteIp, Sprockets::Rails::QuietAssets, Rails::Rack::Logger, ActionDispatch::ShowExceptions, WebConsole::Middleware, ActionDispatch::DebugExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
|
Middleware: Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::MethodOverride, ActionDispatch::RequestId, ActionDispatch::RemoteIp, Sprockets::Rails::QuietAssets, Rails::Rack::Logger, ActionDispatch::ShowExceptions, WebConsole::Middleware, ActionDispatch::DebugExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
|
||||||
Application root /home/foobar/commandsapp
|
Application root /home/foobar/commandsapp
|
||||||
Environment development
|
Environment development
|
||||||
Database adapter sqlite3
|
Database adapter sqlite3
|
||||||
|
@ -274,7 +274,6 @@ Every Rails application comes with a standard set of middleware which it uses in
|
|||||||
* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.public_file_server.enabled` is `false`. Set `config.public_file_server.index_name` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.public_file_server.index_name` to `"main"`.
|
* `ActionDispatch::Static` is used to serve static assets. Disabled if `config.public_file_server.enabled` is `false`. Set `config.public_file_server.index_name` if you need to serve a static directory index file that is not named `index`. For example, to serve `main.html` instead of `index.html` for directory requests, set `config.public_file_server.index_name` to `"main"`.
|
||||||
* `ActionDispatch::Executor` allows thread safe code reloading. Disabled if `config.allow_concurrency` is `false`, which causes `Rack::Lock` to be loaded. `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time.
|
* `ActionDispatch::Executor` allows thread safe code reloading. Disabled if `config.allow_concurrency` is `false`, which causes `Rack::Lock` to be loaded. `Rack::Lock` wraps the app in mutex so it can only be called by a single thread at a time.
|
||||||
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
|
* `ActiveSupport::Cache::Strategy::LocalCache` serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
|
||||||
* `Rack::Runtime` sets an `X-Runtime` header, containing the time (in seconds) taken to execute the request.
|
|
||||||
* `Rails::Rack::Logger` notifies the logs that the request has begun. After request is complete, flushes all the logs.
|
* `Rails::Rack::Logger` notifies the logs that the request has begun. After request is complete, flushes all the logs.
|
||||||
* `ActionDispatch::ShowExceptions` rescues any exception returned by the application and renders nice exception pages if the request is local or if `config.consider_all_requests_local` is set to `true`. If `config.action_dispatch.show_exceptions` is set to `false`, exceptions will be raised regardless.
|
* `ActionDispatch::ShowExceptions` rescues any exception returned by the application and renders nice exception pages if the request is local or if `config.consider_all_requests_local` is set to `true`. If `config.action_dispatch.show_exceptions` is set to `false`, exceptions will be raised regardless.
|
||||||
* `ActionDispatch::RequestId` makes a unique X-Request-Id header available to the response and enables the `ActionDispatch::Request#uuid` method. Configurable with `config.action_dispatch.request_id_header`.
|
* `ActionDispatch::RequestId` makes a unique X-Request-Id header available to the response and enables the `ActionDispatch::Request#uuid` method. Configurable with `config.action_dispatch.request_id_header`.
|
||||||
@ -1582,7 +1581,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
|
|||||||
|
|
||||||
* `initialize_logger`: Initializes the logger (an `ActiveSupport::Logger` object) for the application and makes it accessible at `Rails.logger`, provided that no initializer inserted before this point has defined `Rails.logger`.
|
* `initialize_logger`: Initializes the logger (an `ActiveSupport::Logger` object) for the application and makes it accessible at `Rails.logger`, provided that no initializer inserted before this point has defined `Rails.logger`.
|
||||||
|
|
||||||
* `initialize_cache`: If `Rails.cache` isn't set yet, initializes the cache by referencing the value in `config.cache_store` and stores the outcome as `Rails.cache`. If this object responds to the `middleware` method, its middleware is inserted before `Rack::Runtime` in the middleware stack.
|
* `initialize_cache`: If `Rails.cache` isn't set yet, initializes the cache by referencing the value in `config.cache_store` and stores the outcome as `Rails.cache`. If this object responds to the `middleware` method, its middleware is inserted after `ActionDispatch::Executor` in the middleware stack.
|
||||||
|
|
||||||
* `set_clear_dependencies_hook`: This initializer - which runs only if `cache_classes` is set to `false` - uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
|
* `set_clear_dependencies_hook`: This initializer - which runs only if `cache_classes` is set to `false` - uses `ActionDispatch::Callbacks.after` to remove the constants which have been referenced during the request from the object space so that they will be reloaded during the following request.
|
||||||
|
|
||||||
|
@ -107,7 +107,6 @@ use Rack::Sendfile
|
|||||||
use ActionDispatch::Static
|
use ActionDispatch::Static
|
||||||
use ActionDispatch::Executor
|
use ActionDispatch::Executor
|
||||||
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
|
use ActiveSupport::Cache::Strategy::LocalCache::Middleware
|
||||||
use Rack::Runtime
|
|
||||||
use Rack::MethodOverride
|
use Rack::MethodOverride
|
||||||
use ActionDispatch::RequestId
|
use ActionDispatch::RequestId
|
||||||
use ActionDispatch::RemoteIp
|
use ActionDispatch::RemoteIp
|
||||||
@ -175,10 +174,10 @@ Add the following lines to your application configuration:
|
|||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
# config/application.rb
|
# config/application.rb
|
||||||
config.middleware.delete Rack::Runtime
|
config.middleware.delete ActionDispatch::Executor
|
||||||
```
|
```
|
||||||
|
|
||||||
And now if you inspect the middleware stack, you'll find that `Rack::Runtime` is
|
And now if you inspect the middleware stack, you'll find that `ActionDispatch::Executor` is
|
||||||
not a part of it.
|
not a part of it.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -230,10 +229,6 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
|
|||||||
|
|
||||||
* Used for memory caching. This cache is not thread safe.
|
* Used for memory caching. This cache is not thread safe.
|
||||||
|
|
||||||
**`Rack::Runtime`**
|
|
||||||
|
|
||||||
* Sets an X-Runtime header, containing the time (in seconds) taken to execute the request.
|
|
||||||
|
|
||||||
**`Rack::MethodOverride`**
|
**`Rack::MethodOverride`**
|
||||||
|
|
||||||
* Allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PUT and DELETE HTTP method types.
|
* Allows the method to be overridden if `params[:_method]` is set. This is the middleware which supports the PUT and DELETE HTTP method types.
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
* Remove Rack::Runtime from the default middleware stack and deprecate
|
||||||
|
referencing it in middleware operations without adding it back
|
||||||
|
|
||||||
|
*Hartley McGuire*
|
||||||
|
|
||||||
* Allow adding additional authorized hosts in development via `ENV['RAILS_DEVELOPMENT_HOSTS']`
|
* Allow adding additional authorized hosts in development via `ENV['RAILS_DEVELOPMENT_HOSTS']`
|
||||||
|
|
||||||
*Josh Abernathy*, *Debbie Milburn*
|
*Josh Abernathy*, *Debbie Milburn*
|
||||||
|
@ -59,7 +59,7 @@ module Bootstrap
|
|||||||
Rails.cache = ActiveSupport::Cache.lookup_store(*config.cache_store)
|
Rails.cache = ActiveSupport::Cache.lookup_store(*config.cache_store)
|
||||||
|
|
||||||
if Rails.cache.respond_to?(:middleware)
|
if Rails.cache.respond_to?(:middleware)
|
||||||
config.middleware.insert_before(::Rack::Runtime, Rails.cache.middleware)
|
config.middleware.insert_after(ActionDispatch::Executor, Rails.cache.middleware)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -42,7 +42,7 @@ def build_stack
|
|||||||
|
|
||||||
middleware.use ::ActionDispatch::Executor, app.executor
|
middleware.use ::ActionDispatch::Executor, app.executor
|
||||||
|
|
||||||
middleware.use ::Rack::Runtime
|
middleware.use ::ActionDispatch::MiddlewareStack::FakeRuntime
|
||||||
middleware.use ::Rack::MethodOverride unless config.api_only
|
middleware.use ::Rack::MethodOverride unless config.api_only
|
||||||
middleware.use ::ActionDispatch::RequestId, header: config.action_dispatch.request_id_header
|
middleware.use ::ActionDispatch::RequestId, header: config.action_dispatch.request_id_header
|
||||||
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
|
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
|
||||||
|
@ -31,7 +31,7 @@ def app
|
|||||||
"ActionDispatch::Static",
|
"ActionDispatch::Static",
|
||||||
"ActionDispatch::Executor",
|
"ActionDispatch::Executor",
|
||||||
"ActiveSupport::Cache::Strategy::LocalCache",
|
"ActiveSupport::Cache::Strategy::LocalCache",
|
||||||
"Rack::Runtime",
|
"ActionDispatch::MiddlewareStack::FakeRuntime",
|
||||||
"Rack::MethodOverride",
|
"Rack::MethodOverride",
|
||||||
"ActionDispatch::RequestId",
|
"ActionDispatch::RequestId",
|
||||||
"ActionDispatch::RemoteIp",
|
"ActionDispatch::RemoteIp",
|
||||||
@ -66,7 +66,7 @@ def app
|
|||||||
"ActionDispatch::Static",
|
"ActionDispatch::Static",
|
||||||
"ActionDispatch::Executor",
|
"ActionDispatch::Executor",
|
||||||
"ActiveSupport::Cache::Strategy::LocalCache",
|
"ActiveSupport::Cache::Strategy::LocalCache",
|
||||||
"Rack::Runtime",
|
"ActionDispatch::MiddlewareStack::FakeRuntime",
|
||||||
"Rack::MethodOverride",
|
"Rack::MethodOverride",
|
||||||
"ActionDispatch::RequestId",
|
"ActionDispatch::RequestId",
|
||||||
"ActionDispatch::RemoteIp",
|
"ActionDispatch::RemoteIp",
|
||||||
@ -101,7 +101,7 @@ def app
|
|||||||
"ActionDispatch::Static",
|
"ActionDispatch::Static",
|
||||||
"ActionDispatch::Executor",
|
"ActionDispatch::Executor",
|
||||||
"ActiveSupport::Cache::Strategy::LocalCache",
|
"ActiveSupport::Cache::Strategy::LocalCache",
|
||||||
"Rack::Runtime",
|
"ActionDispatch::MiddlewareStack::FakeRuntime",
|
||||||
"ActionDispatch::RequestId",
|
"ActionDispatch::RequestId",
|
||||||
"ActionDispatch::RemoteIp",
|
"ActionDispatch::RemoteIp",
|
||||||
"Rails::Rack::Logger",
|
"Rails::Rack::Logger",
|
||||||
@ -225,19 +225,19 @@ def app
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "can delete a middleware from the stack even if insert_before is added after delete" do
|
test "can delete a middleware from the stack even if insert_before is added after delete" do
|
||||||
add_to_config "config.middleware.delete Rack::Runtime"
|
add_to_config "config.middleware.delete Rack::Head"
|
||||||
add_to_config "config.middleware.insert_before(Rack::Runtime, Rack::Config)"
|
add_to_config "config.middleware.insert_before(Rack::Head, Rack::Config)"
|
||||||
boot!
|
boot!
|
||||||
assert_includes middleware, "Rack::Config"
|
assert_includes middleware, "Rack::Config"
|
||||||
assert_not middleware.include?("Rack::Runtime")
|
assert_not middleware.include?("Rack::Head")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "can delete a middleware from the stack even if insert_after is added after delete" do
|
test "can delete a middleware from the stack even if insert_after is added after delete" do
|
||||||
add_to_config "config.middleware.delete Rack::Runtime"
|
add_to_config "config.middleware.delete Rack::Head"
|
||||||
add_to_config "config.middleware.insert_after(Rack::Runtime, Rack::Config)"
|
add_to_config "config.middleware.insert_after(Rack::Head, Rack::Config)"
|
||||||
boot!
|
boot!
|
||||||
assert_includes middleware, "Rack::Config"
|
assert_includes middleware, "Rack::Config"
|
||||||
assert_not middleware.include?("Rack::Runtime")
|
assert_not middleware.include?("Rack::Head")
|
||||||
end
|
end
|
||||||
|
|
||||||
test "includes exceptions middlewares even if action_dispatch.show_exceptions is disabled" do
|
test "includes exceptions middlewares even if action_dispatch.show_exceptions is disabled" do
|
||||||
@ -275,14 +275,14 @@ def app
|
|||||||
test "Rails.cache does not respond to middleware" do
|
test "Rails.cache does not respond to middleware" do
|
||||||
add_to_config "config.cache_store = :memory_store, { timeout: 10 }"
|
add_to_config "config.cache_store = :memory_store, { timeout: 10 }"
|
||||||
boot!
|
boot!
|
||||||
assert_equal "Rack::Runtime", middleware[5]
|
assert_equal "ActionDispatch::MiddlewareStack::FakeRuntime", middleware[5]
|
||||||
assert_instance_of ActiveSupport::Cache::MemoryStore, Rails.cache
|
assert_instance_of ActiveSupport::Cache::MemoryStore, Rails.cache
|
||||||
end
|
end
|
||||||
|
|
||||||
test "Rails.cache does respond to middleware" do
|
test "Rails.cache does respond to middleware" do
|
||||||
boot!
|
boot!
|
||||||
assert_equal "ActiveSupport::Cache::Strategy::LocalCache", middleware[5]
|
assert_equal "ActiveSupport::Cache::Strategy::LocalCache", middleware[5]
|
||||||
assert_equal "Rack::Runtime", middleware[6]
|
assert_equal "ActionDispatch::MiddlewareStack::FakeRuntime", middleware[6]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "insert middleware before" do
|
test "insert middleware before" do
|
||||||
|
Loading…
Reference in New Issue
Block a user