Skip to content

Commit a2973c7

Browse files
committed
SWS-748 - Not well formed xml causes server 500 error
1 parent 4d606a7 commit a2973c7

File tree

12 files changed

+156
-21
lines changed

12 files changed

+156
-21
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2005-2012 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ws;
18+
19+
/**
20+
* Exception thrown when a {@link WebServiceMessageFactory} cannot parse the XML passed on to
21+
* {@link WebServiceMessageFactory#createWebServiceMessage(java.io.InputStream)}.
22+
*
23+
* @author Arjen Poutsma
24+
* @since 2.0.4
25+
*/
26+
public final class InvalidXmlException extends WebServiceException {
27+
28+
public InvalidXmlException(String msg, Throwable ex) {
29+
super(msg, ex);
30+
}
31+
}

core/src/main/java/org/springframework/ws/WebServiceMessageFactory.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -46,8 +46,9 @@ public interface WebServiceMessageFactory {
4646
*
4747
* @param inputStream the input stream to read the message from
4848
* @return the created message
49-
* @throws java.io.IOException if an I/O exception occurs
49+
* @throws InvalidXmlException if the XML read from the input stream is invalid
50+
* @throws IOException if an I/O exception occurs
5051
*/
51-
WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException;
52+
WebServiceMessage createWebServiceMessage(InputStream inputStream) throws InvalidXmlException, IOException;
5253

5354
}

core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -32,6 +32,7 @@
3232
import org.springframework.beans.factory.InitializingBean;
3333
import org.springframework.util.CollectionUtils;
3434
import org.springframework.util.StringUtils;
35+
import org.springframework.ws.InvalidXmlException;
3536
import org.springframework.ws.soap.SoapMessageCreationException;
3637
import org.springframework.ws.soap.SoapMessageFactory;
3738
import org.springframework.ws.soap.SoapVersion;
@@ -41,6 +42,7 @@
4142

4243
import org.apache.commons.logging.Log;
4344
import org.apache.commons.logging.LogFactory;
45+
import org.xml.sax.SAXParseException;
4446

