diff --git a/actionwebservice/CHANGELOG b/actionwebservice/CHANGELOG index cb55f0d261..7c41b68492 100644 --- a/actionwebservice/CHANGELOG +++ b/actionwebservice/CHANGELOG @@ -1,3 +1,7 @@ +*SVN* + +* Fix that XML-RPC date/time values did not have well-defined behaviour (#2516, #2534). This fix has one caveat, in that we can't support pre-1970 dates from XML-RPC clients. + *0.9.3* (November 7th, 2005) * Upgraded to Action Pack 1.11.0 and Active Record 1.13.0 diff --git a/actionwebservice/lib/action_web_service/casting.rb b/actionwebservice/lib/action_web_service/casting.rb index c9982f13a0..3c0afbe9f9 100644 --- a/actionwebservice/lib/action_web_service/casting.rb +++ b/actionwebservice/lib/action_web_service/casting.rb @@ -1,5 +1,6 @@ require 'time' require 'date' +require 'xmlrpc/datetime' module ActionWebService # :nodoc: module Casting # :nodoc: @@ -58,6 +59,13 @@ module ActionWebService # :nodoc: end def cast_base_type(value, signature_type) # :nodoc: + # This is a work-around for the fact that XML-RPC special-cases DateTime values into its own DateTime type + # in order to support iso8601 dates. This doesn't work too well for us, so we'll convert it into a Time, + # with the caveat that we won't be able to handle pre-1970 dates that are sent to us. + # + # See http://dev.rubyonrails.com/ticket/2516 + value = value.to_time if value.is_a?(XMLRPC::DateTime) + case signature_type.type when :int Integer(value) diff --git a/actionwebservice/test/abstract_dispatcher.rb b/actionwebservice/test/abstract_dispatcher.rb index 94edb213fa..b857e4a957 100644 --- a/actionwebservice/test/abstract_dispatcher.rb +++ b/actionwebservice/test/abstract_dispatcher.rb @@ -62,6 +62,7 @@ module DispatcherTest api_method :test_utf8, :returns => [:string] api_method :hex, :expects => [:base64], :returns => [:string] api_method :unhex, :expects => [:string], :returns => [:base64] + api_method :time, :expects => [:time], :returns => [:time] end class VirtualAPI < ActionWebService::API::Base @@ -260,6 +261,10 @@ module DispatcherTest return [s].pack("H*") end + def time(t) + t + end + protected def alwaysfail(method_name, params) @before_filter_called = true @@ -295,6 +300,8 @@ module DispatcherCommonTests assert(result[1].is_a?(DispatcherTest::Person)) assert_equal("cafe", do_method_call(@direct_controller, 'Hex', "\xca\xfe")) assert_equal("\xca\xfe", do_method_call(@direct_controller, 'Unhex', "cafe")) + time = Time.gm(1998, "Feb", 02, 15, 12, 01) + assert_equal(time, do_method_call(@direct_controller, 'Time', time)) end def test_direct_entrypoint