aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionwebservice/CHANGELOG2
-rw-r--r--actionwebservice/lib/action_web_service/api.rb3
-rw-r--r--actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb7
-rw-r--r--actionwebservice/test/abstract_dispatcher.rb46
4 files changed, 56 insertions, 2 deletions
diff --git a/actionwebservice/CHANGELOG b/actionwebservice/CHANGELOG
index c243b6a343..7913609587 100644
--- a/actionwebservice/CHANGELOG
+++ b/actionwebservice/CHANGELOG
@@ -1,5 +1,7 @@
*SVN*
+* Allow action_web_service to handle various HTTP methods including GET. Closes #7011. [zackchandler]
+
* Ensure that DispatcherError is being thrown when a malformed request is received. [Kent Sibilev]
* Added support for decimal types. Closes #6676. [Kent Sibilev]
diff --git a/actionwebservice/lib/action_web_service/api.rb b/actionwebservice/lib/action_web_service/api.rb
index 73fb886e6d..d97eb5e6a1 100644
--- a/actionwebservice/lib/action_web_service/api.rb
+++ b/actionwebservice/lib/action_web_service/api.rb
@@ -21,6 +21,9 @@ module ActionWebService # :nodoc:
# Whether to transform the public API method names into camel-cased names
class_inheritable_option :inflect_names, true
+ # By default only HTTP POST requests are processed
+ class_inheritable_option :allowed_http_methods, [ :post ]
+
# Whether to allow ActiveRecord::Base models in <tt>:expects</tt>.
# The default is +false+; you should be aware of the security implications
# of allowing this, and ensure that you don't allow remote callers to
diff --git a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
index 85773a617d..9c16c50248 100644
--- a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
+++ b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb
@@ -37,8 +37,11 @@ module ActionWebService # :nodoc:
module InstanceMethods # :nodoc:
private
def dispatch_web_service_request
- if request.get?
- render_text('GET not supported', '500 GET not supported')
+ method = request.method.to_s.upcase
+ allowed_methods = self.class.web_service_api ? (self.class.web_service_api.allowed_http_methods.dup || []) : [ :post ]
+ allowed_methods.map!{|m| m.to_s.upcase }
+ if !allowed_methods.include?(method)
+ render_text("#{method} not supported", "500 #{method} not supported")
return
end
exception = nil
diff --git a/actionwebservice/test/abstract_dispatcher.rb b/actionwebservice/test/abstract_dispatcher.rb
index 8d7c98a916..c15af41797 100644
--- a/actionwebservice/test/abstract_dispatcher.rb
+++ b/actionwebservice/test/abstract_dispatcher.rb
@@ -426,6 +426,43 @@ module DispatcherCommonTests
assert_match /Web Service Request/, buf
end
+ def test_allowed_http_methods
+ webservice_api = @direct_controller.class.web_service_api
+ original_allowed_http_methods = webservice_api.allowed_http_methods
+
+ # check defaults
+ assert_equal false, http_method_allowed?(:get)
+ assert_equal false, http_method_allowed?(:head)
+ assert_equal false, http_method_allowed?(:put)
+ assert_equal false, http_method_allowed?(:delete)
+ assert_equal false, http_method_allowed?(:trace)
+ assert_equal false, http_method_allowed?(:connect)
+ assert_equal true, http_method_allowed?(:post)
+
+ # allow get and post
+ webservice_api.allowed_http_methods = [ :get, :post ]
+ assert_equal true, http_method_allowed?(:get)
+ assert_equal true, http_method_allowed?(:post)
+
+ # allow get only
+ webservice_api.allowed_http_methods = [ :get ]
+ assert_equal true, http_method_allowed?(:get)
+ assert_equal false, http_method_allowed?(:post)
+
+ # allow delete only
+ webservice_api.allowed_http_methods = [ 'DELETE' ]
+ assert_equal false, http_method_allowed?(:get)
+ assert_equal false, http_method_allowed?(:head)
+ assert_equal false, http_method_allowed?(:post)
+ assert_equal false, http_method_allowed?(:put)
+ assert_equal false, http_method_allowed?(:trace)
+ assert_equal false, http_method_allowed?(:connect)
+ assert_equal true, http_method_allowed?(:delete)
+
+ ensure
+ webservice_api.allowed_http_methods = original_allowed_http_methods
+ end
+
protected
def service_name(container)
raise NotImplementedError
@@ -502,4 +539,13 @@ module DispatcherCommonTests
end
return_value
end
+
+ def http_method_allowed?(method)
+ method = method.to_s.upcase
+ test_request = ActionController::TestRequest.new({ 'action' => 'api' })
+ test_response = ActionController::TestResponse.new
+ test_request.env['REQUEST_METHOD'] = method
+ result = @direct_controller.process(test_request, test_response)
+ result.body =~ /(GET|POST|PUT|DELETE|TRACE|CONNECT) not supported/ ? false : true
+ end
end