Skip to content

Commit

Permalink
Add internal middleware stack to Dispatcher
Browse files Browse the repository at this point in the history
  config.middleware.use Rack::Cache
  • Loading branch information
josh committed Dec 1, 2008
1 parent 3c07a88 commit 06ed8e4
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
1 change: 1 addition & 0 deletions actionpack/lib/action_controller.rb
Expand Up @@ -57,6 +57,7 @@ def self.load_all!
autoload :Integration, 'action_controller/integration'
autoload :IntegrationTest, 'action_controller/integration'
autoload :Layout, 'action_controller/layout'
autoload :MiddlewareStack, 'action_controller/middleware_stack'
autoload :MimeResponds, 'action_controller/mime_responds'
autoload :PolymorphicRoutes, 'action_controller/polymorphic_routes'
autoload :RackRequest, 'action_controller/rack_process'
Expand Down
8 changes: 8 additions & 0 deletions actionpack/lib/action_controller/dispatcher.rb
Expand Up @@ -85,6 +85,9 @@ def failsafe_logger
end
end

cattr_accessor :middleware
self.middleware = MiddlewareStack.new

cattr_accessor :error_file_path
self.error_file_path = Rails.public_path if defined?(Rails.public_path)

Expand All @@ -93,6 +96,7 @@ def failsafe_logger

def initialize(output = $stdout, request = nil, response = nil)
@output, @request, @response = output, request, response
@app = @@middleware.build(lambda { |env| self._call(env) })
end

def dispatch_unlocked
Expand Down Expand Up @@ -127,6 +131,10 @@ def dispatch_cgi(cgi, session_options)
end

def call(env)
@app.call(env)
end

def _call(env)
@request = RackRequest.new(env)
@response = RackResponse.new(@request)
dispatch
Expand Down
42 changes: 42 additions & 0 deletions actionpack/lib/action_controller/middleware_stack.rb
@@ -0,0 +1,42 @@
module ActionController
class MiddlewareStack < Array
class Middleware
attr_reader :klass, :args, :block

def initialize(klass, *args, &block)
@klass = klass.is_a?(Class) ? klass : klass.to_s.constantize
@args = args
@block = block
end

def ==(middleware)
case middleware
when Middleware
klass == middleware.klass
when Class
klass == middleware
else
klass == middleware.to_s.constantize
end
end

def inspect
str = @klass.to_s
@args.each { |arg| str += ", #{arg.inspect}" }
str
end

def build(app)
klass.new(app, *args, &block)
end
end

def use(*args, &block)
push(Middleware.new(*args, &block))
end

def build(app)
reverse.inject(app) { |a, e| e.build(a) }
end
end
end
5 changes: 5 additions & 0 deletions railties/lib/initializer.rb
Expand Up @@ -881,6 +881,11 @@ def to_prepare(&callback)
end
end

def middleware
require 'action_controller'
ActionController::Dispatcher.middleware
end

def builtin_directories
# Include builtins only in the development environment.
(environment == 'development') ? Dir["#{RAILTIES_PATH}/builtin/*/"] : []
Expand Down
7 changes: 7 additions & 0 deletions railties/lib/tasks/middleware.rake
@@ -0,0 +1,7 @@
desc 'Prints out your Rack middleware stack'
task :middleware => :environment do
ActionController::Dispatcher.middleware.each do |middleware|
puts "use #{middleware.inspect}"
end
puts "run ActionController::Dispatcher.new"
end

1 comment on commit 06ed8e4

@stefanoc
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s funny that so many people are saying that you’re doing the “embrace & extend” thing with Rack, yet nobody noticed this commit (event though it was featured prominently in a recent “This week on Edge Rails” post" ).

Please sign in to comment.