Author: sergeyb Date: Wed Mar 14 13:47:05 2012 New Revision: 1300544 URL: http://svn.apache.org/viewvc?rev=1300544&view=rev Log: Merged revisions 1300407,1300410,1300418,1300533 via svnmerge from https://svn.apache.org/repos/asf/cxf/branches/2.5.x-fixes
................ r1300407 | sergeyb | 2012-03-13 23:23:50 +0000 (Tue, 13 Mar 2012) | 9 lines Merged revisions 1298470 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1298470 | sergeyb | 2012-03-08 16:57:36 +0000 (Thu, 08 Mar 2012) | 1 line Initial commit for addressing the collision issue ........ ................ r1300410 | sergeyb | 2012-03-13 23:35:13 +0000 (Tue, 13 Mar 2012) | 9 lines Merged revisions 1298832 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1298832 | sergeyb | 2012-03-09 14:04:08 +0000 (Fri, 09 Mar 2012) | 1 line [CXF-4172] Some refactoring plus working around the lack of streaming support in Jettison ........ ................ r1300418 | sergeyb | 2012-03-13 23:46:00 +0000 (Tue, 13 Mar 2012) | 13 lines Merged revisions 1299086,1299747 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1299086 | sergeyb | 2012-03-09 22:45:36 +0000 (Fri, 09 Mar 2012) | 1 line [CXF-4172] Completing the messy workaround for Jettison, most of this code will be hidden in the next Jettison release ........ r1299747 | sergeyb | 2012-03-12 17:24:22 +0000 (Mon, 12 Mar 2012) | 1 line [CXF-4172] Adding tests for Source and Document ........ ................ r1300533 | sergeyb | 2012-03-14 13:11:18 +0000 (Wed, 14 Mar 2012) | 9 lines Merged revisions 1300530 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1300530 | sergeyb | 2012-03-14 12:58:17 +0000 (Wed, 14 Mar 2012) | 1 line [CXF-4172] Making the names of context properties shorter similar to the attachment properties ........ ................ Added: cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java - copied unchanged from r1300533, cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java - copied unchanged from r1300533, cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java - copied unchanged from r1300533, cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java cxf/branches/2.4.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java - copied unchanged from r1300533, cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java Modified: cxf/branches/2.4.x-fixes/ (props changed) cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceImpl.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Propchange: cxf/branches/2.4.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Mar 14 13:47:05 2012 @@ -1,2 +1,2 @@ -/cxf/branches/2.5.x-fixes:1299092,1299637,1299725,1300270,1300343,1300536 -/cxf/trunk:1298830,1299635,1299682,1300342,1300518 +/cxf/branches/2.5.x-fixes:1299092,1299637,1299725,1300270,1300343,1300407-1300533,1300536 +/cxf/trunk:1298470,1298830,1298832,1299086,1299635,1299682,1299747,1300342,1300518,1300530 Propchange: cxf/branches/2.4.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Modified: cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java (original) +++ cxf/branches/2.4.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java Wed Mar 14 13:47:05 2012 @@ -81,7 +81,11 @@ import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.helpers.XMLUtils; public final class StaxUtils { - + private static final String INNER_ELEMENT_COUNT_SYSTEM_PROP = + "org.apache.cxf.staxutils.innerElementCountThreshold"; + private static final String INNER_ELEMENT_LEVEL_SYSTEM_PROP = + "org.apache.cxf.staxutils.innerElementLevelThreshold"; + private static final Logger LOG = LogUtils.getL7dLogger(StaxUtils.class); private static final BlockingQueue<XMLInputFactory> NS_AWARE_INPUT_FACTORY_POOL; @@ -114,8 +118,7 @@ public final class StaxUtils { NS_AWARE_INPUT_FACTORY_POOL = new LinkedBlockingQueue<XMLInputFactory>(i); OUTPUT_FACTORY_POOL = new LinkedBlockingQueue<XMLOutputFactory>(i); try { - String s = System.getProperty("org.apache.cxf.staxutils.innerElementLevelThreshold", - "-1"); + String s = System.getProperty(INNER_ELEMENT_LEVEL_SYSTEM_PROP, "-1"); innerElementLevelThreshold = Integer.parseInt(s); } catch (Throwable t) { innerElementLevelThreshold = -1; @@ -124,8 +127,7 @@ public final class StaxUtils { innerElementLevelThreshold = -1; } try { - String s = System.getProperty("org.apache.cxf.staxutils.innerElementCountThreshold", - "-1"); + String s = System.getProperty(INNER_ELEMENT_COUNT_SYSTEM_PROP, "-1"); innerElementCountThreshold = Integer.parseInt(s); } catch (Throwable t) { innerElementCountThreshold = -1; @@ -529,7 +531,10 @@ public final class StaxUtils { } break; case XMLStreamConstants.CHARACTERS: - writer.writeCharacters(reader.getText()); + String s = reader.getText(); + if (s != null) { + writer.writeCharacters(s); + } break; case XMLStreamConstants.COMMENT: writer.writeComment(reader.getText()); @@ -610,7 +615,7 @@ public final class StaxUtils { // We need this check because namespace writing works // different on Woodstox and the RI. if (writeElementNS) { - if (prefix == null || prefix.length() == 0) { + if (prefix.length() == 0) { writer.writeDefaultNamespace(uri); writer.setDefaultNamespace(uri); } else { @@ -767,7 +772,7 @@ public final class StaxUtils { String value = attr.getNodeValue(); if (attns == null || attns.length() == 0) { writer.writeAttribute(name, value); - } else if (attrPrefix == null || attrPrefix.length() == 0) { + } else if (attrPrefix.length() == 0) { writer.writeAttribute(attns, name, value); } else { writer.writeAttribute(attrPrefix, attns, name, value); @@ -1022,12 +1027,12 @@ public final class StaxUtils { stack.push(parent); if (isThreshold && innerElementLevelThreshold != -1 && stack.size() >= innerElementLevelThreshold) { - throw new RuntimeException("reach the innerElementLevelThreshold:" + throw new DepthExceededStaxException("reach the innerElementLevelThreshold:" + innerElementLevelThreshold); } if (isThreshold && innerElementCountThreshold != -1 && elementCount >= innerElementCountThreshold) { - throw new RuntimeException("reach the innerElementCountThreshold:" + throw new DepthExceededStaxException("reach the innerElementCountThreshold:" + innerElementCountThreshold); } parent = e; @@ -1395,14 +1400,14 @@ public final class StaxUtils { } else { writer.writeStartElement(localName); } - Iterator it = start.getNamespaces(); + Iterator<XMLEvent> it = CastUtils.cast(start.getNamespaces()); while (it != null && it.hasNext()) { - writeEvent((XMLEvent)it.next(), writer); + writeEvent(it.next(), writer); } - it = start.getAttributes(); + it = CastUtils.cast(start.getAttributes()); while (it != null && it.hasNext()) { - writeAttributeEvent((Attribute)it.next(), writer); + writeAttributeEvent(it.next(), writer); } } private static void writeAttributeEvent(XMLEvent event, XMLStreamWriter writer) Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceImpl.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceImpl.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceImpl.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/JAXRSServiceImpl.java Wed Mar 14 13:47:05 2012 @@ -29,6 +29,7 @@ import java.util.concurrent.Executor; import javax.ws.rs.core.Response; import javax.xml.namespace.QName; +import javax.xml.transform.Source; import org.apache.cxf.common.util.PackageUtils; import org.apache.cxf.configuration.Configurable; @@ -150,7 +151,7 @@ public class JAXRSServiceImpl extends Ab private void createMessagePartInfo(OperationInfo oi, Class<?> type, QName qname, Method m, boolean input) { - if (type == void.class) { + if (type == void.class || Source.class.isAssignableFrom(type)) { return; } if (InjectionUtils.isPrimitive(type) || Response.class == type) { Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Wed Mar 14 13:47:05 2012 @@ -18,7 +18,6 @@ */ package org.apache.cxf.jaxrs.client; -import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -300,7 +299,7 @@ public class WebClient extends AbstractC */ public Response form(Map<String, List<Object>> values) { type(MediaType.APPLICATION_FORM_URLENCODED); - return doInvoke("POST", values, null, InputStream.class, InputStream.class); + return doInvoke("POST", values, null, Response.class, Response.class); } /** @@ -310,7 +309,7 @@ public class WebClient extends AbstractC */ public Response form(Form form) { type(MediaType.APPLICATION_FORM_URLENCODED); - return doInvoke("POST", form.getData(), null, InputStream.class, InputStream.class); + return doInvoke("POST", form.getData(), null, Response.class, Response.class); } /** @@ -675,7 +674,8 @@ public class WebClient extends AbstractC } headers.putSingle(HttpHeaders.CONTENT_TYPE, ct); } - if (responseClass != null && headers.getFirst(HttpHeaders.ACCEPT) == null) { + if (responseClass != null && responseClass != Response.class + && headers.getFirst(HttpHeaders.ACCEPT) == null) { headers.putSingle(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_TYPE.toString()); } resetResponse(); Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Wed Mar 14 13:47:05 2012 @@ -72,7 +72,9 @@ import org.apache.cxf.jaxrs.utils.Resour import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.Message; import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.staxutils.DepthRestrictingStreamReader; import org.apache.cxf.staxutils.DepthXMLStreamReader; +import org.apache.cxf.staxutils.DocumentDepthProperties; import org.apache.cxf.staxutils.transform.TransformUtils; public abstract class AbstractJAXBProvider extends AbstractConfigurableProvider @@ -116,6 +118,7 @@ public abstract class AbstractJAXBProvid private boolean validateOutput; private boolean validateBeforeWrite; private ValidationEventHandler eventHandler; + private DocumentDepthProperties depthProperties; public void setValidationHandler(ValidationEventHandler handler) { eventHandler = handler; @@ -575,8 +578,6 @@ public abstract class AbstractJAXBProvid this.inDropElements = dropElementsSet; } - - public void setAttributesToElements(boolean value) { this.attributesToElements = value; } @@ -607,6 +608,42 @@ public abstract class AbstractJAXBProvid true); } + protected XMLStreamReader createDepthReaderIfNeeded(XMLStreamReader reader, InputStream is) { + DocumentDepthProperties props = getDepthProperties(); + if (props != null && props.isEffective()) { + reader = TransformUtils.createNewReaderIfNeeded(reader, is); + return new DepthRestrictingStreamReader(reader, props); + } + return reader; + } + + protected DocumentDepthProperties getDepthProperties() { + if (depthProperties != null) { + return depthProperties; + } + if (getContext() != null) { + String totalElementCountStr = (String)getContext().getContextualProperty( + DocumentDepthProperties.TOTAL_ELEMENT_COUNT); + String innerElementCountStr = (String)getContext().getContextualProperty( + DocumentDepthProperties.INNER_ELEMENT_COUNT); + String elementLevelStr = (String)getContext().getContextualProperty( + DocumentDepthProperties.INNER_ELEMENT_LEVEL); + if (totalElementCountStr != null || innerElementCountStr != null || elementLevelStr != null) { + try { + int totalElementCount = totalElementCountStr != null + ? Integer.valueOf(totalElementCountStr) : -1; + int elementLevel = elementLevelStr != null ? Integer.valueOf(elementLevelStr) : -1; + int innerElementCount = innerElementCountStr != null + ? Integer.valueOf(innerElementCountStr) : -1; + return new DocumentDepthProperties(totalElementCount, elementLevel, innerElementCount); + } catch (Exception ex) { + throw new WebApplicationException(ex); + } + } + } + return null; + } + public void setValidateBeforeWrite(boolean validateBeforeWrite) { this.validateBeforeWrite = validateBeforeWrite; } @@ -615,6 +652,10 @@ public abstract class AbstractJAXBProvid this.validateOutput = validateOutput; } + public void setDepthProperties(DocumentDepthProperties depthProperties) { + this.depthProperties = depthProperties; + } + @XmlRootElement protected static class CollectionWrapper { Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java Wed Mar 14 13:47:05 2012 @@ -147,10 +147,12 @@ public class FormEncodingProvider implem if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) { MultipartBody body = AttachmentUtils.getMultipartBody(mc, attachmentDir, attachmentThreshold, attachmentMaxSize); - FormUtils.populateMapFromMultipart(params, body, decode); + FormUtils.populateMapFromMultipart(params, body, PhaseInterceptorChain.getCurrentMessage(), + decode); } else { String enc = HttpUtils.getEncoding(mt, "UTF-8"); - FormUtils.populateMapFromString(params, + FormUtils.populateMapFromString(params, + PhaseInterceptorChain.getCurrentMessage(), FormUtils.readBody(is, enc), enc, decode, Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Wed Mar 14 13:47:05 2012 @@ -68,6 +68,7 @@ import org.apache.cxf.jaxrs.utils.JAXBUt import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.Attachment; import org.apache.cxf.message.Message; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.staxutils.transform.TransformUtils; @@ -184,6 +185,8 @@ public class JAXBElementProvider extends } catch (JAXBException e) { handleJAXBException(e, true); + } catch (DepthExceededStaxException e) { + throw new WebApplicationException(413); } catch (WebApplicationException e) { throw e; } catch (Exception e) { @@ -223,6 +226,7 @@ public class JAXBElementProvider extends } reader = createTransformReaderIfNeeded(reader, is); + reader = createDepthReaderIfNeeded(reader, is); if (InjectionUtils.isSupportedCollectionOrArray(type)) { return new JAXBCollectionWrapperReader(TransformUtils.createNewReaderIfNeeded(reader, is)); } else { Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Wed Mar 14 13:47:05 2012 @@ -65,6 +65,7 @@ import org.apache.cxf.jaxrs.utils.Inject import org.apache.cxf.jaxrs.utils.JAXBUtils; import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.staxutils.W3CDOMStreamWriter; import org.codehaus.jettison.mapped.Configuration; @@ -232,6 +233,8 @@ public class JSONProvider extends Abstra } catch (JAXBException e) { handleJAXBException(e, true); + } catch (DepthExceededStaxException e) { + throw new WebApplicationException(413); } catch (XMLStreamException e) { throw new WebApplicationException(e); } catch (WebApplicationException e) { @@ -251,12 +254,15 @@ public class JSONProvider extends Abstra protected XMLStreamReader createReader(Class<?> type, InputStream is) throws Exception { + XMLStreamReader reader = null; if (BADGER_FISH_CONVENTION.equals(convention)) { - return JSONUtils.createBadgerFishReader(is); + reader = JSONUtils.createBadgerFishReader(is); } else { - XMLStreamReader reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap); - return createTransformReaderIfNeeded(reader, is); + reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap, getDepthProperties()); } + reader = createTransformReaderIfNeeded(reader, is); + + return reader; } protected InputStream getInputStream(Class<Object> cls, Type type, InputStream is) throws Exception { Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONUtils.java Wed Mar 14 13:47:05 2012 @@ -18,6 +18,8 @@ */ package org.apache.cxf.jaxrs.provider; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -40,14 +42,22 @@ import javax.xml.stream.XMLStreamWriter; import org.apache.cxf.common.WSDLConstants; import org.apache.cxf.common.util.StringUtils; import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.DepthXMLStreamReader; +import org.apache.cxf.staxutils.DocumentDepthProperties; import org.apache.cxf.staxutils.transform.IgnoreNamespacesWriter; +import org.codehaus.jettison.AbstractXMLInputFactory; import org.codehaus.jettison.AbstractXMLStreamWriter; import org.codehaus.jettison.badgerfish.BadgerFishXMLInputFactory; import org.codehaus.jettison.badgerfish.BadgerFishXMLOutputFactory; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.codehaus.jettison.json.JSONTokener; import org.codehaus.jettison.mapped.Configuration; import org.codehaus.jettison.mapped.MappedNamespaceConvention; import org.codehaus.jettison.mapped.MappedXMLInputFactory; +import org.codehaus.jettison.mapped.MappedXMLStreamReader; import org.codehaus.jettison.mapped.MappedXMLStreamWriter; import org.codehaus.jettison.mapped.TypeConverter; @@ -134,13 +144,228 @@ public final class JSONUtils { public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType, ConcurrentHashMap<String, String> namespaceMap) throws Exception { + return createStreamReader(is, readXsiType, namespaceMap, null); + } + + public static XMLStreamReader createStreamReader(InputStream is, boolean readXsiType, + ConcurrentHashMap<String, String> namespaceMap, + DocumentDepthProperties depthProps) throws Exception { if (readXsiType) { namespaceMap.putIfAbsent(XSI_URI, XSI_PREFIX); } - MappedXMLInputFactory factory = new MappedXMLInputFactory(namespaceMap); + XMLInputFactory factory = depthProps != null + ? new JettisonMappedReaderFactory(namespaceMap, depthProps) + : new MappedXMLInputFactory(namespaceMap); return new JettisonReader(namespaceMap, factory.createXMLStreamReader(is)); } + private static class JettisonMappedReaderFactory extends AbstractXMLInputFactory { + private static final int INPUT_BUF_SIZE = 4096; + private MappedNamespaceConvention convention; + private DocumentDepthProperties depthProps; + public JettisonMappedReaderFactory(Map<?, ?> nstojns, DocumentDepthProperties depthProps) { + convention = new MappedNamespaceConvention(new Configuration(nstojns)); + this.depthProps = depthProps; + } + @Override + public XMLStreamReader createXMLStreamReader(JSONTokener tokener) throws XMLStreamException { + try { + JSONObject root = new JettisonJSONObject(tokener, depthProps); + return new MappedXMLStreamReader(root, convention); + } catch (JSONException e) { + throw new XMLStreamException(e); + } + } + private String readAll(InputStream in, String encoding) + throws IOException { + + final byte[] buffer = new byte[INPUT_BUF_SIZE]; + ByteArrayOutputStream bos = null; + while (true) { + int count = in.read(buffer); + if (count < 0) { // EOF + break; + } + if (bos == null) { + int cap; + if (count < 64) { + cap = 64; + } else if (count == INPUT_BUF_SIZE) { + // Let's assume there's more coming, not just this chunk + cap = INPUT_BUF_SIZE * 4; + } else { + cap = count; + } + bos = new ByteArrayOutputStream(cap); + } + bos.write(buffer, 0, count); + } + return (bos == null) ? "" : bos.toString(encoding); + } + public XMLStreamReader createXMLStreamReader(InputStream is, String charset) + throws XMLStreamException { + /* !!! This is not really correct: should (try to) auto-detect + * encoding, since JSON only allows 3 Unicode-based variants. + * For now it's ok to default to UTF-8 though. + */ + if (charset == null) { + charset = "UTF-8"; + } + try { + String doc = readAll(is, charset); + return createXMLStreamReader(new JettisonJSONTokener(doc, depthProps)); + } catch (IOException e) { + throw new XMLStreamException(e); + } + } + } + + private static class JettisonJSONTokener extends JSONTokener { + private DocumentDepthProperties depthProps; + public JettisonJSONTokener(String s, DocumentDepthProperties depthProps) { + super(s); + this.depthProps = depthProps; + } + public Object nextValue() throws JSONException { + char c = nextClean(); + switch (c) { + case '"': + case '\'': + return nextString(c); + case '{': + back(); + return new JettisonJSONObject(this, depthProps); + case '[': + back(); + return new JSONArray(this); + default: + } + + return finalize(c); + } + private Object finalize(char c) throws JSONException { + StringBuffer sb = new StringBuffer(); + char b = c; + while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { + sb.append(c); + c = next(); + } + back(); + + String s = sb.toString().trim(); + if (s.length() == 0) { + throw new JSONException("Missing value."); + } + Object res = null; + if (s.equalsIgnoreCase("true")) { + res = Boolean.TRUE; + } else if (s.equalsIgnoreCase("false")) { + res = Boolean.FALSE; + } else if (s.equalsIgnoreCase("null")) { + res = JSONObject.NULL; + } + if (res != null) { + return res; + } + if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') { + if (b == '0') { + if (s.length() > 2 && (s.charAt(1) == 'x' || s.charAt(1) == 'X')) { + try { + res = new Integer(Integer.parseInt(s.substring(2), + 16)); + } catch (Exception e) { + /* Ignore the error */ + } + } else { + try { + res = new Integer(Integer.parseInt(s, 8)); + } catch (Exception e) { + /* Ignore the error */ + } + } + } + if (res == null) { + try { + res = new Integer(s); + } catch (Exception e) { + try { + res = new Long(s); + } catch (Exception f) { + try { + res = new Double(s); + } catch (Exception g) { + res = s; + } + } + } + } + if (res != null) { + return res; + } + } + return s; + } + } + + private static class JettisonJSONObject extends JSONObject { + private static final long serialVersionUID = 9016458891093343731L; + private int threshold; + + public JettisonJSONObject(JSONTokener x, DocumentDepthProperties depthProps) + throws JSONException { + this.threshold = depthProps.getElementCountThreshold() != -1 + ? depthProps.getElementCountThreshold() : depthProps.getInnerElementCountThreshold(); + String key; + char c; + if (x.nextClean() != '{') { + throw x.syntaxError("A JSONObject text must begin with '{'"); + } + for (;;) { + c = x.nextClean(); + switch (c) { + case 0: + throw x.syntaxError("A JSONObject text must end with '}'"); + case '}': + return; + default: + x.back(); + key = x.nextValue().toString(); + } + + c = x.nextClean(); + if (c == '=') { + if (x.next() != '>') { + x.back(); + } + } else if (c != ':') { + throw x.syntaxError("Expected a ':' after a key"); + } + put(key, x.nextValue()); //NOPMD + switch (x.nextClean()) { + case ';': + case ',': + if (x.nextClean() == '}') { + return; + } + x.back(); + break; + case '}': + return; + default: + throw new JSONException("Expected a ',' or '}'"); + } + } + } + public JSONObject put(String key, Object value) throws JSONException { + JSONObject obj = super.put(key, value); + if (threshold != -1 && super.length() >= threshold) { + throw new DepthExceededStaxException(); + } + return obj; + + } + } + private static class JettisonReader extends DepthXMLStreamReader { private Map<String, String> namespaceMap; public JettisonReader(Map<String, String> nsMap, Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/SourceProvider.java Wed Mar 14 13:47:05 2012 @@ -48,6 +48,7 @@ import org.apache.cxf.io.CachedOutputStr import org.apache.cxf.jaxrs.ext.MessageContext; import org.apache.cxf.jaxrs.ext.xml.XMLSource; import org.apache.cxf.jaxrs.utils.HttpUtils; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.StaxSource; import org.apache.cxf.staxutils.StaxUtils; @@ -92,6 +93,8 @@ public class SourceProvider extends Abst try { Document doc = StaxUtils.read(reader); return docRequired ? doc : new DOMSource(doc); + } catch (DepthExceededStaxException e) { + throw new WebApplicationException(413); } catch (Exception e) { IOException ioex = new IOException("Problem creating a Source object"); ioex.setStackTrace(e.getStackTrace()); @@ -184,11 +187,12 @@ public class SourceProvider extends Abst protected String getPreferredSource() { MessageContext mc = getContext(); + String source = null; if (mc != null) { - return (String)mc.getContextualProperty(PREFERRED_FORMAT); - } else { - return "sax"; - } + source = (String)mc.getContextualProperty(PREFERRED_FORMAT); + } + return source != null ? source : "sax"; + } protected MessageContext getContext() { Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java Wed Mar 14 13:47:05 2012 @@ -41,6 +41,7 @@ import org.apache.cxf.interceptor.Loggin import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; +import org.apache.cxf.message.Message; import org.apache.cxf.phase.PhaseInterceptorChain; public final class FormUtils { @@ -48,6 +49,7 @@ public final class FormUtils { private static final Logger LOG = LogUtils.getL7dLogger(FormUtils.class); private static final String MULTIPART_FORM_DATA_TYPE = "form-data"; + private static final String MAX_FORM_PARAM_COUNT = "maxFormParameterCount"; private FormUtils() { @@ -77,13 +79,15 @@ public final class FormUtils { } } - public static void populateMapFromString(MultivaluedMap<String, String> params, + public static void populateMapFromString(MultivaluedMap<String, String> params, + Message m, String postBody, String enc, boolean decode, HttpServletRequest request) { if (!StringUtils.isEmpty(postBody)) { List<String> parts = Arrays.asList(postBody.split("&")); + checkNumberOfParts(m, parts.size()); for (String part : parts) { String[] keyValue = part.split("="); // Change to add blank string if key but not value is specified @@ -138,9 +142,11 @@ public final class FormUtils { } public static void populateMapFromMultipart(MultivaluedMap<String, String> params, - MultipartBody body, + MultipartBody body, + Message m, boolean decode) { List<Attachment> atts = body.getAllAttachments(); + checkNumberOfParts(m, atts.size()); for (Attachment a : atts) { ContentDisposition cd = a.getContentDisposition(); if (cd != null && !MULTIPART_FORM_DATA_TYPE.equalsIgnoreCase(cd.getType())) { @@ -161,4 +167,23 @@ public final class FormUtils { } } } + + private static void checkNumberOfParts(Message m, int numberOfParts) { + if (m == null || m.getExchange() == null || m.getExchange().getInMessage() == null) { + return; + } + String maxPartsCountProp = (String)m.getExchange() + .getInMessage().getContextualProperty(MAX_FORM_PARAM_COUNT); + if (maxPartsCountProp == null) { + return; + } + try { + int maxPartsCount = Integer.valueOf(maxPartsCountProp); + if (maxPartsCount != -1 && numberOfParts >= maxPartsCount) { + throw new WebApplicationException(413); + } + } catch (NumberFormatException ex) { + throw new WebApplicationException(500); + } + } } Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Wed Mar 14 13:47:05 2012 @@ -739,12 +739,12 @@ public final class JAXRSUtils { String enc = HttpUtils.getEncoding(mt, "UTF-8"); String body = FormUtils.readBody(m.getContent(InputStream.class), enc); HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST); - FormUtils.populateMapFromString(params, (String)body, enc, decode, request); + FormUtils.populateMapFromString(params, m, (String)body, enc, decode, request); } else { if (mt != null && "multipart".equalsIgnoreCase(mt.getType()) && MediaType.MULTIPART_FORM_DATA_TYPE.isCompatible(mt)) { MultipartBody body = AttachmentUtils.getMultipartBody(mc); - FormUtils.populateMapFromMultipart(params, body, decode); + FormUtils.populateMapFromMultipart(params, body, m, decode); } else { org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message("WRONG_FORM_MEDIA_TYPE", Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java Wed Mar 14 13:47:05 2012 @@ -41,6 +41,7 @@ import org.apache.cxf.jaxrs.ext.multipar import org.apache.cxf.jaxrs.impl.MetadataMap; import org.apache.cxf.jaxrs.utils.FormUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.phase.PhaseInterceptorChain; public final class AttachmentUtils { private static final Logger LOG = LogUtils.getL7dLogger(JAXRSUtils.class); @@ -143,6 +144,7 @@ public final class AttachmentUtils { MultivaluedMap<String, T> data = new MetadataMap<String, T>(); FormUtils.populateMapFromMultipart((MultivaluedMap)data, AttachmentUtils.getMultipartBody(mc), + PhaseInterceptorChain.getCurrentMessage(), true); return data; } Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java Wed Mar 14 13:47:05 2012 @@ -91,6 +91,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); @@ -137,6 +141,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); @@ -180,6 +188,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java Wed Mar 14 13:47:05 2012 @@ -59,6 +59,10 @@ public class ResponseReaderTest extends ProviderFactory instance = ProviderFactory.getInstance(); Endpoint endpoint = EasyMock.createMock(Endpoint.class); + endpoint.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + endpoint.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); endpoint.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(instance).anyTimes(); EasyMock.replay(endpoint); Modified: cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java (original) +++ cxf/branches/2.4.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/provider/SourceProviderTest.java Wed Mar 14 13:47:05 2012 @@ -76,7 +76,7 @@ public class SourceProviderTest extends public void testReadFrom() throws Exception { SourceProvider p = new TestSourceProvider(); assertSame(StreamSource.class, verifyRead(p, StreamSource.class).getClass()); - assertSame(StreamSource.class, verifyRead(p, Source.class).getClass()); + assertSame(StaxSource.class, verifyRead(p, Source.class).getClass()); assertSame(StaxSource.class, verifyRead(p, SAXSource.class).getClass()); assertSame(StaxSource.class, verifyRead(p, StaxSource.class).getClass()); assertSame(DOMSource.class, verifyRead(p, DOMSource.class).getClass()); Modified: cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original) +++ cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Wed Mar 14 13:47:05 2012 @@ -20,6 +20,7 @@ package org.apache.cxf.systest.jaxrs; +import java.io.ByteArrayOutputStream; import java.util.HashMap; import java.util.Map; @@ -34,11 +35,17 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriInfo; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMSource; import org.apache.cxf.annotations.Logging; +import org.apache.cxf.staxutils.DepthExceededStaxException; +import org.apache.cxf.staxutils.StaxUtils; @Path("/") @Produces("application/json") @@ -135,7 +142,42 @@ public class BookStoreSpring { @GET public Book getDefaultBook() { return books.get(mainId); - } + } + + @POST + @Path("depth") + @Produces({"application/xml", "application/json" }) + @Consumes({"application/xml", "application/json" }) + public Book echoBook(Book book) { + return book; + } + + @POST + @Path("depth-source") + @Consumes({"application/xml" }) + public void postSourceBook(Source source) { + try { + StaxUtils.copy(source, new ByteArrayOutputStream()); + } catch (DepthExceededStaxException ex) { + throw new WebApplicationException(413); + } catch (Exception ex) { + // ignore for now + } + throw new WebApplicationException(500); + } + + @POST + @Path("depth-dom") + @Consumes({"application/xml" }) + public void postDomBook(DOMSource source) { + // complete + } + + @POST + @Path("depth-form") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void depthForm(MultivaluedMap<String, String> map) { + } @POST @Path("books/convert") Modified: cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original) +++ cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Wed Mar 14 13:47:05 2012 @@ -48,6 +48,7 @@ import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.jaxrs.ext.form.Form; import org.apache.cxf.jaxrs.ext.xml.XMLSource; import org.apache.cxf.jaxrs.model.wadl.WadlGenerator; import org.apache.cxf.jaxrs.provider.AegisElementProvider; @@ -64,7 +65,7 @@ public class JAXRSClientServerSpringBook @BeforeClass public static void startServers() throws Exception { assertTrue("server did not launch correctly", - launchServer(BookServerSpring.class)); + launchServer(BookServerSpring.class, true)); } @Test @@ -221,6 +222,55 @@ public class JAXRSClientServerSpringBook "application/vnd.example-com.foo+json"); } + @Test + public void testBookDepthExceededXML() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth"; + WebClient wc = WebClient.create(endpointAddress); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testBookDepthExceededXMLSource() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth-source"; + WebClient wc = WebClient.create(endpointAddress); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testBookDepthExceededXMLDom() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth-dom"; + WebClient wc = WebClient.create(endpointAddress); + WebClient.getConfig(wc).getHttpConduit().getClient().setReceiveTimeout(1000000L); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testBookDepthExceededJettison() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks10/depth"; + WebClient wc = WebClient.create(endpointAddress); + wc.accept("application/json").type("application/json"); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testTooManyFormParams() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth-form"; + WebClient wc = WebClient.create(endpointAddress); + Response r = wc.form(new Form().set("a", "b")); + assertEquals(204, r.getStatus()); + r = wc.form(new Form().set("a", "b").set("c", "b")); + assertEquals(413, r.getStatus()); + } + @Test public void testGetBookJsonp() throws Exception { @@ -228,7 +278,6 @@ public class JAXRSClientServerSpringBook WebClient client = WebClient.create(url); client.accept("application/json, application/x-javascript"); client.query("_jsonp", "callback"); - WebClient.getConfig(client).getHttpConduit().getClient().setReceiveTimeout(1000000L); Response r = client.get(); assertEquals("application/x-javascript", r.getMetadata().getFirst("Content-Type")); assertEquals("callback({\"Book\":{\"id\":123,\"name\":\"CXF in Action\"}});", Modified: cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml?rev=1300544&r1=1300543&r2=1300544&view=diff ============================================================================== --- cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml (original) +++ cxf/branches/2.4.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Wed Mar 14 13:47:05 2012 @@ -199,6 +199,33 @@ http://cxf.apache.org/schemas/core.xsd"> </jaxrs:providers> </jaxrs:server> + <jaxrs:server id="bookservice9" + address="/thebooks9"> + <jaxrs:serviceBeans> + <ref bean="serviceBean" /> + </jaxrs:serviceBeans> + <jaxrs:inInterceptors> + <bean class="org.apache.cxf.interceptor.security.DepthRestrictingStreamInterceptor"> + <property name="innerElementLevelThreshold" value="2"/> + </bean> + </jaxrs:inInterceptors> + <jaxrs:properties> + <entry key="maxFormParameterCount" value="2"/> + </jaxrs:properties> + + </jaxrs:server> + + <jaxrs:server id="bookservice10" + address="/thebooks10"> + <jaxrs:serviceBeans> + <ref bean="serviceBean" /> + </jaxrs:serviceBeans> + <jaxrs:properties> + <entry key="depthInnerElementCountThreshold" value="2"/> + </jaxrs:properties> + + </jaxrs:server> + <bean id="jaxbProviderForTypes" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider"> <property name="unmarshallAsJaxbElement" value="true"/> <property name="schemaLocations" ref="theSchemaLocations"/>
