DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14636>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=14636

SOAPAction MIME header set through SAAJ not being passed on

           Summary: SOAPAction MIME header set through SAAJ not being passed
                    on
           Product: Axis
           Version: 1.0-rc1
          Platform: PC
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Basic Architecture
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


I am continuing with development of demonstration SOAP code that uses the SAAJ
API for portability as described in previous bug report 14175 and have
uncovered another incompatability between Axis RC1 and the XML Summer Pack
from java.sun.com.

The problem is that, under the Axis implementation of SAAJ, creating a
SOAPAction MIME header in a client message doesn't result in a SOAPAction
MIME header actually appearing in the message sent over http. I have
verified this using TCPMon.

What my code does is to create a javax.xml.soap.SOAPMessage through the
javax.xml.soap.MessageFactory and its Axis subclass
org.apache.axis.soap.MessageFactoryImpl. From the SOAPMessage I obtain the
javax.xml.soap.MimeHeaders by calling getMimeHeaders(). I then add a
SOAPAction MIME header by calling addHeader(). To send the message I use
the javx.xml.soap.SOAPConnectionFactory to get a connection and then use
the call() method. To reiterate, this works fine in the XML Summer Pack but
not in Axis.

Looking into the problem a bit further, the connection actually appears
to be an instance of org.apache.axis.soap.SOAPConnectionImpl in which the
call() method consists of the following code.

    public SOAPMessage call(SOAPMessage request, Object endpoint)
        throws SOAPException {
        if(closed){
            throw new
SOAPException(org.apache.axis.utils.JavaUtils.getMessage("connectionClosed00
"));
        }
        try {
            Call call = new Call(endpoint.toString());

((org.apache.axis.Message)request).setMessageContext(call.getMessageContext(
));
            SOAPEnvelope env =
((org.apache.axis.Message)request).getSOAPEnvelope();
            call.invoke(env);
            return call.getResponseMessage();
        } catch (java.net.MalformedURLException mue){
            throw new SOAPException(mue);
        } catch (org.apache.axis.AxisFault af){
            throw new SOAPException(af);
        } catch (java.rmi.RemoteException re){
            throw new SOAPException(re);
        }
    }

In the above code only the SOAPEnvelope is passed to the locally created
Call instance. The MIME headers, being accessible only through the
SOAPMessage, are left behind.

It looks like a fix for this that passes all potential MIME headers that
might have been set up could be very involved (i.e. requiring a change to the
MessageContext) and require that some http transport specific knowledge (i.e.
MIME headers) be placed in higher layers. For an easier fix it
shouldn't be too tricky to add specific support for the SOAPAction MIME
header by adding the following three lines before call.invoke(env) above.

String soapActionURI = checkForSOAPActionHeader(request);
if (soapActionURI != null)
    call.setSOAPActionURI(soapActionURI);


and add the following method to the class too.

/** Checks whether the request has an associated SOAPAction MIME header
 * and returns its value.
 * @param request the message to check
 * @return the value of any associated SOAPAction MIME header or null
 * if there is no such header.
 */
private String checkForSOAPActionHeader(SOAPMessage request)
{
    MIMEHeaders hdrs = request.getMimeHeaders();
    if (hdrs != null)
    {
        String[] saHdrs = hdrs.getHeader("SOAPAction") ;
        if (saHdrs != null && saHdrs.length > 1)
            return saHdrs[0];
    }
    return null;
}

Obviously this is a bit of a kludge and you'll need to decide how faithfully
you want to implement the API however not passing a SOAPAction is going to
cause a lot of problems.

Chris

Reply via email to