001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.transport.mailets;
019:
020: import org.apache.james.core.MailImpl;
021: import org.apache.james.test.mock.mailet.MockMailContext;
022: import org.apache.james.test.mock.mailet.MockMailetConfig;
023: import org.apache.mailet.Mail;
024: import org.apache.mailet.Mailet;
025:
026: import javax.mail.MessagingException;
027: import javax.mail.Session;
028: import javax.mail.internet.MimeMessage;
029: import javax.mail.internet.MimeUtility;
030:
031: import java.io.ByteArrayInputStream;
032: import java.io.ByteArrayOutputStream;
033: import java.io.IOException;
034: import java.io.UnsupportedEncodingException;
035: import java.util.Properties;
036:
037: import junit.framework.TestCase;
038:
039: /**
040: * Test encoding issues
041: *
042: * This test should also be run with the following JVM options to be sure it tests:
043: * "-Dfile.encoding=ASCII -Dmail.mime.charset=ANSI_X3.4-1968"
044: */
045: public class AddFooterTest extends TestCase {
046:
047: public AddFooterTest(String arg0)
048: throws UnsupportedEncodingException {
049: super (arg0);
050:
051: /*
052:
053: String encoding = (new InputStreamReader(System.in)).getEncoding();
054: System.out.println("System Encoding: "+encoding);
055: System.out.println("Default Java Charset:"+MimeUtility.getDefaultJavaCharset());
056: System.out.println("---------");
057: String a = "\u20AC\u00E0"; // euro char followed by an italian a with an accent System.out.println(debugString(a,"UTF-8"));
058: System.out.println(debugString(a,"UTF8"));
059: System.out.println(debugString(a,"UTF-16"));
060: System.out.println(debugString(a,"UNICODE"));
061: System.out.println(debugString(a,"ISO-8859-15"));
062: System.out.println(debugString(a,"ISO-8859-1"));
063: System.out.println(debugString(a,"CP1252"));
064: System.out.println(debugString(a,"ANSI_X3.4-1968"));
065:
066: */
067: }
068:
069: private final static char[] hexchars = { '0', '1', '2', '3', '4',
070: '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
071:
072: public String debugString(String a, String charset)
073: throws UnsupportedEncodingException {
074: byte[] bytes = a.getBytes(charset);
075: StringBuffer res = new StringBuffer();
076: for (int i = 0; i < bytes.length; i++) {
077: if (i > 0)
078: res.append("-");
079: res.append(hexchars[((bytes[i] + 256) % 256) / 16]);
080: res.append(hexchars[((bytes[i] + 256) % 256) % 16]);
081: }
082: res.append(" (");
083: res.append(MimeUtility.mimeCharset(charset));
084: res.append(" / ");
085: res.append(MimeUtility.javaCharset(charset));
086: res.append(")");
087: return res.toString();
088: }
089:
090: /*
091: * Class under test for String getSubject()
092: */
093: public void testAddFooterTextPlain() throws MessagingException,
094: IOException {
095:
096: // quoted printable mimemessage text/plain
097: String asciisource = "Subject: test\r\nContent-Type: text/plain; charset=ISO-8859-15\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nTest=E0 and one\r\n";
098:
099: String iso885915qpheader = "------ my footer =E0/=A4 ------";
100: String footer = "------ my footer \u00E0/\u20AC ------";
101:
102: String res = processAddFooter(asciisource, footer);
103:
104: assertEquals(asciisource + iso885915qpheader, res);
105:
106: }
107:
108: public void testUnsupportedEncoding() throws MessagingException,
109: IOException {
110:
111: // quoted printable mimemessage text/plain
112: String asciisource = "Subject: test\r\nContent-Type: text/plain; charset=UNSUPPORTED_ENCODING\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nTest=E0 and one\r\n";
113:
114: String footer = "------ my footer \u00E0/\u20AC ------";
115:
116: try {
117: String res = processAddFooter(asciisource, footer);
118: assertEquals(asciisource, res);
119: } catch (Exception e) {
120: fail("should not throw an exception: " + e.getMessage());
121: }
122:
123: }
124:
125: /*
126: * Test for JAMES-443
127: * This should not add the header and should leave the multipart/mixed Content-Type intact
128: */
129: public void testAddFooterMimeNestedUnsupportedMultipart()
130: throws MessagingException, IOException {
131:
132: // quoted printable mimemessage text/plain
133: String asciisource = "MIME-Version: 1.0\r\n"
134: + "Content-Type: multipart/mixed; boundary=\"===============0204599088==\"\r\n"
135: + "\r\n"
136: + "This is a cryptographically signed message in MIME format.\r\n"
137: + "\r\n"
138: + "--===============0204599088==\r\n"
139: + "Content-Type: multipart/unsupported; boundary=\"------------ms050404020900070803030808\"\r\n"
140: + "\r\n"
141: + "--------------ms050404020900070803030808\r\n"
142: + "Content-Type: text/plain; charset=ISO-8859-1\r\n"
143: + "\r\n" + "test\r\n" + "\r\n"
144: + "--------------ms050404020900070803030808--\r\n"
145: + "\r\n" + "--===============0204599088==--\r\n";
146: // String asciisource = "Subject: test\r\nContent-Type: multipart/mixed; boundary=\"===============0204599088==\"\r\nMIME-Version: 1.0\r\n\r\nThis is a cryptographically signed message in MIME format.\r\n\r\n--===============0204599088==\r\nContent-Type: text/plain\r\n\r\ntest\r\n--===============0204599088==\r\nContent-Type: text/plain; charset=\"us-ascii\"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 7bit\r\nContent-Disposition: inline\r\n\r\ntest\r\n--===============0204599088==--\r\n";
147:
148: String footer = "------ my footer \u00E0/\u20AC ------";
149:
150: String res = processAddFooter(asciisource, footer);
151:
152: assertEquals(asciisource, res);
153:
154: }
155:
156: /*
157: * Test for JAMES-368
158: * AddFooter couldn't process mails which MimeType is multipart/related
159: */
160: public void testAddFooterMultipartRelated()
161: throws MessagingException, IOException {
162:
163: // quoted printable mimemessage text/plain
164: String asciisource = "MIME-Version: 1.0\r\n"
165: + "Subject: test\r\n"
166: + "Content-Type: multipart/related;\r\n"
167: + " boundary=\"------------050206010102010306090507\"\r\n"
168: + "\r\n"
169: + "--------------050206010102010306090507\r\n"
170: + "Content-Type: text/html; charset=ISO-8859-15\r\n"
171: + "Content-Transfer-Encoding: quoted-printable\r\n"
172: + "\r\n"
173: + "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"
174: + "<html>\r\n"
175: + "<head>\r\n"
176: + "<meta content=3D\"text/html;charset=3DISO-8859-15\" http-equiv=3D\"Content-Typ=\r\n"
177: + "e\">\r\n"
178: + "</head>\r\n"
179: + "<body bgcolor=3D\"#ffffff\" text=3D\"#000000\">\r\n"
180: + "<br>\r\n"
181: + "<div class=3D\"moz-signature\">-- <br>\r\n"
182: + "<img src=3D\"cid:part1.02060605.123@zzz.com\" border=3D\"0\"></div>\r\n";
183: String asciifoot = "</body>\r\n" + "</html>\r\n" + "\r\n"
184: + "--------------050206010102010306090507\r\n"
185: + "Content-Type: image/gif\r\n"
186: + "Content-Transfer-Encoding: base64\r\n"
187: + "Content-ID: <part1.02060605.123@zzz.com>\r\n"
188: + "Content-Disposition: inline;\r\n" + "\r\n"
189: + "YQ==\r\n"
190: + "--------------050206010102010306090507--\r\n";
191:
192: // String asciisource = "Subject: test\r\nContent-Type: multipart/mixed; boundary=\"===============0204599088==\"\r\nMIME-Version: 1.0\r\n\r\nThis is a cryptographically signed message in MIME format.\r\n\r\n--===============0204599088==\r\nContent-Type: text/plain\r\n\r\ntest\r\n--===============0204599088==\r\nContent-Type: text/plain; charset=\"us-ascii\"\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: 7bit\r\nContent-Disposition: inline\r\n\r\ntest\r\n--===============0204599088==--\r\n";
193:
194: String footer = "------ my footer \u00E0/\u20AC ------";
195: String expectedFooter = "<br>------ my footer =E0/=A4 ------";
196:
197: String res = processAddFooter(asciisource + asciifoot, footer);
198:
199: assertEquals(asciisource + expectedFooter + asciifoot, res);
200:
201: }
202:
203: /*
204: * Class under test for String getSubject()
205: */
206: public void testAddFooterTextPlainISO8859()
207: throws MessagingException, IOException {
208:
209: // quoted printable mimemessage text/plain
210: String asciisource = "Subject: test\r\nContent-Type: text/plain; charset=iso-8859-15\r\nMIME-Version: 1.0\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nTest=E0 and one =A4\r\n";
211:
212: String iso885915qpheader = "------ my footer =E0/=A4 ------";
213: String footer = "------ my footer \u00E0/\u20AC ------";
214:
215: String res = processAddFooter(asciisource, footer);
216:
217: assertEquals(asciisource + iso885915qpheader, res);
218:
219: }
220:
221: /*
222: * Class under test for String getSubject()
223: */
224: public void testAddFooterMultipartAlternative()
225: throws MessagingException, IOException {
226:
227: String sep = "--==--";
228: String head = "Subject: test\r\nContent-Type: multipart/alternative;\r\n boundary=\""
229: + sep + "\"\r\nMIME-Version: 1.0\r\n";
230: String content1 = "Content-Type: text/plain;\r\n charset=\"ISO-8859-15\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\nTest=E0 and @=80";
231: String c2h = "Content-Type: text/html;\r\n charset=\"CP1252\"\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n";
232: String c2pre = "<html><body>test =80 ss";
233: String c2post = "</body></html>";
234:
235: StringBuffer asciisource = new StringBuffer();
236: asciisource.append(head);
237: asciisource.append("\r\n--");
238: asciisource.append(sep);
239: asciisource.append("\r\n");
240: asciisource.append(content1);
241: asciisource.append("\r\n--");
242: asciisource.append(sep);
243: asciisource.append("\r\n");
244: asciisource.append(c2h);
245: asciisource.append(c2pre);
246: asciisource.append(c2post);
247: asciisource.append("\r\n--");
248: asciisource.append(sep);
249: asciisource.append("--\r\n");
250:
251: String iso885915qpheader = "------ my footer =E0/=A4 ------";
252: String cp1252qpfooter = "------ my footer =E0/=80 ------";
253: String footer = "------ my footer \u00E0/\u20AC ------";
254:
255: StringBuffer expected = new StringBuffer();
256: expected.append(head);
257: expected.append("\r\n--");
258: expected.append(sep);
259: expected.append("\r\n");
260: expected.append(content1);
261: expected.append("\r\n");
262: expected.append(iso885915qpheader);
263: expected.append("\r\n--");
264: expected.append(sep);
265: expected.append("\r\n");
266: expected.append(c2h);
267: expected.append(c2pre);
268: expected.append("<br>");
269: expected.append(cp1252qpfooter);
270: expected.append(c2post);
271: expected.append("\r\n--");
272: expected.append(sep);
273: expected.append("--\r\n");
274:
275: String res = processAddFooter(asciisource.toString(), footer);
276:
277: assertEquals(expected.toString(), res);
278:
279: }
280:
281: private String processAddFooter(String asciisource, String footer)
282: throws MessagingException, IOException {
283: Mailet mailet = new AddFooter();
284:
285: MockMailetConfig mci = new MockMailetConfig("Test",
286: new MockMailContext());
287: mci.setProperty("text", footer);
288:
289: mailet.init(mci);
290:
291: Mail mail = new MailImpl(new MimeMessage(Session
292: .getDefaultInstance(new Properties()),
293: new ByteArrayInputStream(asciisource.getBytes())));
294:
295: mailet.service(mail);
296:
297: ByteArrayOutputStream rawMessage = new ByteArrayOutputStream();
298: mail.getMessage().writeTo(rawMessage,
299: new String[] { "Bcc", "Content-Length", "Message-ID" });
300: String res = rawMessage.toString();
301: return res;
302: }
303:
304: }
|