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
This commit is contained in:
Rick Olson 2007-11-29 02:08:51 +00:00
parent ab73a988ac
commit 0a9bc591e7
4 changed files with 42 additions and 14 deletions

@ -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

@ -85,6 +85,8 @@ def initialize(message = nil)
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

@ -3,6 +3,9 @@
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 @@ class AbstractRequest
# 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 @@ def get?
# 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

@ -306,11 +306,26 @@ def test_symbolized_request_methods
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