aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Olson <technoweenie@gmail.com>2007-11-29 02:08:51 +0000
committerRick Olson <technoweenie@gmail.com>2007-11-29 02:08:51 +0000
commit0a9bc591e78382b221ef5c2f463bac90564b9982 (patch)
treefb4a264ddb46ba16fd04327f6ca27da1aa1a5569
parentab73a988aca073e6ff16cd608df6e2e08808d31c (diff)
downloadrails-0a9bc591e78382b221ef5c2f463bac90564b9982.tar.gz
rails-0a9bc591e78382b221ef5c2f463bac90564b9982.tar.bz2
rails-0a9bc591e78382b221ef5c2f463bac90564b9982.zip
Raise UnknownHttpMethod exception for unknown HTTP methods. Closes #10303 [tarmo]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8235 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--actionpack/CHANGELOG2
-rwxr-xr-xactionpack/lib/action_controller/base.rb2
-rwxr-xr-xactionpack/lib/action_controller/request.rb33
-rw-r--r--actionpack/test/controller/request_test.rb19
4 files changed, 42 insertions, 14 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index eaefdb77fc..0155731943 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
*2.0.0 [RC2]* (November 28th, 2007)
+* Raise UnknownHttpMethod exception for unknown HTTP methods. Closes #10303 [tarmo]
+
* Update to Prototype -r8232. [sam]
* Make sure the optimisation code for routes doesn't get used if :host, :anchor or :port are provided in the hash arguments. [pager, Koz] #10292
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 3193362fc8..b9fd25aa8f 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -85,6 +85,8 @@ module ActionController #:nodoc:
end
end
+ class UnknownHttpMethod < ActionControllerError #:nodoc:
+ end
# Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed
# on request and then either render a template or redirect to another action. An action is defined as a public method
diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb
index 2926ead13a..2e63180f80 100755
--- a/actionpack/lib/action_controller/request.rb
+++ b/actionpack/lib/action_controller/request.rb
@@ -3,6 +3,9 @@ require 'stringio'
require 'strscan'
module ActionController
+ # HTTP methods which are accepted by default.
+ ACCEPTED_HTTP_METHODS = Set.new(%w( get head put post delete ))
+
# CgiRequest and TestRequest provide concrete implementations.
class AbstractRequest
cattr_accessor :relative_url_root
@@ -12,18 +15,24 @@ module ActionController
# such as { 'RAILS_ENV' => 'production' }.
attr_reader :env
+ # The true HTTP request method as a lowercase symbol, such as :get.
+ # UnknownHttpMethod is raised for invalid methods not listed in ACCEPTED_HTTP_METHODS.
+ def request_method
+ @request_method ||= begin
+ method = ((@env['REQUEST_METHOD'] == 'POST' && !parameters[:_method].blank?) ? parameters[:_method].to_s : @env['REQUEST_METHOD']).downcase
+ if ACCEPTED_HTTP_METHODS.include?(method)
+ method.to_sym
+ else
+ raise UnknownHttpMethod, "#{method}, accepted HTTP methods are #{ACCEPTED_HTTP_METHODS.to_a.to_sentence}"
+ end
+ end
+ end
+
# The HTTP request method as a lowercase symbol, such as :get.
# Note, HEAD is returned as :get since the two are functionally
# equivalent from the application's perspective.
def method
- @request_method ||=
- if @env['REQUEST_METHOD'] == 'POST' && !parameters[:_method].blank?
- parameters[:_method].to_s.downcase.to_sym
- else
- @env['REQUEST_METHOD'].downcase.to_sym
- end
-
- @request_method == :head ? :get : @request_method
+ request_method == :head ? :get : request_method
end
# Is this a GET (or HEAD) request? Equivalent to request.method == :get
@@ -33,23 +42,23 @@ module ActionController
# Is this a POST request? Equivalent to request.method == :post
def post?
- method == :post
+ request_method == :post
end
# Is this a PUT request? Equivalent to request.method == :put
def put?
- method == :put
+ request_method == :put
end
# Is this a DELETE request? Equivalent to request.method == :delete
def delete?
- method == :delete
+ request_method == :delete
end
# Is this a HEAD request? request.method sees HEAD as :get, so check the
# HTTP method directly.
def head?
- @env['REQUEST_METHOD'].downcase.to_sym == :head
+ request_method == :head
end
def headers
diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb
index 1ade378739..1ae1f975a0 100644
--- a/actionpack/test/controller/request_test.rb
+++ b/actionpack/test/controller/request_test.rb
@@ -306,11 +306,26 @@ class RequestTest < Test::Unit::TestCase
end
end
+ def test_invalid_http_method_raises_exception
+ set_request_method_to :random_method
+ assert_raises(ActionController::UnknownHttpMethod) do
+ @request.method
+ end
+ end
+
def test_allow_method_hacking_on_post
set_request_method_to :post
- [:get, :put, :delete].each do |method|
+ [:get, :head, :put, :post, :delete].each do |method|
@request.instance_eval { @parameters = { :_method => method } ; @request_method = nil }
- assert_equal method, @request.method
+ assert_equal(method == :head ? :get : method, @request.method)
+ end
+ end
+
+ def test_invalid_method_hacking_on_post_raises_exception
+ set_request_method_to :post
+ @request.instance_eval { @parameters = { :_method => :random_method } ; @request_method = nil }
+ assert_raises(ActionController::UnknownHttpMethod) do
+ @request.method
end
end