From 8694a79bb2d543a46867454b743c38ce85380e4e Mon Sep 17 00:00:00 2001 From: Leon Breedt Date: Thu, 28 Apr 2005 17:55:34 +0000 Subject: default to using UTF-8 as response encoding for SOAP if none is supplied, but if an encoding is supplied by caller, use that for the response instead (NAKAMURA Hiroshi) git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1245 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/action_web_service/dispatcher/abstract.rb | 10 ++++---- .../dispatcher/action_controller_dispatcher.rb | 2 +- .../lib/action_web_service/protocol/abstract.rb | 4 ++-- .../action_web_service/protocol/soap_protocol.rb | 28 ++++++++++++++++++---- .../action_web_service/protocol/xmlrpc_protocol.rb | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) (limited to 'actionwebservice/lib') diff --git a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb index bec38d8c1c..e60f30a05b 100644 --- a/actionwebservice/lib/action_web_service/dispatcher/abstract.rb +++ b/actionwebservice/lib/action_web_service/dispatcher/abstract.rb @@ -32,7 +32,7 @@ module ActionWebService # :nodoc: else return_value = self.__send__(invocation.api_method.name) end - web_service_create_response(invocation.protocol, invocation.api, invocation.api_method, return_value) + web_service_create_response(invocation.protocol, invocation.protocol_options, invocation.api, invocation.api_method, return_value) end def web_service_delegated_invoke(invocation) @@ -43,13 +43,14 @@ module ActionWebService # :nodoc: if cancellation_reason raise(DispatcherError, "request canceled: #{cancellation_reason}") end - web_service_create_response(invocation.protocol, invocation.api, invocation.api_method, return_value) + web_service_create_response(invocation.protocol, invocation.protocol_options, invocation.api, invocation.api_method, return_value) end def web_service_invocation(request) public_method_name = request.method_name invocation = Invocation.new invocation.protocol = request.protocol + invocation.protocol_options = request.protocol_options invocation.service_name = request.service_name if web_service_dispatching_mode == :layered case invocation.protocol @@ -109,18 +110,19 @@ module ActionWebService # :nodoc: invocation end - def web_service_create_response(protocol, api, api_method, return_value) + def web_service_create_response(protocol, protocol_options, api, api_method, return_value) if api.has_api_method?(api_method.name) return_type = api_method.returns ? api_method.returns[0] : nil return_value = api_method.cast_returns(return_value) else return_type = ActionWebService::SignatureTypes.canonical_signature_entry(return_value.class, 0) end - protocol.encode_response(api_method.public_name + 'Response', return_value, return_type) + protocol.encode_response(api_method.public_name + 'Response', return_value, return_type, protocol_options) end class Invocation # :nodoc: attr_accessor :protocol + attr_accessor :protocol_options attr_accessor :service_name attr_accessor :api attr_accessor :api_method 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 bce3f4e944..55f0e96600 100644 --- a/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb +++ b/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb @@ -85,7 +85,7 @@ module ActionWebService # :nodoc: api_method = request.api_method public_method_name = api_method ? api_method.public_name : request.method_name return_type = ActionWebService::SignatureTypes.canonical_signature_entry(Exception, 0) - response = request.protocol.encode_response(public_method_name + 'Response', exception, return_type) + response = request.protocol.encode_response(public_method_name + 'Response', exception, return_type, request.protocol_options) send_web_service_response(response) else if self.class.web_service_exception_reporting diff --git a/actionwebservice/lib/action_web_service/protocol/abstract.rb b/actionwebservice/lib/action_web_service/protocol/abstract.rb index d8830968d0..3819aa2ade 100644 --- a/actionwebservice/lib/action_web_service/protocol/abstract.rb +++ b/actionwebservice/lib/action_web_service/protocol/abstract.rb @@ -17,7 +17,7 @@ module ActionWebService # :nodoc: request end - def decode_request(raw_request, service_name, protocol_options=nil) + def decode_request(raw_request, service_name, protocol_options={}) end def encode_request(method_name, params, param_types) @@ -26,7 +26,7 @@ module ActionWebService # :nodoc: def decode_response(raw_response) end - def encode_response(method_name, return_value, return_type) + def encode_response(method_name, return_value, return_type, protocol_options={}) end def protocol_client(api, protocol_name, endpoint_uri, options) diff --git a/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb b/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb index b3f1be2ae4..3e5bad0086 100644 --- a/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb +++ b/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb @@ -1,4 +1,5 @@ require 'action_web_service/protocol/soap_protocol/marshaler' +require 'soap/streamHandler' module ActionWebService # :nodoc: module Protocol # :nodoc: @@ -9,6 +10,8 @@ module ActionWebService # :nodoc: end class SoapProtocol < AbstractProtocol # :nodoc: + DefaultEncoding = 'utf-8' + def marshaler @marshaler ||= SoapMarshaler.new end @@ -16,7 +19,11 @@ module ActionWebService # :nodoc: def decode_action_pack_request(action_pack_request) return nil unless soap_action = has_valid_soap_action?(action_pack_request) service_name = action_pack_request.parameters['action'] - protocol_options = { :soap_action => soap_action } + charset = parse_charset(action_pack_request.env['HTTP_CONTENT_TYPE']) + protocol_options = { + :soap_action => soap_action, + :charset => charset + } decode_request(action_pack_request.raw_post, service_name, protocol_options) end @@ -26,8 +33,9 @@ module ActionWebService # :nodoc: request end - def decode_request(raw_request, service_name, protocol_options=nil) - envelope = SOAP::Processor.unmarshal(raw_request) + def decode_request(raw_request, service_name, protocol_options={}) + charset = protocol_options[:charset] || DefaultEncoding + envelope = SOAP::Processor.unmarshal(raw_request, :charset => charset) unless envelope raise ProtocolError, "Failed to parse SOAP request message" end @@ -66,7 +74,7 @@ module ActionWebService # :nodoc: [method_name, return_value] end - def encode_response(method_name, return_value, return_type) + def encode_response(method_name, return_value, return_type, protocol_options={}) if return_type return_binding = marshaler.register_type(return_type) marshaler.annotate_arrays(return_binding, return_value) @@ -93,7 +101,8 @@ module ActionWebService # :nodoc: end end envelope = create_soap_envelope(response) - Response.new(SOAP::Processor.marshal(envelope), 'text/xml; charset=utf-8', return_value) + charset = protocol_options[:charset] || DefaultEncoding + Response.new(SOAP::Processor.marshal(envelope, :charset => charset), "text/xml; charset=#{charset}", return_value) end def protocol_client(api, protocol_name, endpoint_uri, options={}) @@ -121,6 +130,15 @@ module ActionWebService # :nodoc: soap_action end + def parse_charset(content_type) + return DefaultEncoding if content_type.nil? + if /^text\/xml(?:\s*;\s*charset=([^"]+|"[^"]+"))$/i =~ content_type + $1 + else + DefaultEncoding + end + end + def create_soap_envelope(body) header = SOAP::SOAPHeader.new body = SOAP::SOAPBody.new(body) diff --git a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb index af3c1a49f6..d20fe05726 100644 --- a/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb +++ b/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb @@ -34,7 +34,7 @@ module ActionWebService # :nodoc: [nil, XMLRPC::Marshal.load_response(raw_response)] end - def encode_response(method_name, return_value, return_type) + def encode_response(method_name, return_value, return_type, protocol_options={}) return_value = true if return_value.nil? if return_type return_value = value_to_xmlrpc_wire_format(return_value, return_type) -- cgit v1.2.3