diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_dispatch.rb | 1 | ||||
-rwxr-xr-x | actionpack/lib/action_dispatch/http/request.rb | 12 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/head.rb | 18 | ||||
-rw-r--r-- | actionpack/test/abstract_unit.rb | 2 | ||||
-rw-r--r-- | actionpack/test/controller/integration_test.rb | 13 | ||||
-rw-r--r-- | actionpack/test/dispatch/request_test.rb | 4 |
6 files changed, 42 insertions, 8 deletions
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index ad6d54b6a2..f6d693d6f0 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -43,6 +43,7 @@ module ActionDispatch autoload_under 'middleware' do autoload :Callbacks autoload :Cascade + autoload :Head autoload :ParamsParser autoload :Rescue autoload :ShowExceptions diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 6e8a5dcb8a..3d0aab8a06 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -35,7 +35,8 @@ module ActionDispatch # <tt>:get</tt>. If the request \method is not listed in the HTTP_METHODS # constant above, an UnknownHttpMethod exception is raised. def request_method - HTTP_METHOD_LOOKUP[super] || raise(ActionController::UnknownHttpMethod, "#{super}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}") + method = env["rack.methodoverride.original_method"] || env["REQUEST_METHOD"] + HTTP_METHOD_LOOKUP[method] || raise(ActionController::UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}") end # Returns the HTTP request \method used for action processing as a @@ -43,7 +44,8 @@ module ActionDispatch # method returns <tt>:get</tt> for a HEAD request because the two are # functionally equivalent from the application's perspective.) def method - request_method == :head ? :get : request_method + method = env["REQUEST_METHOD"] + HTTP_METHOD_LOOKUP[method] || raise(ActionController::UnknownHttpMethod, "#{method}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}") end # Is this a GET (or HEAD) request? Equivalent to <tt>request.method == :get</tt>. @@ -53,17 +55,17 @@ module ActionDispatch # Is this a POST request? Equivalent to <tt>request.method == :post</tt>. def post? - request_method == :post + method == :post end # Is this a PUT request? Equivalent to <tt>request.method == :put</tt>. def put? - request_method == :put + method == :put end # Is this a DELETE request? Equivalent to <tt>request.method == :delete</tt>. def delete? - request_method == :delete + method == :delete end # Is this a HEAD request? Since <tt>request.method</tt> sees HEAD as <tt>:get</tt>, diff --git a/actionpack/lib/action_dispatch/middleware/head.rb b/actionpack/lib/action_dispatch/middleware/head.rb new file mode 100644 index 0000000000..56e2d2f2a8 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/head.rb @@ -0,0 +1,18 @@ +module ActionDispatch + class Head + def initialize(app) + @app = app + end + + def call(env) + if env["REQUEST_METHOD"] == "HEAD" + env["REQUEST_METHOD"] = "GET" + env["rack.methodoverride.original_method"] = "HEAD" + status, headers, body = @app.call(env) + [status, headers, []] + else + @app.call(env) + end + end + end +end diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 3e631d45df..f26542b31e 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -91,7 +91,7 @@ class ActionController::IntegrationTest < ActiveSupport::TestCase middleware.use "ActionDispatch::ShowExceptions" middleware.use "ActionDispatch::Callbacks" middleware.use "ActionDispatch::ParamsParser" - middleware.use "Rack::Head" + middleware.use "ActionDispatch::Head" }.build(routes || ActionController::Routing::Routes) end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 624b14e69b..683ab5236c 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -254,6 +254,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest render :text => "Created", :status => 201 end + def method + render :text => "method: #{request.method}" + end + def cookie_monster cookies["cookie_1"] = nil cookies["cookie_3"] = "chocolate" @@ -379,6 +383,14 @@ class IntegrationProcessTest < ActionController::IntegrationTest head '/post' assert_equal 201, status assert_equal "", body + + get '/get/method' + assert_equal 200, status + assert_equal "method: get", body + + head '/get/method' + assert_equal 200, status + assert_equal "", body end end @@ -391,6 +403,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest with_routing do |set| set.draw do |map| match ':action', :to => ::IntegrationProcessTest::IntegrationController + get 'get/:action', :to => ::IntegrationProcessTest::IntegrationController end yield end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index b62df9a6b2..cb95ecea50 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -319,7 +319,7 @@ class RequestTest < ActiveSupport::TestCase end test "allow method hacking on post" do - [:get, :head, :options, :put, :post, :delete].each do |method| + [:get, :options, :put, :post, :delete].each do |method| request = stub_request "REQUEST_METHOD" => method.to_s.upcase assert_equal(method == :head ? :get : method, request.method) end @@ -341,7 +341,7 @@ class RequestTest < ActiveSupport::TestCase end test "head masquerading as get" do - request = stub_request 'REQUEST_METHOD' => 'HEAD' + request = stub_request 'REQUEST_METHOD' => 'GET', "rack.methodoverride.original_method" => "HEAD" assert_equal :get, request.method assert request.get? assert request.head? |