Using POST or PUT in REST proxy calls causes SOAP Parse Exception
-----------------------------------------------------------------

                 Key: SYNAPSE-559
                 URL: https://issues.apache.org/jira/browse/SYNAPSE-559
             Project: Synapse
          Issue Type: Bug
    Affects Versions: NIGHTLY
            Reporter: Greg Coulombe


Hello,

I have recently encountered an issue that I think might be a bug in how Synapse 
handles REST requests. I have configured a simple REST service proxy as follows:


<definitions xmlns="http://ws.apache.org/ns/synapse";>
     <proxy name="identity" transports="http" startOnLoad="true">
                <target>
                        <endpoint>
                                <address 
uri="http://localhost:8080/identity/v1"; format="rest"/>
                        </endpoint>
                        <outSequence>
                                <send/>
                        </outSequence>
                </target>
         </proxy>
</definitions>

When I make GET, OPTIONS or DELETE requests to this proxy, the calls succeed as 
expected. If, however, I make POST or PUT requests, I get a SOAP parse 
exception. Here is a sample request:

POST http://localhost:8280/services/identity/idsession
Content-Type: application/x-identity-idsession-v1+xml; charset=UTF-8

<idsession>
...
</idsession>


Here's the stack trace that appears in the synapse console window:

2009-06-22 10:09:00,611 [-] [HttpServerWorker-3] ERROR ServerWorker Error 
processing POST request 
org.apache.axis2.AxisFault: First Element must contain the local name, Envelope 
, but found idsession
        at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
        at 
org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:169)
        at 
org.apache.synapse.transport.nhttp.ServerWorker.processEntityEnclosingMethod(ServerWorker.java:349)
        at 
org.apache.synapse.transport.nhttp.ServerWorker.run(ServerWorker.java:243)
        at 
org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:58)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650)
        at 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675)
        at java.lang.Thread.run(Thread.java:595)
Caused by: org.apache.axiom.soap.SOAPProcessingException: First Element must 
contain the local name, Envelope , but found idsession
        at 
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.constructNode(StAXSOAPModelBuilder.java:267)
        at 
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createOMElement(StAXSOAPModelBuilder.java:214)
        at 
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.createNextOMElement(StAXSOAPModelBuilder.java:196)
        at 
org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:207)
        at 
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.getSOAPEnvelope(StAXSOAPModelBuilder.java:161)
        at 
org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder.<init>(StAXSOAPModelBuilder.java:110)
        at 
org.apache.axis2.builder.BuilderUtil.getSOAPBuilder(BuilderUtil.java:682)
        at 
org.apache.axis2.transport.TransportUtils.createDocumentElement(TransportUtils.java:210)
        at 
org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:140)
        at 
org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:162)
        ... 6 more

I did some investigation to try to get to the bottom of this and it appears 
that the problem is that Axis is looking at the message's content type to 
determine if the resquest is a SOAP request or a REST request. Basically, if 
the content type is "application/soap+xml" then it's a SOAP 1.2 request. If the 
content type is "text/xml" AND the request has a SOAP Action header, then it's 
a SOAP 1.1 request. Finally, the Axis code looks at the content type to see if 
it's REST: 

(from org.apache.axis2.transport.http.HTTPTransportUtils):

public static boolean isRESTRequest(String contentType) {
        return contentType != null &&
               (contentType.indexOf(HTTPConstants.MEDIA_TYPE_APPLICATION_XML) > 
-1 ||
                contentType.indexOf(HTTPConstants.MEDIA_TYPE_X_WWW_FORM) > -1 ||
                
contentType.indexOf(HTTPConstants.MEDIA_TYPE_MULTIPART_FORM_DATA) > -1);
    }

Basically, this code is checking the content type for literal substrings of 
"application/xml" to determine if it's a REST call. In our case, though, the 
substring isn't found because of the "x-identity-idsession-v1" business. So, 
Axis falls through that content type check and treats the request like it's 
SOAP, leading to the parse error.

So, it looks to me like Synapse will only proxy REST calls if they use one of 
those specific content types. Is this the intended behaviour? I'd like to be 
able to specify specific XML content types (like in my example) so that callers 
can know for certain which schemas are legal for which REST calls. Also, I'd 
like to be able to proxy REST services that use non-XML content types - JSON 
comes to mind.

Thanks,

Greg Coulombe

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to