1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.transport.mailets;
21  
22  import org.apache.mailet.base.test.FakeMail;
23  import org.apache.mailet.base.test.FakeMailContext;
24  import org.apache.mailet.base.test.FakeMailetConfig;
25  import org.apache.mailet.Mail;
26  import org.apache.mailet.Mailet;
27  
28  import javax.mail.MessagingException;
29  import javax.mail.Session;
30  import javax.mail.internet.MimeBodyPart;
31  import javax.mail.internet.MimeMessage;
32  import javax.mail.internet.MimeMultipart;
33  
34  import java.io.ByteArrayInputStream;
35  import java.io.ByteArrayOutputStream;
36  import java.io.File;
37  import java.io.FileInputStream;
38  import java.io.IOException;
39  import java.io.InputStream;
40  import java.util.Collection;
41  import java.util.Properties;
42  
43  import junit.framework.TestCase;
44  
45  public class StripAttachmentTest extends TestCase {
46  
47      public void testNoAttachment() {
48  
49      }
50  
51      public void testSimpleAttachment() throws MessagingException, IOException {
52          Mailet mailet = initMailet();
53  
54          MimeMessage message = new MimeMessage(Session
55                  .getDefaultInstance(new Properties()));
56  
57          MimeMultipart mm = new MimeMultipart();
58          MimeBodyPart mp = new MimeBodyPart();
59          mp.setText("simple text");
60          mm.addBodyPart(mp);
61          String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
62          MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
63                  ("Content-Transfer-Encoding: 8bit\r\nContent-Type: application/octet-stream; charset=utf-8\r\n\r\n" + body).getBytes("UTF-8")));
64          mp2.setDisposition("attachment");
65          mp2.setFileName("10.tmp");
66          mm.addBodyPart(mp2);
67          String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
68          MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
69                  ("Content-Transfer-Encoding: 8bit\r\nContent-Type: application/octet-stream; charset=utf-8\r\n\r\n" + body2).getBytes("UTF-8")));
70          mp3.setDisposition("attachment");
71          mp3.setFileName("temp.zip");
72          mm.addBodyPart(mp3);
73          message.setSubject("test");
74          message.setContent(mm);
75          message.saveChanges();
76  
77          Mail mail = new FakeMail();
78          mail.setMessage(message);
79  
80          mailet.service(mail);
81  
82          ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
83          mail.getMessage().writeTo(rawMessage,
84                  new String[] { "Bcc", "Content-Length", "Message-ID" });
85  
86          Collection c = (Collection) mail
87                  .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
88          assertNotNull(c);
89  
90          assertEquals(1, c.size());
91  
92          String name = (String) c.iterator().next();
93  
94          File f = new File("./"+name);
95          InputStream is = new FileInputStream(f);
96          String savedFile = toString(is);
97          is.close();
98          assertEquals(body, savedFile);
99  
100         f.delete();
101 
102     }
103 
104     public String toString(final InputStream is) throws IOException {
105         final ByteArrayOutputStream sw = new ByteArrayOutputStream();
106         final byte[] buffer = new byte[1024];
107         int n = 0;
108         while (-1 != (n = is.read(buffer))) {
109             System.err.println(new String(buffer,0,n));
110             sw.write(buffer, 0, n);
111         }
112         return sw.toString("UTF-8");
113     }
114 
115     public void testSimpleAttachment2() throws MessagingException, IOException {
116         Mailet mailet = new StripAttachment();
117 
118         FakeMailetConfig mci = new FakeMailetConfig("Test",
119                 new FakeMailContext());
120         mci.setProperty("directory", "./");
121         mci.setProperty("remove", "all");
122         mci.setProperty("notpattern", "^(winmail\\.dat$)");
123         mailet.init(mci);
124 
125         MimeMessage message = new MimeMessage(Session
126                 .getDefaultInstance(new Properties()));
127 
128         MimeMultipart mm = new MimeMultipart();
129         MimeBodyPart mp = new MimeBodyPart();
130         mp.setText("simple text");
131         mm.addBodyPart(mp);
132         String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
133         MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
134                 ("Content-Transfer-Encoding: 8bit\r\n\r\n" + body).getBytes("UTF-8")));
135         mp2.setDisposition("attachment");
136         mp2.setFileName("temp.tmp");
137         mm.addBodyPart(mp2);
138         String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
139         MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
140                 ("Content-Transfer-Encoding: 8bit\r\n\r\n" + body2).getBytes("UTF-8")));
141         mp3.setDisposition("attachment");
142         mp3.setFileName("winmail.dat");
143         mm.addBodyPart(mp3);
144         message.setSubject("test");
145         message.setContent(mm);
146         message.saveChanges();
147 
148         Mail mail = new FakeMail();
149         mail.setMessage(message);
150 
151         mailet.service(mail);
152 
153         ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
154         mail.getMessage().writeTo(rawMessage,
155                 new String[] { "Bcc", "Content-Length", "Message-ID" });
156         // String res = rawMessage.toString();
157 
158         Collection c = (Collection) mail
159                 .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
160         assertNotNull(c);
161 
162         assertEquals(1, c.size());
163 
164         String name = (String) c.iterator().next();
165 
166         File f = new File("./"+name);
167         InputStream is = new FileInputStream(f);
168         String savedFile = toString(is);
169         is.close();
170         assertEquals(body, savedFile);
171 
172         f.delete();
173 
174     }
175 
176     public void testSimpleAttachment3() throws MessagingException, IOException {
177         Mailet mailet = initMailet();
178 
179         // System.setProperty("mail.mime.decodefilename", "true");
180 
181         MimeMessage message = new MimeMessage(Session
182                 .getDefaultInstance(new Properties()));
183 
184         MimeMultipart mm = new MimeMultipart();
185         MimeBodyPart mp = new MimeBodyPart();
186         mp.setText("simple text");
187         mm.addBodyPart(mp);
188         String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
189         MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
190                 ("Content-Transfer-Encoding: 8bit\r\n\r\n" + body).getBytes("UTF-8")));
191         mp2.setDisposition("attachment");
192         mp2
193                 .setFileName("=?iso-8859-15?Q?=E9_++++Pubblicit=E0_=E9_vietata____Milano9052.tmp?=");
194         mm.addBodyPart(mp2);
195         String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
196         MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
197                 ("Content-Transfer-Encoding: 8bit\r\n\r\n" + body2).getBytes("UTF-8")));
198         mp3.setDisposition("attachment");
199         mp3.setFileName("temp.zip");
200         mm.addBodyPart(mp3);
201         message.setSubject("test");
202         message.setContent(mm);
203         message.saveChanges();
204 
205         // message.writeTo(System.out);
206         // System.out.println("--------------------------\n\n\n");
207 
208         Mail mail = new FakeMail();
209         mail.setMessage(message);
210 
211         mailet.service(mail);
212 
213         ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
214         mail.getMessage().writeTo(rawMessage,
215                 new String[] { "Bcc", "Content-Length", "Message-ID" });
216         // String res = rawMessage.toString();
217 
218         Collection c = (Collection) mail
219                 .getAttribute(StripAttachment.SAVED_ATTACHMENTS_ATTRIBUTE_KEY);
220         assertNotNull(c);
221 
222         assertEquals(1, c.size());
223 
224         String name = (String) c.iterator().next();
225         // System.out.println("--------------------------\n\n\n");
226         // System.out.println(name);
227 
228         assertTrue(name.startsWith("e_Pubblicita_e_vietata_Milano9052"));
229 
230         File f = new File("./"+name);
231         InputStream is = new FileInputStream(f);
232         String savedFile = toString(is);
233         is.close();
234         assertEquals(body, savedFile);
235 
236         f.delete();
237 
238     }
239 
240     public void testToAndFromAttributes() throws MessagingException,
241             IOException {
242         Mailet strip = new StripAttachment();
243         FakeMailetConfig mci = new FakeMailetConfig("Test",
244                 new FakeMailContext());
245         mci.setProperty("attribute", "my.attribute");
246         mci.setProperty("remove", "all");
247         mci.setProperty("notpattern", ".*\\.tmp.*");
248         strip.init(mci);
249 
250         Mailet recover = new RecoverAttachment();
251         FakeMailetConfig mci2 = new FakeMailetConfig("Test",
252                 new FakeMailContext());
253         mci2.setProperty("attribute", "my.attribute");
254         recover.init(mci2);
255 
256         Mailet onlyText = new OnlyText();
257         onlyText.init(new FakeMailetConfig("Test", new FakeMailContext()));
258 
259         MimeMessage message = new MimeMessage(Session
260                 .getDefaultInstance(new Properties()));
261 
262         MimeMultipart mm = new MimeMultipart();
263         MimeBodyPart mp = new MimeBodyPart();
264         mp.setText("simple text");
265         mm.addBodyPart(mp);
266         String body = "\u0023\u00A4\u00E3\u00E0\u00E9";
267         MimeBodyPart mp2 = new MimeBodyPart(new ByteArrayInputStream(
268                 ("Content-Transfer-Encoding: 8bit\r\nContent-Type: application/octet-stream; charset=utf-8\r\n\r\n" + body).getBytes("UTF-8")));
269         mp2.setDisposition("attachment");
270         mp2
271                 .setFileName("=?iso-8859-15?Q?=E9_++++Pubblicit=E0_=E9_vietata____Milano9052.tmp?=");
272         mm.addBodyPart(mp2);
273         String body2 = "\u0014\u00A3\u00E1\u00E2\u00E4";
274         MimeBodyPart mp3 = new MimeBodyPart(new ByteArrayInputStream(
275                 ("Content-Transfer-Encoding: 8bit\r\nContent-Type: application/octet-stream; charset=utf-8\r\n\r\n" + body2).getBytes("UTF-8")));
276         mp3.setDisposition("attachment");
277         mp3.setFileName("temp.zip");
278         mm.addBodyPart(mp3);
279         message.setSubject("test");
280         message.setContent(mm);
281         message.saveChanges();
282         Mail mail = new FakeMail();
283         mail.setMessage(message);
284 
285         assertTrue(mail.getMessage().getContent() instanceof MimeMultipart);
286         assertEquals(3, ((MimeMultipart) mail.getMessage().getContent())
287                 .getCount());
288 
289         strip.service(mail);
290 
291         assertTrue(mail.getMessage().getContent() instanceof MimeMultipart);
292         assertEquals(1, ((MimeMultipart) mail.getMessage().getContent())
293                 .getCount());
294 
295         onlyText.service(mail);
296 
297         assertFalse(mail.getMessage().getContent() instanceof MimeMultipart);
298         
299         assertEquals("simple text", mail.getMessage().getContent());
300 
301         // prova per caricare il mime message da input stream che altrimenti
302         // javamail si comporta differentemente.
303         String mimeSource = "Message-ID: <26194423.21197328775426.JavaMail.bago@bagovista>\r\nSubject: test\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=us-ascii\r\nContent-Transfer-Encoding: 7bit\r\n\r\nsimple text";
304 
305         MimeMessage mmNew = new MimeMessage(Session
306                 .getDefaultInstance(new Properties()),
307                 new ByteArrayInputStream(mimeSource.getBytes("UTF-8")));
308 
309         mmNew.writeTo(System.out);
310         mail.setMessage(mmNew);
311         
312         recover.service(mail);
313 
314         assertTrue(mail.getMessage().getContent() instanceof MimeMultipart);
315         assertEquals(2, ((MimeMultipart) mail.getMessage().getContent())
316                 .getCount());
317 
318         Object actual = ((MimeMultipart) mail.getMessage().getContent())
319                 .getBodyPart(1).getContent();
320         if (actual instanceof ByteArrayInputStream) {
321             assertEquals(body2, toString((ByteArrayInputStream) actual));
322         } else {
323             assertEquals(body2, actual);
324         }
325 
326     }
327 
328     private Mailet initMailet() throws MessagingException {
329         Mailet mailet = new StripAttachment();
330 
331         FakeMailetConfig mci = new FakeMailetConfig("Test",
332                 new FakeMailContext());
333         mci.setProperty("directory", "./");
334         mci.setProperty("remove", "all");
335         mci.setProperty("pattern", ".*\\.tmp");
336         mci.setProperty("decodeFilename", "true");
337         mci.setProperty("replaceFilenamePattern",
338                 "/[\u00C0\u00C1\u00C2\u00C3\u00C4\u00C5]/A//,"
339                         + "/[\u00C6]/AE//,"
340                         + "/[\u00C8\u00C9\u00CA\u00CB]/E//,"
341                         + "/[\u00CC\u00CD\u00CE\u00CF]/I//,"
342                         + "/[\u00D2\u00D3\u00D4\u00D5\u00D6]/O//,"
343                         + "/[\u00D7]/x//," + "/[\u00D9\u00DA\u00DB\u00DC]/U//,"
344                         + "/[\u00E0\u00E1\u00E2\u00E3\u00E4\u00E5]/a//,"
345                         + "/[\u00E6]/ae//,"
346                         + "/[\u00E8\u00E9\u00EA\u00EB]/e//,"
347                         + "/[\u00EC\u00ED\u00EE\u00EF]/i//,"
348                         + "/[\u00F2\u00F3\u00F4\u00F5\u00F6]/o//,"
349                         + "/[\u00F9\u00FA\u00FB\u00FC]/u//,"
350                         + "/[^A-Za-z0-9._-]+/_//");
351 
352         mailet.init(mci);
353         return mailet;
354     }
355 
356 }