Author: dkulp
Date: Mon Mar 31 17:29:26 2008
New Revision: 643228
URL: http://svn.apache.org/viewvc?rev=643228&view=rev
Log:
[CXF-1491] Split out fault detection to interceptor run later and keep all
nodes of soap body so verification can be accurate.
Added:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
(with props)
Modified:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/SoapBindingFactory.java
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/ReadHeaderInterceptorTest.java
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptorTest.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/logical/LogicalMessageImpl.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
Modified:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/SoapBindingFactory.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/SoapBindingFactory.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/SoapBindingFactory.java
(original)
+++
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/SoapBindingFactory.java
Mon Mar 31 17:29:26 2008
@@ -38,6 +38,7 @@
import org.apache.cxf.binding.AbstractBindingFactory;
import org.apache.cxf.binding.Binding;
+import org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor;
import org.apache.cxf.binding.soap.interceptor.EndpointSelectionInterceptor;
import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
import org.apache.cxf.binding.soap.interceptor.RPCInInterceptor;
@@ -366,6 +367,7 @@
sb.getInInterceptors().add(new SoapHeaderInterceptor());
sb.getInInterceptors().add(new ReadHeadersInterceptor(getBus()));
+ sb.getInInterceptors().add(new CheckFaultInterceptor());
sb.getInInterceptors().add(new MustUnderstandInterceptor());
sb.getOutInterceptors().add(new SoapPreProtocolOutInterceptor());
sb.getOutInterceptors().add(new SoapOutInterceptor(getBus()));
@@ -647,6 +649,7 @@
// processing. But, if you've disabled message processing, you
// probably aren't going to use this feature.
newMO.getBindingInterceptors().add(new
ReadHeadersInterceptor(getBus()));
+ newMO.getBindingInterceptors().add(new CheckFaultInterceptor());
// Add in a default selection interceptor
newMO.getRoutingInterceptors().add(new
EndpointSelectionInterceptor());
Added:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java?rev=643228&view=auto
==============================================================================
---
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
(added)
+++
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
Mon Mar 31 17:29:26 2008
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.binding.soap.interceptor;
+
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.phase.Phase;
+
+public class CheckFaultInterceptor extends AbstractSoapInterceptor {
+ private static final Logger LOG =
LogUtils.getL7dLogger(CheckFaultInterceptor.class);
+
+ public CheckFaultInterceptor() {
+ this(Phase.POST_PROTOCOL);
+ }
+ public CheckFaultInterceptor(String phase) {
+ super(phase);
+ }
+
+ public void handleMessage(SoapMessage message) {
+ XMLStreamReader xmlReader = message.getContent(XMLStreamReader.class);
+ if (xmlReader == null) {
+ return;
+ }
+ try {
+ // advance to first tag.
+ int x = xmlReader.getEventType();
+ while (x != XMLStreamReader.START_ELEMENT
+ && x != XMLStreamReader.END_ELEMENT
+ && xmlReader.hasNext()) {
+ x = xmlReader.next();
+ }
+ } catch (XMLStreamException e) {
+ throw new SoapFault(new Message("XML_STREAM_EXC", LOG), e,
+ message.getVersion().getSender());
+ }
+ if (message.getVersion().getFault().equals(xmlReader.getName())) {
+ Endpoint ep = message.getExchange().get(Endpoint.class);
+ message.getInterceptorChain().abort();
+ if (ep.getInFaultObserver() != null) {
+ ep.getInFaultObserver().onMessage(message);
+ }
+ }
+ }
+}
Propchange:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/CheckFaultInterceptor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified:
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
(original)
+++
incubator/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ReadHeadersInterceptor.java
Mon Mar 31 17:29:26 2008
@@ -44,14 +44,12 @@
import org.apache.cxf.common.i18n.Message;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.databinding.DataBinding;
-import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.headers.HeaderManager;
import org.apache.cxf.headers.HeaderProcessor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.staxutils.PartialXMLStreamReader;
import org.apache.cxf.staxutils.StaxUtils;
-import static org.apache.cxf.message.Message.DECOUPLED_CHANNEL_MESSAGE;
public class ReadHeadersInterceptor extends AbstractSoapInterceptor {
private static final Logger LOG =
LogUtils.getL7dLogger(ReadHeadersInterceptor.class);
@@ -172,28 +170,17 @@
}
}
}
-
- // advance just past body.
- xmlReader.nextTag();
- if
(message.getVersion().getFault().equals(xmlReader.getName())) {
- Endpoint ep = message.getExchange().get(Endpoint.class);
- if (!isDecoupled(message)) {
- message.getInterceptorChain().abort();
- if (ep.getInFaultObserver() != null) {
- ep.getInFaultObserver().onMessage(message);
- }
- } else {
-
message.getExchange().put("deferred.fault.observer.notification", Boolean.TRUE);
- }
+ //advance to just outside the <soap:body> opening tag, but not
+ //to the nextTag as that may skip over white space that is
+ //important to keep for ws-security signature digests and stuff
+ int i = xmlReader.next();
+ while (i == XMLStreamReader.NAMESPACE
+ || i == XMLStreamReader.ATTRIBUTE) {
+ i = xmlReader.next();
}
}
} catch (XMLStreamException e) {
throw new SoapFault(new Message("XML_STREAM_EXC", LOG), e,
message.getVersion().getSender());
}
- }
-
- private boolean isDecoupled(SoapMessage message) {
- Boolean decoupled = (Boolean)message.get(DECOUPLED_CHANNEL_MESSAGE);
- return decoupled != null && decoupled.booleanValue();
}
}
Modified:
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/ReadHeaderInterceptorTest.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/ReadHeaderInterceptorTest.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/ReadHeaderInterceptorTest.java
(original)
+++
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/ReadHeaderInterceptorTest.java
Mon Mar 31 17:29:26 2008
@@ -34,6 +34,7 @@
import org.apache.cxf.BusFactory;
import org.apache.cxf.attachment.AttachmentImpl;
import org.apache.cxf.attachment.AttachmentUtil;
+import org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor;
import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.StaxInInterceptor;
@@ -52,6 +53,7 @@
rhi = new ReadHeadersInterceptor(BusFactory.getDefaultBus(), "phase1");
chain.add(rhi);
+ chain.add(new CheckFaultInterceptor("phase2"));
}
@Test
Modified:
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptorTest.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptorTest.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptorTest.java
(original)
+++
incubator/cxf/trunk/rt/bindings/soap/src/test/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptorTest.java
Mon Mar 31 17:29:26 2008
@@ -34,6 +34,7 @@
import org.apache.cxf.binding.soap.Soap12;
import org.apache.cxf.binding.soap.TestBase;
import org.apache.cxf.binding.soap.TestUtil;
+import org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor;
import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.StaxInInterceptor;
@@ -56,6 +57,8 @@
saajIntc = new SAAJInInterceptor("phase2");
chain.add(saajIntc);
+
+ chain.add(new CheckFaultInterceptor("phase3"));
}
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/logical/LogicalMessageImpl.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/logical/LogicalMessageImpl.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/logical/LogicalMessageImpl.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/logical/LogicalMessageImpl.java
Mon Mar 31 17:29:26 2008
@@ -70,54 +70,12 @@
Source source = null;
Service.Mode mode =
msgContext.getWrappedMessage().getExchange().get(Service.Mode.class);
- Message message = msgContext.getWrappedMessage();
if (mode != null) {
//Dispatch/Provider case
- Source obj = message.getContent(Source.class);
- if (message instanceof SoapMessage) {
- // StreamSource may only be used once, need to make a copy
- if (obj instanceof StreamSource) {
- try {
- CachedOutputStream cos = new CachedOutputStream();
- Transformer transformer = XMLUtils.newTransformer();
- transformer.transform(obj, new StreamResult(cos));
-
- obj = new StreamSource(cos.getInputStream());
- message.setContent(Source.class, new
StreamSource(cos.getInputStream()));
- cos.close();
- } catch (Exception e) {
- throw new Fault(e);
- }
- }
-
- if (mode == Service.Mode.PAYLOAD) {
- source = (Source)obj;
- } else {
- try {
- CachedOutputStream cos = new CachedOutputStream();
- Transformer transformer = XMLUtils.newTransformer();
-
- transformer.transform(obj, new StreamResult(cos));
- InputStream in = cos.getInputStream();
- SOAPMessage msg = initSOAPMessage(in);
- source = new
DOMSource(((SOAPMessage)msg).getSOAPBody().getFirstChild());
- in.close();
- cos.close();
- } catch (Exception e) {
- throw new Fault(e);
- }
- }
- } else if (message instanceof XMLMessage) {
- if (obj != null) {
- source = (Source)obj;
- } else if (message.getContent(DataSource.class) != null) {
- throw new Fault(new org.apache.cxf.common.i18n.Message(
-
"GETPAYLOAD_OF_DATASOURCE_NOT_VALID_XMLHTTPBINDING",
- LOG));
- }
- }
+ source = handleDispatchProviderCase(mode);
} else {
+ Message message = msgContext.getWrappedMessage();
source = message.getContent(Source.class);
if (source == null) {
// need to convert
@@ -125,7 +83,11 @@
XMLStreamReader reader = null;
if (msg != null) {
try {
- source = new
DOMSource(msg.getSOAPBody().getFirstChild());
+ Node node = msg.getSOAPBody().getFirstChild();
+ while (node != null && !(node instanceof Element)) {
+ node = node.getNextSibling();
+ }
+ source = new DOMSource(node);
reader = StaxUtils.createXMLStreamReader(source);
} catch (SOAPException e) {
throw new Fault(e);
@@ -172,6 +134,55 @@
}
}
+ return source;
+ }
+
+ private Source handleDispatchProviderCase(Service.Mode mode) {
+ Source source = null;
+ Message message = msgContext.getWrappedMessage();
+ Source obj = message.getContent(Source.class);
+ if (message instanceof SoapMessage) {
+ // StreamSource may only be used once, need to make a copy
+ if (obj instanceof StreamSource) {
+ try {
+ CachedOutputStream cos = new CachedOutputStream();
+ Transformer transformer = XMLUtils.newTransformer();
+ transformer.transform(obj, new StreamResult(cos));
+
+ obj = new StreamSource(cos.getInputStream());
+ message.setContent(Source.class, new
StreamSource(cos.getInputStream()));
+ cos.close();
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ }
+
+ if (mode == Service.Mode.PAYLOAD) {
+ source = (Source)obj;
+ } else {
+ try {
+ CachedOutputStream cos = new CachedOutputStream();
+ Transformer transformer = XMLUtils.newTransformer();
+
+ transformer.transform(obj, new StreamResult(cos));
+ InputStream in = cos.getInputStream();
+ SOAPMessage msg = initSOAPMessage(in);
+ source = new
DOMSource(((SOAPMessage)msg).getSOAPBody().getFirstChild());
+ in.close();
+ cos.close();
+ } catch (Exception e) {
+ throw new Fault(e);
+ }
+ }
+ } else if (message instanceof XMLMessage) {
+ if (obj != null) {
+ source = (Source)obj;
+ } else if (message.getContent(DataSource.class) != null) {
+ throw new Fault(new org.apache.cxf.common.i18n.Message(
+
"GETPAYLOAD_OF_DATASOURCE_NOT_VALID_XMLHTTPBINDING",
+ LOG));
+ }
+ }
return source;
}
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/handler/soap/SOAPHandlerInterceptor.java
Mon Mar 31 17:29:26 2008
@@ -278,10 +278,12 @@
if (body == null) {
return null;
}
- Iterator<SOAPElement> it = CastUtils.cast(body.getChildElements());
- if (it != null && it.hasNext()) {
- SOAPElement el = it.next();
- return el.getElementQName();
+ org.w3c.dom.Node nd = body.getFirstChild();
+ while (nd != null && !(nd instanceof org.w3c.dom.Element)) {
+ nd = nd.getNextSibling();
+ }
+ if (nd != null) {
+ return new QName(nd.getNamespaceURI(), nd.getLocalName());
}
} catch (SOAPException e) {
//ignore, nothing we can do
Modified:
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java?rev=643228&r1=643227&r2=643228&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
(original)
+++
incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/DispatchInDatabindingInterceptor.java
Mon Mar 31 17:29:26 2008
@@ -55,6 +55,7 @@
import org.apache.cxf.databinding.DataReader;
import org.apache.cxf.databinding.source.NodeDataReader;
import org.apache.cxf.databinding.source.XMLStreamDataReader;
+import org.apache.cxf.endpoint.Endpoint;
//import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils;
@@ -130,10 +131,20 @@
SOAPMessage soapMessage = newSOAPMessage(is,
(SoapMessage)message);
SOAPFault soapFault = soapMessage.getSOAPBody().getFault();
if (soapFault != null) {
+ Endpoint ep = message.getExchange().get(Endpoint.class);
+ message.getInterceptorChain().abort();
+ if (ep.getInFaultObserver() != null) {
+ message.setContent(SOAPMessage.class, soapMessage);
+ ep.getInFaultObserver().onMessage(message);
+ return;
+ }
+
+ /*
Fault fault = new Fault(new
org.apache.cxf.common.i18n.Message(soapFault.getFaultString(),
LOG));
fault.setFaultCode(soapFault.getFaultCodeAsQName());
message.setContent(Exception.class, fault);
+ */
}
PostDispatchSOAPHandlerInterceptor postSoap = new
PostDispatchSOAPHandlerInterceptor();