From 7ec7e1f6988f5faf28968aa7ae683cb77af7f78c Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 15 Jul 2008 13:02:18 +0000 Subject: [PATCH] SWS-393 --- .../ws/soap/saaj/SaajSoapMessageFactory.java | 54 +++++++++++++----- .../AbstractSoap11MessageFactoryTestCase.java | 32 ++++++++++- .../ws/soap/soap11/soap11-utf16-be-bom.xml | Bin 0 -> 652 bytes .../ws/soap/soap11/soap11-utf16-le-bom.xml | Bin 0 -> 652 bytes .../{soap11-bom.xml => soap11-utf8-bom.xml} | 3 +- 5 files changed, 72 insertions(+), 17 deletions(-) create mode 100644 core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-be-bom.xml create mode 100644 core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-le-bom.xml rename core/src/test/resources/org/springframework/ws/soap/soap11/{soap11-bom.xml => soap11-utf8-bom.xml} (68%) diff --git a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java index d36f1510..98270aa2 100644 --- a/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java +++ b/core/src/main/java/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.java @@ -16,8 +16,10 @@ package org.springframework.ws.soap.saaj; +import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.PushbackInputStream; import java.util.Iterator; import java.util.StringTokenizer; import javax.xml.soap.MessageFactory; @@ -146,21 +148,9 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB } public WebServiceMessage createWebServiceMessage(InputStream inputStream) throws IOException { - MimeHeaders mimeHeaders = new MimeHeaders(); - if (inputStream instanceof TransportInputStream) { - TransportInputStream transportInputStream = (TransportInputStream) inputStream; - for (Iterator headerNames = transportInputStream.getHeaderNames(); headerNames.hasNext();) { - String headerName = (String) headerNames.next(); - for (Iterator headerValues = transportInputStream.getHeaders(headerName); headerValues.hasNext();) { - String headerValue = (String) headerValues.next(); - StringTokenizer tokenizer = new StringTokenizer(headerValue, ","); - while (tokenizer.hasMoreTokens()) { - mimeHeaders.addHeader(headerName, tokenizer.nextToken().trim()); - } - } - } - } + MimeHeaders mimeHeaders = parseMimeHeaders(inputStream); try { + inputStream = checkForUtf8ByteOrderMark(inputStream); return new SaajSoapMessage(messageFactory.createMessage(mimeHeaders, inputStream)); } catch (SOAPException ex) { @@ -182,6 +172,42 @@ public class SaajSoapMessageFactory implements SoapMessageFactory, InitializingB } } + private MimeHeaders parseMimeHeaders(InputStream inputStream) throws IOException { + MimeHeaders mimeHeaders = new MimeHeaders(); + if (inputStream instanceof TransportInputStream) { + TransportInputStream transportInputStream = (TransportInputStream) inputStream; + for (Iterator headerNames = transportInputStream.getHeaderNames(); headerNames.hasNext();) { + String headerName = (String) headerNames.next(); + for (Iterator headerValues = transportInputStream.getHeaders(headerName); headerValues.hasNext();) { + String headerValue = (String) headerValues.next(); + StringTokenizer tokenizer = new StringTokenizer(headerValue, ","); + while (tokenizer.hasMoreTokens()) { + mimeHeaders.addHeader(headerName, tokenizer.nextToken().trim()); + } + } + } + } + return mimeHeaders; + } + + /** + * Checks for the UTF-8 Byte Order Mark, and removes it if present. The SAAJ RI cannot cope with these BOMs. + * + * @see SWS-393 + * @see UTF-8 BOMs + */ + private InputStream checkForUtf8ByteOrderMark(InputStream inputStream) throws IOException { + PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3); + byte[] bom = new byte[3]; + if (pushbackInputStream.read(bom) != -1) { + // check for the UTF-8 BOM, and remove it if there. See SWS-393 + if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) { + pushbackInputStream.unread(bom); + } + } + return pushbackInputStream; + } + public String toString() { StringBuffer buffer = new StringBuffer("SaajSoapMessageFactory["); buffer.append(SaajUtils.getSaajVersionString()); diff --git a/core/src/test/java/org/springframework/ws/soap/soap11/AbstractSoap11MessageFactoryTestCase.java b/core/src/test/java/org/springframework/ws/soap/soap11/AbstractSoap11MessageFactoryTestCase.java index 0c6c67c3..ca1fd971 100644 --- a/core/src/test/java/org/springframework/ws/soap/soap11/AbstractSoap11MessageFactoryTestCase.java +++ b/core/src/test/java/org/springframework/ws/soap/soap11/AbstractSoap11MessageFactoryTestCase.java @@ -39,7 +39,7 @@ public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapM public void testCreateSoapMessageNoAttachment() throws Exception { InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11.xml"); - final Properties headers = new Properties(); + Properties headers = new Properties(); headers.setProperty("Content-Type", "text/xml"); String soapAction = "http://springframework.org/spring-ws/Action"; headers.setProperty("SOAPAction", soapAction); @@ -112,5 +112,35 @@ public abstract class AbstractSoap11MessageFactoryTestCase extends AbstractSoapM assertNotNull("No attachment read", attachment); } + public void testCreateSoapMessageUtf8ByteOrderMark() throws Exception { + InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-utf8-bom.xml"); + Properties headers = new Properties(); + headers.setProperty("Content-Type", "text/xml; charset=UTF-8"); + TransportInputStream tis = new MockTransportInputStream(is, headers); + + SoapMessage message = (SoapMessage) messageFactory.createWebServiceMessage(tis); + assertEquals("Invalid soap version", SoapVersion.SOAP_11, message.getVersion()); + } + + public void testCreateSoapMessageUtf16BigEndianByteOrderMark() throws Exception { + InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-utf16-be-bom.xml"); + Properties headers = new Properties(); + headers.setProperty("Content-Type", "text/xml; charset=UTF-16"); + TransportInputStream tis = new MockTransportInputStream(is, headers); + + SoapMessage message = (SoapMessage) messageFactory.createWebServiceMessage(tis); + assertEquals("Invalid soap version", SoapVersion.SOAP_11, message.getVersion()); + } + + public void testCreateSoapMessageUtf16LittleEndianByteOrderMark() throws Exception { + InputStream is = AbstractSoap11MessageFactoryTestCase.class.getResourceAsStream("soap11-utf16-le-bom.xml"); + Properties headers = new Properties(); + headers.setProperty("Content-Type", "text/xml; charset=UTF-16"); + TransportInputStream tis = new MockTransportInputStream(is, headers); + + SoapMessage message = (SoapMessage) messageFactory.createWebServiceMessage(tis); + assertEquals("Invalid soap version", SoapVersion.SOAP_11, message.getVersion()); + } + } diff --git a/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-be-bom.xml b/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-be-bom.xml new file mode 100644 index 0000000000000000000000000000000000000000..1517963ec5184a543e562499a2f3b5cc8c1ffb3d GIT binary patch literal 652 zcma))Pfx-?5XIlwPtkDkM2i;>q(U(MiHT7Xg*#XjVs~xYM&!$@zg^q36b@z%vzdAG z=DlgZe-vx1FBzo@^r@9{724=SRu}5&OrZwkfR5D*^@Og~oA1u_tQ++~or4)`q!aj_ z^r(rZ)UWlRxrSuxxl`sdn1X7fW!LZk@Aj@$5*giyDA>Ga&S=3qtfmXt7GOehjv|Nq zt3+O{b5n1O;B@MODvqhVWIEAq57*!gT5e%1b?;S_c+Yty)TX>PXzV&OT<$cdngX_~TU~D_771lWhvEx!pm{O2ey5qvJzfQZ}+@hI`nEQ{* S_I}5F_{H0|JdWu86Qf_(FK1l< literal 0 HcmV?d00001 diff --git a/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-le-bom.xml b/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf16-le-bom.xml new file mode 100644 index 0000000000000000000000000000000000000000..454ee138c25a142bceb74edc1c15538cd0f77fc8 GIT binary patch literal 652 zcma))Pfx-?5XIlwPtkDkM2i;>q(U(MiHT7Xg*#XjVs~xYM&!$@zg^q36b@z%vzdAG z=DlfuzGIE`C8JbOwu8Db#=*(6M@=^WB-Ab)!D0b1-9#bfQ>K zdelTy>eqVETtl+;+$r-JOhL8LvTJyNcYD_=iHvSU6l`8IXSCoQR?`J+3os!$N0Gz* zRU)s}xv4isa5{BC6~|OwGM#9*himW#Ew?b1y7wwdyyv_UYExbtGPOex4K-EraAU#DGfZqZCe%>Bn@ Td%t5o{Nn9f9!GTliIIK*Jf3G= literal 0 HcmV?d00001 diff --git a/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-bom.xml b/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf8-bom.xml similarity index 68% rename from core/src/test/resources/org/springframework/ws/soap/soap11/soap11-bom.xml rename to core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf8-bom.xml index 1fba6b1f..fa22ad85 100644 --- a/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-bom.xml +++ b/core/src/test/resources/org/springframework/ws/soap/soap11/soap11-utf8-bom.xml @@ -1,6 +1,5 @@  - + DIS