Client 가 PHP 환경이라면 SOAP 호출을 위하여 NuSOAP을 많이 사용한다. nusoap을 이용하여 SOAP Client를 만들때 WSDL을 이용하지 않고 만들고 actionWebService를 이용하여 만들어진 rails의 SOAP 메소드를 호출하게 되면 다음과 같은 에러가 나타난다.
ActionWebService::Dispatcher::DispatcherError (Malformed SOAP or XML-RPC protocol message):
trace에 보면 dispatcher/action_controller_dispatcher.rb 에서 나타는 것이고 이 원인은
dispatcher/action_controller_dispatcher.rb의 48라인의
begin
ws_request = discover_web_service_request(request)
rescue Exception => e
exception = e
end
에서 ws_request가 nil이라서 발생하는 현상이다. discover_web_service_request는 protocol/discovery.rb 에 정의 되어 있으며
SOAP 요청의 경우 soap_protocol.rb 의 decode_action_pack_request 를 호출한다. decode_action_pack_request 함수에서는 함수 entry에 다음의 코드가 있는데
return nil unless soap_action = has_valid_soap_action?(action_pack_request)
has_valid_soap_action함수에서 nil이 리턴되어 decode_action_pack_request가 nil을 리턴하게 되고 이에 따라 ws_request가 nil이 된다.
W3C SOAP 문서에는 다음과 같은 내용이 나온다.
"The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request."
"The presence and content of the SOAPAction header field can be used by servers such as firewalls to appropriately filter SOAP request messages in HTTP. The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI. No value means that there is no indication of the intent of the message."
문서에는 client가 HTTP_SOAPACTION을 설정하도록 되어 있으나 "" 로 empty일 경우에는 Request-URI에 SOAP message의 intent가 정의 된다고 하였다. nuSOAP의 경우가 이런 경우이고
따라서 HTTP_SOAPACTION의 내용을 soap_action으로 하되 empty 일 경우에는 Request-URI를 action_action으로 해야 다른 클라이언트와 호환성이 보장이 된다는 것이다.
이에 따라 nusoap을 지원하기 위하여 soap_protocol.rb의 has_valid_soap_action을 다음과 같이 수정한다.
이제 HTTP_SOAPACTION환경을 헤더에 설정하지 않는 클라이언트를 지원하게 되었다.