mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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
This commit is contained in:
parent
896fea505b
commit
8694a79bb2
8 changed files with 51 additions and 14 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
* Fix that generated WSDL was not using relative_url_root for base URI #1210 [Shugo Maeda]
|
||||
|
||||
* Use UTF-8 encoding for SOAP responses #1211 [Shugo Maeda]
|
||||
* Use UTF-8 encoding by default for SOAP responses, but if an encoding is supplied by caller, use that for the response #1211 [Shugo Maeda, NAKAMURA Hiroshi]
|
||||
|
||||
* If the WSDL was retrieved over HTTPS, use HTTPS URLs in the WSDL too
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -379,6 +379,12 @@ module DispatcherCommonTests
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def update_request(ap_request)
|
||||
end
|
||||
|
||||
def check_response(ap_response)
|
||||
end
|
||||
|
||||
def do_method_call(container, public_method_name, *params)
|
||||
request_env = {}
|
||||
mode = container.web_service_dispatching_mode
|
||||
|
@ -416,9 +422,11 @@ module DispatcherCommonTests
|
|||
# puts body
|
||||
ap_request = @protocol.encode_action_pack_request(service_name, public_method_name, body, :request_class => ActionController::TestRequest)
|
||||
ap_request.env.update(request_env)
|
||||
update_request(ap_request)
|
||||
ap_response = ActionController::TestResponse.new
|
||||
container.process(ap_request, ap_response)
|
||||
# puts ap_response.body
|
||||
check_response(ap_response)
|
||||
public_method_name, return_value = @protocol.decode_response(ap_response.body)
|
||||
unless is_exception?(return_value) || virtual
|
||||
return_value = method.cast_returns(return_value)
|
||||
|
|
|
@ -68,6 +68,15 @@ class TC_DispatcherActionControllerSoap < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
protected
|
||||
def update_request(ap_request)
|
||||
ap_request.env.update('HTTP_CONTENT_TYPE' => 'text/xml; charset=us-ascii')
|
||||
end
|
||||
|
||||
def check_response(ap_response)
|
||||
assert_equal 'text/xml; charset=us-ascii', ap_response.headers['Content-Type']
|
||||
assert_match /xml.*?encoding="us-ascii"/, ap_response.body
|
||||
end
|
||||
|
||||
def exception_message(soap_fault_exception)
|
||||
soap_fault_exception.detail.cause.message
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue