You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by re...@apache.org on 2022/07/15 14:19:18 UTC
[cxf] 01/02: CXF-8733: [regression] Content-ID of attachments for outgoing requests is not URL-decoded (#968)
This is an automated email from the ASF dual-hosted git repository.
reta pushed a commit to branch 3.5.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git
commit f92c8278e3bba8c7d900900cff3eb9b0a33d23b6
Author: Andriy Redko <dr...@gmail.com>
AuthorDate: Fri Jul 15 09:54:42 2022 -0400
CXF-8733: [regression] Content-ID of attachments for outgoing requests is not URL-decoded (#968)
(cherry picked from commit 952cd07527d9abb0b6665d7483913afe1c1ae5e7)
---
.../org/apache/cxf/attachment/AttachmentUtil.java | 23 +--
.../AttachmentSerializerDeserializerTest.java | 188 +++++++++++++++++++++
2 files changed, 196 insertions(+), 15 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
index f62ebee76b..ce393ee54d 100644
--- a/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
+++ b/core/src/main/java/org/apache/cxf/attachment/AttachmentUtil.java
@@ -355,21 +355,14 @@ public final class AttachmentUtil {
}
// strip cid:
if (id.startsWith("cid:")) {
- //
- // RFC-2392 (https://datatracker.ietf.org/doc/html/rfc2392) says:
- //
- // A "cid" URL is converted to the corresponding Content-ID message
- // header [MIME] by removing the "cid:" prefix, converting the % encoded
- // character to their equivalent US-ASCII characters, and enclosing the
- // remaining parts with an angle bracket pair, "<" and ">".
- //
- try {
- id = id.substring(4);
- // urldecode
- id = URLDecoder.decode(id, StandardCharsets.UTF_8.name());
- } catch (UnsupportedEncodingException e) {
- //ignore, keep id as is
- }
+ id = id.substring(4);
+ }
+
+ try {
+ // urldecode
+ id = URLDecoder.decode(id, StandardCharsets.UTF_8.name());
+ } catch (UnsupportedEncodingException e) {
+ //ignore, keep id as is
}
}
if (id == null) {
diff --git a/core/src/test/java/org/apache/cxf/attachment/AttachmentSerializerDeserializerTest.java b/core/src/test/java/org/apache/cxf/attachment/AttachmentSerializerDeserializerTest.java
new file mode 100644
index 0000000000..99d5c11492
--- /dev/null
+++ b/core/src/test/java/org/apache/cxf/attachment/AttachmentSerializerDeserializerTest.java
@@ -0,0 +1,188 @@
+/**
+ * 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.attachment;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.activation.DataHandler;
+import javax.mail.MessagingException;
+import javax.mail.util.ByteArrayDataSource;
+
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.message.Attachment;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class AttachmentSerializerDeserializerTest {
+
+ @Test
+ public void testMessageWriteXopOn1() throws Exception {
+ doTestMessageSerde(true, "text/xml");
+ }
+
+ @Test
+ public void testMessageWriteXopOn2() throws Exception {
+ doTestMessageSerde(true, "application/soap+xml; action=\"urn:foo\"");
+ }
+
+ @Test
+ public void testMessageWriteXopOff1() throws Exception {
+ doTestMessageSerde(false, "text/xml");
+ }
+
+ @Test
+ public void testMessageWriteXopOff2() throws Exception {
+ doTestMessageSerde(false, "application/soap+xml; action=\"urn:foo\"");
+ }
+
+ private void doTestMessageSerde(boolean xop, String soapContentType) throws Exception {
+ MessageImpl in = new MessageImpl();
+
+ Collection<Attachment> atts = new ArrayList<>();
+ AttachmentImpl a = new AttachmentImpl("test.xml");
+
+ InputStream is = getClass().getResourceAsStream("my.wav");
+ ByteArrayDataSource ds = new ByteArrayDataSource(is, "application/octet-stream");
+ a.setDataHandler(new DataHandler(ds));
+
+ atts.add(a);
+
+ in.setAttachments(atts);
+
+ // Set the SOAP content type
+ in.put(Message.CONTENT_TYPE, soapContentType);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ in.setContent(OutputStream.class, out);
+
+ AttachmentSerializer serializer = new AttachmentSerializer(in);
+ if (!xop) {
+ // default is "on"
+ serializer.setXop(xop);
+ }
+
+ serializer.writeProlog();
+ out.write("<soap:Body/>".getBytes());
+
+ serializer.writeAttachments();
+ out.flush();
+
+ doTestMessageRead(in, "test.xml");
+ is.close();
+ }
+
+ private void doTestMessageRead(Message in, String contentId)
+ throws IOException, MessagingException {
+
+ final MessageImpl msg = new MessageImpl();
+ msg.put(Message.CONTENT_TYPE, "multipart/related;");
+
+ final ByteArrayOutputStream out = (ByteArrayOutputStream)in.getContent(OutputStream.class);
+ try (ByteArrayInputStream content = new ByteArrayInputStream(out.toByteArray())) {
+ msg.setContent(InputStream.class, content);
+
+ AttachmentDeserializer deserializer = new AttachmentDeserializer(msg);
+ deserializer.initializeAttachments();
+
+ Collection<Attachment> atts = msg.getAttachments();
+ assertNotNull(atts);
+
+ Iterator<Attachment> itr = atts.iterator();
+ assertTrue(itr.hasNext());
+
+ Attachment a = itr.next();
+ assertNotNull(a);
+
+ assertEquals("binary", a.getHeader("Content-Transfer-Encoding"));
+ assertEquals(contentId, a.getId());
+
+ // check the cached output stream
+ InputStream attBody = msg.getContent(InputStream.class);
+ try (ByteArrayOutputStream attOut = new ByteArrayOutputStream()) {
+ IOUtils.copy(attBody, attOut);
+ assertEquals("<soap:Body/>", attOut.toString());
+ }
+ }
+ }
+
+ @Test
+ public void testMessageMTOM() throws Exception {
+ doTestMessageMTOM("test.xml", "<test.xml>", "test.xml");
+ }
+
+ @Test
+ public void testMessageMTOMCid() throws Exception {
+ doTestMessageMTOM("cid:http%3A%2F%2Fcxf.apache.org%2F", "<http://cxf.apache.org/>", "http://cxf.apache.org/");
+ }
+
+ @Test
+ public void testMessageMTOMUrlDecoded() throws Exception {
+ doTestMessageMTOM("test+me.xml", "<test%2Bme.xml>", "test+me.xml");
+ }
+
+ private void doTestMessageMTOM(String contentId, String expectedEncocedContentId,
+ String expectedDecocedContentId) throws Exception {
+ MessageImpl msg = new MessageImpl();
+
+ Collection<Attachment> atts = new ArrayList<>();
+ AttachmentImpl a = new AttachmentImpl(contentId);
+
+ InputStream is = getClass().getResourceAsStream("my.wav");
+ ByteArrayDataSource ds = new ByteArrayDataSource(is, "application/octet-stream");
+ a.setDataHandler(new DataHandler(ds));
+
+ atts.add(a);
+
+ msg.setAttachments(atts);
+
+ // Set the SOAP content type
+ msg.put(Message.CONTENT_TYPE, "application/soap+xml");
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ msg.setContent(OutputStream.class, out);
+
+ AttachmentSerializer serializer = new AttachmentSerializer(msg);
+
+ serializer.writeProlog();
+
+ String ct = (String) msg.get(Message.CONTENT_TYPE);
+ assertTrue(ct.indexOf("multipart/related;") == 0);
+ assertTrue(ct.indexOf("start=\"<ro...@cxf.apache.org>\"") > -1);
+ assertTrue(ct.indexOf("start-info=\"application/soap+xml\"") > -1);
+
+ out.write("<soap:Body/>".getBytes());
+
+ serializer.writeAttachments();
+ out.flush();
+
+ doTestMessageRead(msg, expectedDecocedContentId);
+ }
+}
\ No newline at end of file