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]