Skip to content

Commit

Permalink
CAMEL-12630: better attachment handling in came...
Browse files Browse the repository at this point in the history
...l-mail component
  • Loading branch information
zregvart committed Jul 9, 2018
1 parent a232dfa commit a0d25d9
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 2 deletions.
6 changes: 6 additions & 0 deletions components/camel-mail/pom.xml
Expand Up @@ -119,6 +119,12 @@
<artifactId>camel-quartz2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
@@ -0,0 +1,59 @@
/**
* 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.camel.component.mail;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.activation.DataSource;

import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;

final class DelegatingDataSource implements DataSource {

private final DataSource delegate;

private final String name;

public DelegatingDataSource(final String name, final DataSource delegate) {
this.name = StringHelper.notEmpty(name, "name");
this.delegate = ObjectHelper.notNull(delegate, "DataSource");
}

@Override
public String getContentType() {
return delegate.getContentType();
}

@Override
public InputStream getInputStream() throws IOException {
return delegate.getInputStream();
}

@Override
public String getName() {
return name;
}

@Override
public OutputStream getOutputStream() throws IOException {
return delegate.getOutputStream();
}

}
Expand Up @@ -52,6 +52,7 @@
import org.apache.camel.impl.DefaultHeaderFilterStrategy;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.util.CollectionHelper;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
Expand Down Expand Up @@ -314,7 +315,7 @@ protected void extractAttachmentsFromMultipart(Multipart mp, Map<String, Attachm
extractAttachmentsFromMultipart((Multipart) part.getContent(), map);
} else {
String disposition = part.getDisposition();
String fileName = part.getFileName();
String fileName = FileUtil.stripPath(part.getFileName());

if (LOG.isTraceEnabled()) {
LOG.trace("Part #{}: Disposition: {}", i, disposition);
Expand All @@ -330,7 +331,11 @@ protected void extractAttachmentsFromMultipart(Multipart mp, Map<String, Attachm
LOG.debug("Mail contains file attachment: {}", fileName);
if (!map.containsKey(fileName)) {
// Parts marked with a disposition of Part.ATTACHMENT are clearly attachments
DefaultAttachment camelAttachment = new DefaultAttachment(part.getDataHandler());
final DataHandler dataHandler = part.getDataHandler();
final DataSource dataSource = dataHandler.getDataSource();

final DataHandler replacement = new DataHandler(new DelegatingDataSource(fileName, dataSource));
DefaultAttachment camelAttachment = new DefaultAttachment(replacement);
@SuppressWarnings("unchecked")
Enumeration<Header> headers = part.getAllHeaders();
while (headers.hasMoreElements()) {
Expand Down
@@ -0,0 +1,75 @@
/**
* 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.camel.component.mail;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.camel.Attachment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(Parameterized.class)
public class MailBindingAttachmentFileTest {

@Parameter
public String name;

private final MailBinding binding = new MailBinding();

@Test
public void shouldSanitizeAttachmentFileNames() throws MessagingException, IOException {
final Session session = Session.getInstance(new Properties());
final Message message = new MimeMessage(session);

final Multipart multipart = new MimeMultipart();
final MimeBodyPart part = new MimeBodyPart();
part.attachFile(name);
multipart.addBodyPart(part);
message.setContent(multipart);

final Map<String, Attachment> attachments = new HashMap<>();
binding.extractAttachmentsFromMail(message, attachments);

assertThat(attachments).containsKey("file.txt");
final Attachment attachment = attachments.get("file.txt");
final DataHandler dataHandler = attachment.getDataHandler();
assertThat(dataHandler.getName()).isEqualTo("file.txt");
}

@Parameters(name = "{0}")
public static Iterable<String> fileNames() {
return Arrays.asList("file.txt", "../file.txt", "..\\file.txt", "/absolute/file.txt", "c:\\absolute\\file.txt");
}
}

0 comments on commit a0d25d9

Please sign in to comment.