SWS-748 - Not well formed xml causes server 500 error

This commit is contained in:
Arjen Poutsma
2012-01-25 12:08:15 +00:00
parent 4d606a7d37
commit a2973c7e44
12 changed files with 156 additions and 21 deletions

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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.springframework.ws;
/**
* Exception thrown when a {@link WebServiceMessageFactory} cannot parse the XML passed on to
* {@link WebServiceMessageFactory#createWebServiceMessage(java.io.InputStream)}.
*
* @author Arjen Poutsma
* @since 2.0.4
*/
public final class InvalidXmlException extends WebServiceException {
public InvalidXmlException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -46,8 +46,9 @@ public interface WebServiceMessageFactory {
*
* @param inputStream the input stream to read the message from
* @return the created message
* @throws java.io.IOException if an I/O exception occurs
* @throws InvalidXmlException if the XML read from the input stream is invalid
* @throws IOException if an I/O exception occurs
*/
WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException;
WebServiceMessage createWebServiceMessage(InputStream inputStream) throws InvalidXmlException, IOException;
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -32,6 +32,7 @@ import javax.xml.soap.SOAPMessage;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.soap.SoapMessageCreationException;
import org.springframework.ws.soap.SoapMessageFactory;
import org.springframework.ws.soap.SoapVersion;
@@ -41,6 +42,7 @@ import org.springframework.ws.transport.TransportInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXParseException;
/**
* SAAJ-specific implementation of the {@link org.springframework.ws.WebServiceMessageFactory WebServiceMessageFactory}.
@@ -202,6 +204,23 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB
}
}
throw new SoapMessageCreationException("Could not create message from InputStream: " + ex.getMessage(), ex);
} catch (SaajSoapEnvelopeException ex) {
SAXParseException parseException = getSAXParseException(ex);
if (parseException != null) {
throw new InvalidXmlException("Could not parse XML", parseException);
} else {
throw ex;
}
}
}
private SAXParseException getSAXParseException(Throwable ex) {
if (ex instanceof SAXParseException) {
return (SAXParseException) ex;
} else if (ex.getCause() != null) {
return getSAXParseException(ex.getCause());
} else {
return null;
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2006 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -21,6 +21,7 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.WebServiceMessageReceiver;
import org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport;
@@ -54,7 +55,12 @@ public class WebServiceMessageReceiverHandlerAdapter extends WebServiceMessageRe
Object handler) throws Exception {
if (HttpTransportConstants.METHOD_POST.equals(httpServletRequest.getMethod())) {
WebServiceConnection connection = new HttpServletConnection(httpServletRequest, httpServletResponse);
handleConnection(connection, (WebServiceMessageReceiver) handler);
try {
handleConnection(connection, (WebServiceMessageReceiver) handler);
}
catch (InvalidXmlException ex) {
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
}
else {
httpServletResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -17,6 +17,7 @@
package org.springframework.ws.soap;
import org.springframework.ws.AbstractWebServiceMessageFactoryTestCase;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.WebServiceMessage;
import org.junit.Test;
@@ -31,6 +32,9 @@ public abstract class AbstractSoapMessageFactoryTestCase extends AbstractWebServ
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
}
@Test(expected = InvalidXmlException.class)
public abstract void testCreateSoapMessageIllFormedXml() throws Exception;
@Test
public abstract void testCreateSoapMessageNoAttachment() throws Exception;

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -22,6 +22,7 @@ import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.soap11.AbstractSoap11MessageFactoryTestCase;
@@ -49,6 +50,12 @@ public class AxiomSoap11MessageFactoryTest extends AbstractSoap11MessageFactoryT
return factory;
}
@Override
public void testCreateSoapMessageIllFormedXml() throws Exception {
// Axiom parses the contents of XML lazily, so it will not throw an InvalidXmlException when a message is parsed
throw new InvalidXmlException(null, null);
}
@Test
public void testGetCharsetEncoding() {
AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -16,6 +16,7 @@
package org.springframework.ws.soap.axiom;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.SoapVersion;
import org.springframework.ws.soap.soap12.AbstractSoap12MessageFactoryTestCase;
@@ -30,4 +31,10 @@ public class AxiomSoap12MessageFactoryTest extends AbstractSoap12MessageFactoryT
return factory;
}
@Override
public void testCreateSoapMessageIllFormedXml() throws Exception {
// Axiom parses the contents of XML lazily, so it will not throw an InvalidXmlException when a message is parsed
throw new InvalidXmlException(null, null);
}
}

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -60,6 +60,17 @@ public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapM
assertFalse("Message a XOP pacakge", soapMessage.isXopPackage());
}
@Override
public void testCreateSoapMessageIllFormedXml() throws Exception {
InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-ill-formed.xml");
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "text/xml");
TransportInputStream tis = new MockTransportInputStream(is, headers);
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
message.writeTo(System.out);
}
@Override
public void testCreateSoapMessageSwA() throws Exception {
InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-attachment.bin");

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -58,6 +58,17 @@ public abstract class AbstractSoap12MessageFactoryTestCase extends AbstractSoapM
assertFalse("Message is a XOP pacakge", soapMessage.isXopPackage());
}
@Override
public void testCreateSoapMessageIllFormedXml() throws Exception {
InputStream is = AbstractSoap12MessageFactoryTestCase.class.getResourceAsStream("soap12-ill-formed.xml");
Map<String, String> headers = new HashMap<String, String>();
headers.put(TransportConstants.HEADER_CONTENT_TYPE, "application/soap+xml");
TransportInputStream tis = new MockTransportInputStream(is, headers);
messageFactory.createWebServiceMessage(tis);
}
@Override
public void testCreateSoapMessageSwA() throws Exception {
InputStream is = AbstractSoap12MessageFactoryTestCase.class.getResourceAsStream("soap12-attachment.bin");

View File

@@ -1,11 +1,11 @@
/*
* Copyright 2005-2010 the original author or authors.
* Copyright 2005-2012 the original author or authors.
*
* Licensed 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
* 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,
@@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletResponse;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.ws.FaultAwareWebServiceMessage;
import org.springframework.ws.InvalidXmlException;
import org.springframework.ws.NoEndpointFoundException;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.context.MessageContext;
@@ -178,6 +179,28 @@ public class WebServiceMessageReceiverHandlerAdapterTest {
}
@Test
public void testHandleInvalidXml() throws Exception {
httpRequest.setMethod(HttpTransportConstants.METHOD_POST);
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
httpRequest.setCharacterEncoding("UTF-8");
expect(factoryMock.createWebServiceMessage(isA(InputStream.class))).andThrow(new InvalidXmlException(null, null));
replayMockControls();
WebServiceMessageReceiver endpoint = new WebServiceMessageReceiver() {
public void receive(MessageContext messageContext) throws Exception {
}
};
adapter.handle(httpRequest, httpResponse, endpoint);
Assert.assertEquals("No 400 returned", HttpServletResponse.SC_BAD_REQUEST, httpResponse.getStatus());
verifyMockControls();
}
private void replayMockControls() {
replay(factoryMock, requestMock, responseMock);
}

View File

@@ -0,0 +1,8 @@
<SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/'
SOAP-ENV:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m='http://www.springframework.org/spring-ws'>
<symbol>DIS
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

View File

@@ -0,0 +1,7 @@
<env:Envelope xmlns:env='http://www.w3.org/2003/05/soap-envelope'>
<env:Body>
<m:alert xmlns:m='http://example.org/alert'>
<m:msg>Pick up Mary at school at 2pm
</m:alert>
</env:Body>
</env:Envelope>