提交 27409436 编写于 作者: J José Valim 提交者: Mikel Lindsaar

Remove the laziness from the middleware stack.

上级 27939bd7
...@@ -3,49 +3,15 @@ ...@@ -3,49 +3,15 @@
module ActionDispatch module ActionDispatch
class MiddlewareStack < Array class MiddlewareStack < Array
class Middleware class Middleware
def self.new(klass, *args, &block)
if klass.is_a?(self)
klass
else
super
end
end
attr_reader :args, :block attr_reader :args, :block
def initialize(klass, *args, &block) def initialize(klass, *args, &block)
@klass = klass @klass, @args, @block = klass, args, block
options = args.extract_options!
if options.has_key?(:if)
@conditional = options.delete(:if)
else
@conditional = true
end
args << options unless options.empty?
@args = args
@block = block
end end
def klass def klass
if @klass.respond_to?(:new) return @klass if @klass.respond_to?(:new)
@klass @klass = ActiveSupport::Inflector.constantize(@klass.to_s)
elsif @klass.respond_to?(:call)
@klass.call
else
ActiveSupport::Inflector.constantize(@klass.to_s)
end
end
def active?
return false unless klass
if @conditional.respond_to?(:call)
@conditional.call
else
@conditional
end
end end
def ==(middleware) def ==(middleware)
...@@ -58,7 +24,7 @@ def ==(middleware) ...@@ -58,7 +24,7 @@ def ==(middleware)
if lazy_compare?(@klass) && lazy_compare?(middleware) if lazy_compare?(@klass) && lazy_compare?(middleware)
normalize(@klass) == normalize(middleware) normalize(@klass) == normalize(middleware)
else else
klass.name == middleware.to_s klass.name == normalize(middleware.to_s)
end end
end end
end end
...@@ -68,25 +34,18 @@ def inspect ...@@ -68,25 +34,18 @@ def inspect
end end
def build(app) def build(app)
if block klass.new(app, *args, &block)
klass.new(app, *build_args, &block)
else
klass.new(app, *build_args)
end
end end
private private
def lazy_compare?(object)
object.is_a?(String) || object.is_a?(Symbol)
end
def normalize(object) def lazy_compare?(object)
object.to_s.strip.sub(/^::/, '') object.is_a?(String) || object.is_a?(Symbol)
end end
def build_args def normalize(object)
Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg } object.to_s.strip.sub(/^::/, '')
end end
end end
def initialize(*args, &block) def initialize(*args, &block)
...@@ -119,15 +78,14 @@ def use(*args, &block) ...@@ -119,15 +78,14 @@ def use(*args, &block)
end end
def active def active
find_all { |middleware| middleware.active? } ActiveSupport::Deprecation.warn "All middlewares in the chaing are active since the laziness " <<
"was removed from the middleware stack", caller
end end
def build(app = nil, &blk) def build(app = nil, &blk)
app ||= blk app ||= blk
raise "MiddlewareStack#build requires an app" unless app raise "MiddlewareStack#build requires an app" unless app
reverse.inject(app) { |a, e| e.build(a) }
active.reverse.inject(app) { |a, e| e.build(a) }
end end
end end
end end
...@@ -66,29 +66,14 @@ def setup ...@@ -66,29 +66,14 @@ def setup
assert_equal BazMiddleware, @stack[0].klass assert_equal BazMiddleware, @stack[0].klass
end end
test "active returns all only enabled middleware" do
assert_no_difference "@stack.active.size" do
assert_difference "@stack.size" do
@stack.use BazMiddleware, :if => lambda { false }
end
end
end
test "lazy evaluates middleware class" do test "lazy evaluates middleware class" do
assert_difference "@stack.size" do assert_difference "@stack.size" do
@stack.use lambda { BazMiddleware } @stack.use "MiddlewareStackTest::BazMiddleware"
end end
assert_equal BazMiddleware, @stack.last.klass assert_equal BazMiddleware, @stack.last.klass
end end
test "lazy evaluates middleware arguments" do test "lazy compares so unloaded constants are not loaded" do
assert_difference "@stack.size" do
@stack.use BazMiddleware, lambda { :foo }
end
assert_equal [:foo], @stack.last.send(:build_args)
end
test "lazy compares so unloaded constants can be loaded" do
@stack.use "UnknownMiddleware" @stack.use "UnknownMiddleware"
@stack.use :"MiddlewareStackTest::BazMiddleware" @stack.use :"MiddlewareStackTest::BazMiddleware"
assert @stack.include?("::MiddlewareStackTest::BazMiddleware") assert @stack.include?("::MiddlewareStackTest::BazMiddleware")
......
...@@ -124,7 +124,10 @@ def load_generators ...@@ -124,7 +124,10 @@ def load_generators
end end
def app def app
@app ||= config.middleware.build(routes) @app ||= begin
config.middleware = config.middleware.merge_into(default_middleware_stack)
config.middleware.build(routes)
end
end end
def call(env) def call(env)
...@@ -148,6 +151,29 @@ def initializers ...@@ -148,6 +151,29 @@ def initializers
protected protected
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
middleware.use ::ActionDispatch::Static, paths.public.to_a.first if config.serve_static_assets
middleware.use ::Rack::Lock if !config.allow_concurrency
middleware.use ::Rack::Runtime
middleware.use ::Rails::Rack::Logger
middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local if config.action_dispatch.show_exceptions
middleware.use ::ActionDispatch::RemoteIp, config.action_dispatch.ip_spoofing_check, config.action_dispatch.trusted_proxies
middleware.use ::Rack::Sendfile, config.action_dispatch.x_sendfile_header
middleware.use ::ActionDispatch::Callbacks, !config.cache_classes
middleware.use ::ActionDispatch::Cookies
if config.session_store
middleware.use config.session_store, config.session_options
middleware.use ::ActionDispatch::Flash
end
middleware.use ::ActionDispatch::ParamsParser
middleware.use ::Rack::MethodOverride
middleware.use ::ActionDispatch::Head
end
end
def initialize_tasks def initialize_tasks
require "rails/tasks" require "rails/tasks"
task :environment do task :environment do
......
...@@ -47,7 +47,7 @@ module Bootstrap ...@@ -47,7 +47,7 @@ module Bootstrap
silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) } silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(config.cache_store) }
if RAILS_CACHE.respond_to?(:middleware) if RAILS_CACHE.respond_to?(:middleware)
config.middleware.insert_after(:"Rack::Lock", RAILS_CACHE.middleware) config.middleware.insert_before("Rack::Runtime", RAILS_CACHE.middleware)
end end
end end
end end
......
...@@ -9,7 +9,7 @@ class Configuration < ::Rails::Engine::Configuration ...@@ -9,7 +9,7 @@ class Configuration < ::Rails::Engine::Configuration
attr_accessor :allow_concurrency, :cache_classes, :cache_store, attr_accessor :allow_concurrency, :cache_classes, :cache_store,
:encoding, :consider_all_requests_local, :dependency_loading, :encoding, :consider_all_requests_local, :dependency_loading,
:filter_parameters, :log_level, :logger, :filter_parameters, :log_level, :logger, :middleware,
:plugins, :preload_frameworks, :reload_engines, :reload_plugins, :plugins, :preload_frameworks, :reload_engines, :reload_plugins,
:secret_token, :serve_static_assets, :session_options, :secret_token, :serve_static_assets, :session_options,
:time_zone, :whiny_nils :time_zone, :whiny_nils
...@@ -25,6 +25,7 @@ def initialize(*) ...@@ -25,6 +25,7 @@ def initialize(*)
@session_store = :cookie_store @session_store = :cookie_store
@session_options = {} @session_options = {}
@time_zone = "UTC" @time_zone = "UTC"
@middleware = app_middleware
end end
def encoding=(value) def encoding=(value)
...@@ -41,10 +42,6 @@ def encoding=(value) ...@@ -41,10 +42,6 @@ def encoding=(value)
end end
end end
def middleware
@middleware ||= app_middleware.merge_into(default_middleware_stack)
end
def paths def paths
@paths ||= begin @paths ||= begin
paths = super paths = super
...@@ -134,27 +131,6 @@ def session_store(*args) ...@@ -134,27 +131,6 @@ def session_store(*args)
@session_options = args.shift || {} @session_options = args.shift || {}
end end
end end
protected
def default_middleware_stack
ActionDispatch::MiddlewareStack.new.tap do |middleware|
middleware.use('::ActionDispatch::Static', lambda { paths.public.to_a.first }, :if => lambda { serve_static_assets })
middleware.use('::Rack::Lock', :if => lambda { !allow_concurrency })
middleware.use('::Rack::Runtime')
middleware.use('::Rails::Rack::Logger')
middleware.use('::ActionDispatch::ShowExceptions', lambda { consider_all_requests_local }, :if => lambda { action_dispatch.show_exceptions })
middleware.use('::ActionDispatch::RemoteIp', lambda { action_dispatch.ip_spoofing_check }, lambda { action_dispatch.trusted_proxies })
middleware.use('::Rack::Sendfile', lambda { action_dispatch.x_sendfile_header })
middleware.use('::ActionDispatch::Callbacks', lambda { !cache_classes })
middleware.use('::ActionDispatch::Cookies')
middleware.use(lambda { session_store }, lambda { session_options })
middleware.use('::ActionDispatch::Flash', :if => lambda { session_store })
middleware.use('::ActionDispatch::ParamsParser')
middleware.use('::Rack::MethodOverride')
middleware.use('::ActionDispatch::Head')
end
end
end end
end end
end end
desc 'Prints out your Rack middleware stack' desc 'Prints out your Rack middleware stack'
task :middleware => :environment do task :middleware => :environment do
Rails.configuration.middleware.active.each do |middleware| Rails.configuration.middleware.each do |middleware|
puts "use #{middleware.inspect}" puts "use #{middleware.inspect}"
end end
puts "run #{Rails::Application.instance.class.name}.routes" puts "run #{Rails::Application.instance.class.name}.routes"
......
...@@ -164,7 +164,7 @@ def boot! ...@@ -164,7 +164,7 @@ def boot!
end end
def middleware def middleware
AppTemplate::Application.middleware.active.map(&:klass).map(&:name) AppTemplate::Application.middleware.map(&:klass).map(&:name)
end end
def remote_ip(env = {}) def remote_ip(env = {})
......
...@@ -7,6 +7,6 @@ class IntegrationTestGeneratorTest < Rails::Generators::TestCase ...@@ -7,6 +7,6 @@ class IntegrationTestGeneratorTest < Rails::Generators::TestCase
def test_integration_test_skeleton_is_created def test_integration_test_skeleton_is_created
run_generator run_generator
assert_file "test/integration/integration_test.rb", /class IntegrationTest < ActionController::IntegrationTest/ assert_file "test/integration/integration_test.rb", /class IntegrationTest < ActionDispatch::IntegrationTest/
end end
end end
...@@ -7,6 +7,6 @@ class PerformanceTestGeneratorTest < Rails::Generators::TestCase ...@@ -7,6 +7,6 @@ class PerformanceTestGeneratorTest < Rails::Generators::TestCase
def test_performance_test_skeleton_is_created def test_performance_test_skeleton_is_created
run_generator run_generator
assert_file "test/performance/performance_test.rb", /class PerformanceTest < ActionController::PerformanceTest/ assert_file "test/performance/performance_test.rb", /class PerformanceTest < ActionDispatch::PerformanceTest/
end end
end end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册