aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeon Breedt <bitserf@gmail.com>2005-04-16 19:29:42 +0000
committerLeon Breedt <bitserf@gmail.com>2005-04-16 19:29:42 +0000
commit7f32666924493fb21a72ad56fb2cf4091aad4141 (patch)
tree8abd737c826d3441a4a9df69c1f7afbc76d599c0
parent6ee06ebec6814576b16f6438c89fb53d557305c2 (diff)
downloadrails-7f32666924493fb21a72ad56fb2cf4091aad4141.tar.gz
rails-7f32666924493fb21a72ad56fb2cf4091aad4141.tar.bz2
rails-7f32666924493fb21a72ad56fb2cf4091aad4141.zip
Remove a cause of casting failure for XML-RPC by ignoring structure members not
defined in the target type, and perform more sanity checks to make more obvious what the resolution should be when neglecting to provide a valid signature or failing to attach an API to a service implementation class. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1171 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--actionwebservice/CHANGELOG2
-rw-r--r--actionwebservice/lib/action_web_service/api.rb3
-rw-r--r--actionwebservice/lib/action_web_service/casting.rb4
-rw-r--r--actionwebservice/lib/action_web_service/dispatcher/abstract.rb3
-rw-r--r--actionwebservice/lib/action_web_service/support/signature_types.rb3
-rw-r--r--actionwebservice/test/abstract_dispatcher.rb9
6 files changed, 22 insertions, 2 deletions
diff --git a/actionwebservice/CHANGELOG b/actionwebservice/CHANGELOG
index 6cb8d5c15e..f9aaf225a6 100644
--- a/actionwebservice/CHANGELOG
+++ b/actionwebservice/CHANGELOG
@@ -1,5 +1,7 @@
*0.7.0* (Unreleased)
+* When casting structured types, don't try to send obj.name= unless obj responds to it, causes casting to be less likely to fail for XML-RPC
+
* Add scaffolding via ActionController::Base.web_service_scaffold for quick testing using a web browser
* ActionWebService::API::Base#api_methods now returns a hash containing ActionWebService::API::Method objects
diff --git a/actionwebservice/lib/action_web_service/api.rb b/actionwebservice/lib/action_web_service/api.rb
index 0ff1671144..87ac1b164e 100644
--- a/actionwebservice/lib/action_web_service/api.rb
+++ b/actionwebservice/lib/action_web_service/api.rb
@@ -58,6 +58,9 @@ module ActionWebService # :nodoc:
# [<tt>:returns</tt>] Signature for the method return value
# [<tt>:expects_and_returns</tt>] Signature for both input parameters and return value
def api_method(name, options={})
+ unless options.is_a?(Hash)
+ raise(ActionWebServiceError, "Expected a Hash for options")
+ end
validate_options([:expects, :returns, :expects_and_returns], options.keys)
if options[:expects_and_returns]
expects = options[:expects_and_returns]
diff --git a/actionwebservice/lib/action_web_service/casting.rb b/actionwebservice/lib/action_web_service/casting.rb
index 88462d8cc9..b30de2d4c4 100644
--- a/actionwebservice/lib/action_web_service/casting.rb
+++ b/actionwebservice/lib/action_web_service/casting.rb
@@ -93,12 +93,12 @@ module ActionWebService # :nodoc:
value.each_pair do |name, val|
type = klass.respond_to?(:member_type) ? klass.member_type(name) : nil
val = cast(val, type) if type
- obj.__send__("#{name}=", val)
+ obj.__send__("#{name}=", val) if obj.respond_to?(name)
end
elsif value.respond_to?(:attributes)
signature_type.each_member do |name, type|
val = value.__send__(name)
- obj.__send__("#{name}=", cast(val, type))
+ obj.__send__("#{name}=", cast(val, type)) if obj.respond_to?(name)
end
else
raise CastingError, "Don't know how to cast #{value.class} to #{signature_type.type_class}"
diff --git a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
index 1d8715a8f7..bec38d8c1c 100644
--- a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
+++ b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb
@@ -73,6 +73,9 @@ module ActionWebService # :nodoc:
invocation.service = web_service_object(invocation.service_name)
invocation.api = invocation.service.class.web_service_api
end
+ if invocation.api.nil?
+ raise(DispatcherError, "no API attached to #{invocation.service.class}")
+ end
invocation.protocol.register_api(invocation.api)
request.api = invocation.api
if invocation.api.has_public_api_method?(public_method_name)
diff --git a/actionwebservice/lib/action_web_service/support/signature_types.rb b/actionwebservice/lib/action_web_service/support/signature_types.rb
index a7ee2fc773..65f63d16e1 100644
--- a/actionwebservice/lib/action_web_service/support/signature_types.rb
+++ b/actionwebservice/lib/action_web_service/support/signature_types.rb
@@ -2,6 +2,9 @@ module ActionWebService # :nodoc:
module SignatureTypes # :nodoc:
def canonical_signature(signature)
return nil if signature.nil?
+ unless signature.is_a?(Array)
+ raise(ActionWebServiceError, "Expected signature to be an Array")
+ end
i = -1
signature.map{ |spec| canonical_signature_entry(spec, i += 1) }
end
diff --git a/actionwebservice/test/abstract_dispatcher.rb b/actionwebservice/test/abstract_dispatcher.rb
index c3d256d71a..0fe7525c48 100644
--- a/actionwebservice/test/abstract_dispatcher.rb
+++ b/actionwebservice/test/abstract_dispatcher.rb
@@ -344,6 +344,15 @@ module DispatcherCommonTests
assert !person.equal?(@direct_controller.struct_pass_value)
end
assert_equal person, do_method_call(@direct_controller, 'HashStructReturn')[0]
+ result = do_method_call(@direct_controller, 'StructPass', {'id' => '1', 'name' => 'test', 'nonexistent_attribute' => 'value'})
+ case @protocol
+ when ActionWebService::Protocol::Soap::SoapProtocol
+ assert_equal(person, @direct_controller.struct_pass_value)
+ assert !person.equal?(@direct_controller.struct_pass_value)
+ when ActionWebService::Protocol::XmlRpc::XmlRpcProtocol
+ assert_equal(person, @direct_controller.struct_pass_value)
+ assert !person.equal?(@direct_controller.struct_pass_value)
+ end
end
def test_logging