4547
/**
4648
* SAAJ-specific implementation of the {@link org.springframework.ws.WebServiceMessageFactory WebServiceMessageFactory}.
@@ -202,6 +204,23 @@ public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws I
202204
}
203205
}
204206
throw new SoapMessageCreationException("Could not create message from InputStream: " + ex.getMessage(), ex);
207+
} catch (SaajSoapEnvelopeException ex) {
208+
SAXParseException parseException = getSAXParseException(ex);
209+
if (parseException != null) {
210+
throw new InvalidXmlException("Could not parse XML", parseException);
211+
} else {
212+
throw ex;
213+
}
214+
}
215+
}
216+
217+
private SAXParseException getSAXParseException(Throwable ex) {
218+
if (ex instanceof SAXParseException) {
219+
return (SAXParseException) ex;
220+
} else if (ex.getCause() != null) {
221+
return getSAXParseException(ex.getCause());
222+
} else {
223+
return null;
205224
}
206225
}
207226

core/src/main/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapter.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2006 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -21,6 +21,7 @@
2121

2222
import org.springframework.web.servlet.HandlerAdapter;
2323
import org.springframework.web.servlet.ModelAndView;
24+
import org.springframework.ws.InvalidXmlException;
2425
import org.springframework.ws.transport.WebServiceConnection;
2526
import org.springframework.ws.transport.WebServiceMessageReceiver;
2627
import org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport;
@@ -54,7 +55,12 @@ public ModelAndView handle(HttpServletRequest httpServletRequest,
5455
Object handler) throws Exception {
5556
if (HttpTransportConstants.METHOD_POST.equals(httpServletRequest.getMethod())) {
5657
WebServiceConnection connection = new HttpServletConnection(httpServletRequest, httpServletResponse);
57-
handleConnection(connection, (WebServiceMessageReceiver) handler);
58+
try {
59+
handleConnection(connection, (WebServiceMessageReceiver) handler);
60+
}
61+
catch (InvalidXmlException ex) {
62+
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
63+
}
5864
}
5965
else {
6066
httpServletResponse.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);

core/src/test/java/org/springframework/ws/soap/AbstractSoapMessageFactoryTestCase.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,6 +17,7 @@
1717
package org.springframework.ws.soap;
1818

1919
import org.springframework.ws.AbstractWebServiceMessageFactoryTestCase;
20+
import org.springframework.ws.InvalidXmlException;
2021
import org.springframework.ws.WebServiceMessage;
2122

2223
import org.junit.Test;
@@ -31,6 +32,9 @@ public void testCreateEmptySoapMessage() throws Exception {
3132
assertTrue("Not a SoapMessage", message instanceof SoapMessage);
3233
}
3334

35+
@Test(expected = InvalidXmlException.class)
36+
public abstract void testCreateSoapMessageIllFormedXml() throws Exception;
37+
3438
@Test
3539
public abstract void testCreateSoapMessageNoAttachment() throws Exception;
3640

core/src/test/java/org/springframework/ws/soap/axiom/AxiomSoap11MessageFactoryTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,6 +22,7 @@
2222
import javax.xml.transform.TransformerException;
2323
import javax.xml.transform.TransformerFactory;
2424

25+
import org.springframework.ws.InvalidXmlException;
2526
import org.springframework.ws.WebServiceMessage;
2627
import org.springframework.ws.WebServiceMessageFactory;
2728
import org.springframework.ws.soap.soap11.AbstractSoap11MessageFactoryTestCase;
@@ -49,6 +50,12 @@ protected WebServiceMessageFactory createMessageFactory() throws Exception {
4950
return factory;
5051
}
5152

53+
@Override
54+
public void testCreateSoapMessageIllFormedXml() throws Exception {
55+
// Axiom parses the contents of XML lazily, so it will not throw an InvalidXmlException when a message is parsed
56+
throw new InvalidXmlException(null, null);
57+
}
58+
5259
@Test
5360
public void testGetCharsetEncoding() {
5461
AxiomSoapMessageFactory messageFactory = new AxiomSoapMessageFactory();

core/src/test/java/org/springframework/ws/soap/axiom/AxiomSoap12MessageFactoryTest.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.ws.soap.axiom;
1818

19+
import org.springframework.ws.InvalidXmlException;
1920
import org.springframework.ws.WebServiceMessageFactory;
2021
import org.springframework.ws.soap.SoapVersion;
2122
import org.springframework.ws.soap.soap12.AbstractSoap12MessageFactoryTestCase;
@@ -30,4 +31,10 @@ protected WebServiceMessageFactory createMessageFactory() throws Exception {
3031
return factory;
3132
}
3233

34+
@Override
35+
public void testCreateSoapMessageIllFormedXml() throws Exception {
36+
// Axiom parses the contents of XML lazily, so it will not throw an InvalidXmlException when a message is parsed
37+
throw new InvalidXmlException(null, null);
38+
}
39+
3340
}

core/src/test/java/org/springframework/ws/soap/soap11/AbstractSoap11MessageFactoryTestCase.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -60,6 +60,17 @@ public void testCreateSoapMessageNoAttachment() throws Exception {
6060
assertFalse("Message a XOP pacakge", soapMessage.isXopPackage());
6161
}
6262

63+
@Override
64+
public void testCreateSoapMessageIllFormedXml() throws Exception {
65+
InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-ill-formed.xml");
66+
Map<String, String> headers = new HashMap<String, String>();
67+
headers.put("Content-Type", "text/xml");
68+
TransportInputStream tis = new MockTransportInputStream(is, headers);
69+
70+
WebServiceMessage message = messageFactory.createWebServiceMessage(tis);
71+
message.writeTo(System.out);
72+
}
73+
6374
@Override
6475
public void testCreateSoapMessageSwA() throws Exception {
6576
InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-attachment.bin");

core/src/test/java/org/springframework/ws/soap/soap12/AbstractSoap12MessageFactoryTestCase.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -58,6 +58,17 @@ public void testCreateSoapMessageNoAttachment() throws Exception {
5858
assertFalse("Message is a XOP pacakge", soapMessage.isXopPackage());
5959
}
6060

61+
@Override
62+
public void testCreateSoapMessageIllFormedXml() throws Exception {
63+
InputStream is = AbstractSoap12MessageFactoryTestCase.class.getResourceAsStream("soap12-ill-formed.xml");
64+
Map<String, String> headers = new HashMap<String, String>();
65+
headers.put(TransportConstants.HEADER_CONTENT_TYPE, "application/soap+xml");
66+
TransportInputStream tis = new MockTransportInputStream(is, headers);
67+
68+
messageFactory.createWebServiceMessage(tis);
69+
}
70+
71+
6172
@Override
6273
public void testCreateSoapMessageSwA() throws Exception {
6374
InputStream is = AbstractSoap12MessageFactoryTestCase.class.getResourceAsStream("soap12-attachment.bin");

core/src/test/java/org/springframework/ws/transport/http/WebServiceMessageReceiverHandlerAdapterTest.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2005-2010 the original author or authors.
2+
* Copyright 2005-2012 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -23,6 +23,7 @@
2323
import org.springframework.mock.web.MockHttpServletRequest;
2424
import org.springframework.mock.web.MockHttpServletResponse;
2525
import org.springframework.ws.FaultAwareWebServiceMessage;
26+
import org.springframework.ws.InvalidXmlException;
2627
import org.springframework.ws.NoEndpointFoundException;
2728
import org.springframework.ws.WebServiceMessageFactory;
2829
import org.springframework.ws.context.MessageContext;
@@ -178,6 +179,28 @@ public void receive(MessageContext messageContext) throws Exception {
178179

179180
}
180181

182+
@Test
183+
public void testHandleInvalidXml() throws Exception {
184+
httpRequest.setMethod(HttpTransportConstants.METHOD_POST);
185+
httpRequest.setContent(REQUEST.getBytes("UTF-8"));
186+
httpRequest.setContentType("text/xml; charset=\"utf-8\"");
187+
httpRequest.setCharacterEncoding("UTF-8");
188+
expect(factoryMock.createWebServiceMessage(isA(InputStream.class))).andThrow(new InvalidXmlException(null, null));
189+
190+
replayMockControls();
191+
192+
WebServiceMessageReceiver endpoint = new WebServiceMessageReceiver() {
193+
194+
public void receive(MessageContext messageContext) throws Exception {
195+
}
196+
};
197+
198+
adapter.handle(httpRequest, httpResponse, endpoint);
199+
Assert.assertEquals("No 400 returned", HttpServletResponse.SC_BAD_REQUEST, httpResponse.getStatus());
200+
201+
verifyMockControls();
202+
}
203+
181204
private void replayMockControls() {
182205
replay(factoryMock, requestMock, responseMock);
183206
}

0 commit comments

Comments
 (0)