aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYehuda Katz <wycats@gmail.com>2009-09-12 13:51:15 -0500
committerYehuda Katz <wycats@gmail.com>2009-09-12 13:51:15 -0500
commit7152a4e9a654ccd0b9fefdcf34dc6aac655a727a (patch)
tree1771bdb314f81996173310bbd4da766b2a83f586
parent3180619c0d228812c119e9704ac5956cbcad8614 (diff)
downloadrails-7152a4e9a654ccd0b9fefdcf34dc6aac655a727a.tar.gz
rails-7152a4e9a654ccd0b9fefdcf34dc6aac655a727a.tar.bz2
rails-7152a4e9a654ccd0b9fefdcf34dc6aac655a727a.zip
Add per-controller middleware
-rw-r--r--actionpack/lib/action_controller/metal.rb15
-rw-r--r--actionpack/test/new_base/middleware_test.rb77
2 files changed, 91 insertions, 1 deletions
diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb
index 51fbba3661..296d359391 100644
--- a/actionpack/lib/action_controller/metal.rb
+++ b/actionpack/lib/action_controller/metal.rb
@@ -88,6 +88,16 @@ module ActionController
end
end
+ extlib_inheritable_accessor(:middleware_stack) { ActionDispatch::MiddlewareStack.new }
+
+ def self.use(*args)
+ middleware_stack.use(*args)
+ end
+
+ def self.middleware
+ middleware_stack
+ end
+
# Return a rack endpoint for the given action. Memoize the endpoint, so
# multiple calls into MyController.action will return the same object
# for the same action.
@@ -99,7 +109,10 @@ module ActionController
# Proc:: A rack application
def self.action(name)
@actions ||= {}
- @actions[name.to_s] ||= ActionEndpoint.new(self, name)
+ @actions[name.to_s] ||= begin
+ endpoint = ActionEndpoint.new(self, name)
+ middleware_stack.build(endpoint)
+ end
end
end
end
diff --git a/actionpack/test/new_base/middleware_test.rb b/actionpack/test/new_base/middleware_test.rb
new file mode 100644
index 0000000000..15aef270e2
--- /dev/null
+++ b/actionpack/test/new_base/middleware_test.rb
@@ -0,0 +1,77 @@
+require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
+
+module MiddlewareTest
+ class MyMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ result = @app.call(env)
+ result[1]["Middleware-Test"] = "Success"
+ result[1]["Middleware-Order"] = "First"
+ result
+ end
+ end
+
+ class ExclaimerMiddleware
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ result = @app.call(env)
+ result[1]["Middleware-Order"] << "!"
+ result
+ end
+ end
+
+ class MyController < ActionController::Metal
+ use MyMiddleware
+
+ middleware.insert_before MyMiddleware, ExclaimerMiddleware
+
+ def index
+ self.response_body = "Hello World"
+ end
+ end
+
+ class InheritedController < MyController
+ end
+
+ module MiddlewareTests
+ extend ActiveSupport::Testing::Declarative
+
+ test "middleware that is 'use'd is called as part of the Rack application" do
+ result = @app.call(env_for("/"))
+ assert_equal "Hello World", result[2]
+ assert_equal "Success", result[1]["Middleware-Test"]
+ end
+
+ test "the middleware stack is exposed as 'middleware' in the controller" do
+ result = @app.call(env_for("/"))
+ assert_equal "First!", result[1]["Middleware-Order"]
+ end
+ end
+
+ class TestMiddleware < ActiveSupport::TestCase
+ include MiddlewareTests
+
+ def setup
+ @app = MyController.action(:index)
+ end
+
+ def env_for(url)
+ Rack::MockRequest.env_for(url)
+ end
+ end
+
+ class TestInheritedMiddleware < TestMiddleware
+ def setup
+ @app = InheritedController.action(:index)
+ end
+
+ test "middleware inherits" do
+ end
+ end
+end