You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/05/25 20:42:24 UTC
svn commit: r660013 - in /james/mime4j/trunk/src:
main/java/org/apache/james/mime4j/message/
main/java/org/apache/james/mime4j/util/ test/java/org/apache/james/mime4j/
test/java/org/apache/james/mime4j/message/
Author: rdonkin
Date: Sun May 25 11:42:23 2008
New Revision: 660013
URL: http://svn.apache.org/viewvc?rev=660013&view=rev
Log:
Confirmed and fixed MIME4J-37 Wrong implementation of TempFileBinaryBody.writeTo https://issues.apache.org/jira/browse/MIME4J-37 for the binary Base64 encoded case only. Binaries transfer encoded with printed-quotable.
Added:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java (contents, props changed)
- copied, changed from r659933, james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java
Modified:
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MessageUtils.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MessageWriteToTest.java
james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/BinaryBody.java Sun May 25 11:42:23 2008
@@ -35,7 +35,7 @@
* Gets a <code>InputStream</code> which reads the bytes of the
* body.
*
- * @return the stream.
+ * @return the stream, transfer decoded
* @throws IOException on I/O errors.
*/
InputStream getInputStream() throws IOException;
Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Message.java Sun May 25 11:42:23 2008
@@ -28,12 +28,9 @@
import org.apache.james.mime4j.ContentHandler;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.MimeStreamParser;
-import org.apache.james.mime4j.decoder.Base64InputStream;
-import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
import org.apache.james.mime4j.field.Field;
import org.apache.james.mime4j.field.UnstructuredField;
import org.apache.james.mime4j.util.MessageUtils;
-import org.apache.james.mime4j.util.MimeUtil;
/**
@@ -99,7 +96,7 @@
getHeader().writeTo(out, mode);
final Body body = getBody();
- body.writeTo(out, MessageUtils.LENIENT);
+ body.writeTo(out, mode);
}
private class MessageBuilder implements ContentHandler {
@@ -179,21 +176,16 @@
/**
* @see org.apache.james.mime4j.ContentHandler#body(org.apache.james.mime4j.BodyDescriptor, java.io.InputStream)
*/
- public void body(BodyDescriptor bd, InputStream is) throws IOException {
+ public void body(BodyDescriptor bd, final InputStream is) throws IOException {
expect(Entity.class);
- String enc = bd.getTransferEncoding();
- if (MimeUtil.ENC_BASE64.equals(enc)) {
- is = new Base64InputStream(is);
- } else if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(enc)) {
- is = new QuotedPrintableInputStream(is);
- }
+ final String enc = bd.getTransferEncoding();
- Body body = null;
+ final Body body;
if (bd.getMimeType().startsWith("text/")) {
body = new TempFileTextBody(is, bd.getCharset());
} else {
- body = new TempFileBinaryBody(is);
+ body = new TempFileBinaryBody(is, enc);
}
((Entity) stack.peek()).setBody(body);
@@ -252,7 +244,7 @@
}
/**
- * TODO: Implement me
+ * TODO: Implement me... but how?
*
* @see org.apache.james.mime4j.ContentHandler#raw(java.io.InputStream)
*/
Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/Multipart.java Sun May 25 11:42:23 2008
@@ -208,7 +208,8 @@
writer.write(boundary);
writer.write(MessageUtils.CRLF);
writer.flush();
- ((BodyPart) bodyParts.get(i)).writeTo(out, mode);
+ final BodyPart bodyPart = (BodyPart) bodyParts.get(i);
+ bodyPart.writeTo(out, mode);
writer.write(MessageUtils.CRLF);
}
@@ -216,8 +217,8 @@
writer.write(boundary);
writer.write("--");
writer.write(MessageUtils.CRLF);
- writer.write(getEpilogue());
- writer.write(MessageUtils.CRLF);
+ final String epilogue = getEpilogue();
+ writer.write(epilogue);
writer.flush();
}
}
Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/message/TempFileBinaryBody.java Sun May 25 11:42:23 2008
@@ -24,8 +24,10 @@
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.apache.james.mime4j.decoder.Base64InputStream;
+import org.apache.james.mime4j.decoder.QuotedPrintableInputStream;
+import org.apache.james.mime4j.util.CodecUtil;
+import org.apache.james.mime4j.util.MimeUtil;
import org.apache.james.mime4j.util.TempFile;
import org.apache.james.mime4j.util.TempPath;
import org.apache.james.mime4j.util.TempStorage;
@@ -38,10 +40,10 @@
* @version $Id: TempFileBinaryBody.java,v 1.2 2004/10/02 12:41:11 ntherning Exp $
*/
class TempFileBinaryBody extends AbstractBody implements BinaryBody {
- private static Log log = LogFactory.getLog(TempFileBinaryBody.class);
private Entity parent = null;
private TempFile tempFile = null;
+ private final String transferEncoding;
/**
* Use the given InputStream to build the TemporyFileBinaryBody
@@ -49,13 +51,22 @@
* @param is the InputStream to use as source
* @throws IOException
*/
- public TempFileBinaryBody(InputStream is) throws IOException {
+ public TempFileBinaryBody(final InputStream is, final String transferEncoding) throws IOException {
+ this.transferEncoding = transferEncoding;
TempPath tempPath = TempStorage.getInstance().getRootTempPath();
tempFile = tempPath.createTempFile("attachment", ".bin");
OutputStream out = tempFile.getOutputStream();
- IOUtils.copy(is, out);
+ final InputStream decodedStream;
+ if (MimeUtil.ENC_BASE64.equals(transferEncoding)) {
+ decodedStream = new Base64InputStream(is);
+ } else if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(transferEncoding)) {
+ decodedStream = new QuotedPrintableInputStream(is);
+ } else {
+ decodedStream = is;
+ }
+ IOUtils.copy(decodedStream, out);
out.close();
}
@@ -84,6 +95,14 @@
* @see org.apache.james.mime4j.message.Body#writeTo(java.io.OutputStream, int)
*/
public void writeTo(OutputStream out, int mode) throws IOException {
- IOUtils.copy(getInputStream(),out);
+ final InputStream inputStream = getInputStream();
+ if (MimeUtil.ENC_BASE64.equals(transferEncoding)) {
+ CodecUtil.encodeBase64(inputStream, out);
+ out.write(CodecUtil.CRLF_CRLF);
+ } else if (MimeUtil.ENC_QUOTED_PRINTABLE.equals(transferEncoding)) {
+ IOUtils.copy(inputStream,out);
+ } else {
+ IOUtils.copy(inputStream,out);
+ }
}
}
Copied: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java (from r659933, james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java)
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java?p2=james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java&p1=james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java&r1=659933&r2=660013&rev=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/EncodeUtils.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java Sun May 25 11:42:23 2008
@@ -17,95 +17,131 @@
* under the License. *
****************************************************************/
-package org.apache.james.mime4j;
+package org.apache.james.mime4j.util;
-
-public class EncodeUtils {
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Utility methods related to codecs.
+ */
+public class CodecUtil {
+
+
+ public static final byte[] CRLF = {'\r', '\n'};
- public static final int MASK = 0x3F;
- public static final int FIRST_MASK = MASK << 18;
- public static final int SECOND_MASK = MASK << 12;
- public static final int THIRD_MASK = MASK << 6;
- public static final int FORTH_MASK = MASK;
-
- public static final byte[] ENCODING = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P' ,'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
- 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '+', '/'};
-
- public static final void main(String[] args) throws Exception {
- byte[] bytes = {(byte) 0, (byte) 128, (byte) 0};
- System.out.println(new String(toBase64(bytes)));
- System.out.println(new String(toBase64("Hello, World".getBytes())));
- System.out.println(new String(toBase64("Monday".getBytes())));
- System.out.println(new String(toBase64("M\u00F6nchengladbach\r\n".getBytes("ISO-8859-1"))));
+ public static final byte[] CRLF_CRLF = {'\r', '\n', '\r', '\n'};
+
+ private static final int DEFAULT_ENCODING_BUFFER_SIZE = 1024;
+
+ /**
+ * Encodes the given stream using Base64.
+ * @param in not null
+ * @param out not null
+ * @throws IOException
+ */
+ public static void encodeBase64(final InputStream in, final OutputStream out) throws IOException {
+ Base64Encoder encoder = new Base64Encoder(DEFAULT_ENCODING_BUFFER_SIZE);
+ encoder.encode(in, out);
}
- public static byte[] toBase64(byte[] in) {
- int inputLength = in.length;
- int outputLength = (int) Math.floor((4*inputLength) / 3f) + 3;
- outputLength = outputLength + 2 * (int) Math.floor(outputLength / 76f);
- byte[] results = new byte[outputLength];
- int inputIndex = 0;
- int outputIndex = 0;
- while (inputLength - inputIndex > 2) {
- int one = (toInt(in[inputIndex++]) << 16);
- int two = (toInt(in[inputIndex++]) << 8);
- int three = toInt(in[inputIndex++]);
- int quantum = one | two | three;
- int index = (quantum & FIRST_MASK) >> 18;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- index = (quantum & SECOND_MASK) >> 12;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- index = (quantum & THIRD_MASK) >> 6;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- index = (quantum & FORTH_MASK);
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- }
-
- switch (inputLength - inputIndex) {
- case 1:
- int quantum = in[inputIndex++] << 16;
+ private static final class Base64Encoder {
+ private static final int MASK = 0x3F;
+ private static final int FIRST_MASK = MASK << 18;
+ private static final int SECOND_MASK = MASK << 12;
+ private static final int THIRD_MASK = MASK << 6;
+ private static final int FORTH_MASK = MASK;
+
+ private static final byte[] ENCODING = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P' ,'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
+ 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/'};
+
+ private final byte[] in;
+ private final byte[] out;
+
+ public Base64Encoder(final int inputBufferSize) {
+ in = new byte[inputBufferSize];
+ int outputBufferSize = ((int) Math.floor((4*inputBufferSize) / 3f) + 3);
+ outputBufferSize = outputBufferSize + 2 * (int) Math.floor(outputBufferSize / 76f);
+ out = new byte[outputBufferSize];
+ }
+
+ public void encode(final InputStream inStream, final OutputStream outStream) throws IOException {
+ int inputLength = inStream.read(in);
+ while (inputLength > -1) {
+ int outputLength = encodeInputBuffer(inputLength);
+ if (outputLength > 0) {
+ outStream.write(out, 0, outputLength);
+ }
+ inputLength = inStream.read(in);
+ }
+ }
+
+ private int encodeInputBuffer(final int inputLength) {
+ if (inputLength == 0) {
+ return 0;
+ }
+ int inputIndex = 0;
+ int outputIndex = 0;
+ while (inputLength - inputIndex > 2) {
+ int one = (toInt(in[inputIndex++]) << 16);
+ int two = (toInt(in[inputIndex++]) << 8);
+ int three = toInt(in[inputIndex++]);
+ int quantum = one | two | three;
int index = (quantum & FIRST_MASK) >> 18;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- index = (quantum & SECOND_MASK) >> 12;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- outputIndex = setResult(results, outputIndex, (byte) '=');
- outputIndex = setResult(results, outputIndex, (byte) '=');
- break;
-
- case 2:
- quantum = (in[inputIndex++] << 16) + (in[inputIndex++] << 8);
- index = (quantum & FIRST_MASK) >> 18;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
index = (quantum & SECOND_MASK) >> 12;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
index = (quantum & THIRD_MASK) >> 6;
- outputIndex = setResult(results, outputIndex, ENCODING[index]);
- outputIndex = setResult(results, outputIndex, (byte) '=');
- break;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ index = (quantum & FORTH_MASK);
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ }
+
+ switch (inputLength - inputIndex) {
+ case 1:
+ int quantum = in[inputIndex++] << 16;
+ int index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ outputIndex = setResult(out, outputIndex, (byte) '=');
+ outputIndex = setResult(out, outputIndex, (byte) '=');
+ break;
+
+ case 2:
+ quantum = (in[inputIndex++] << 16) + (in[inputIndex++] << 8);
+ index = (quantum & FIRST_MASK) >> 18;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ index = (quantum & SECOND_MASK) >> 12;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ index = (quantum & THIRD_MASK) >> 6;
+ outputIndex = setResult(out, outputIndex, ENCODING[index]);
+ outputIndex = setResult(out, outputIndex, (byte) '=');
+ break;
+ }
+
+ return outputIndex;
}
- return results;
- }
-
- private static int toInt(byte b) {
- return (int)(b & 255);
- }
-
-
- private static int setResult(byte[] results, int outputIndex, byte value) {
- results[outputIndex++] = value;
- outputIndex = checkLineLength(results, outputIndex);
- return outputIndex;
- }
+ private int toInt(byte b) {
+ return (int)(b & 255);
+ }
+ private int setResult(byte[] results, int outputIndex, byte value) {
+ results[outputIndex++] = value;
+ outputIndex = checkLineLength(results, outputIndex);
+ return outputIndex;
+ }
- private static int checkLineLength(byte[] results, int outputIndex) {
- if (outputIndex == 76 || outputIndex > 76 && (outputIndex - 2*Math.floor(outputIndex/76f - 1)) % 76 == 0) {
- results[outputIndex++] = '\r';
- results[outputIndex++] = '\n';
+ private int checkLineLength(byte[] results, int outputIndex) {
+ if (outputIndex == 76 || outputIndex > 76 && (outputIndex - 2*Math.floor(outputIndex/76f - 1)) % 76 == 0) {
+ results[outputIndex++] = '\r';
+ results[outputIndex++] = '\n';
+ }
+ return outputIndex;
}
- return outputIndex;
}
}
Propchange: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/CodecUtil.java
------------------------------------------------------------------------------
svn:mergeinfo =
Modified: james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MessageUtils.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MessageUtils.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MessageUtils.java (original)
+++ james/mime4j/trunk/src/main/java/org/apache/james/mime4j/util/MessageUtils.java Sun May 25 11:42:23 2008
@@ -38,7 +38,7 @@
public static final Charset ISO_8859_1 = CharsetUtil.getCharset("ISO-8859-1");
public static final Charset DEFAULT_CHARSET = ASCII;
-
+
public static final String CRLF = "\r\n";
public static boolean isASCII(char ch) {
@@ -57,5 +57,4 @@
}
return true;
}
-
}
Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/ExampleMail.java Sun May 25 11:42:23 2008
@@ -25,6 +25,157 @@
public static final Charset US_ASCII = Charset.forName("US-ASCII");
public static final Charset LATIN1 = Charset.forName("ISO-8859-1");
+ public static final String MULTIPART_WITH_BINARY_ATTACHMENTS =
+ "Return-Path: <ro...@blueyonder.co.uk>\r\n" +
+ "Received: (qmail 18554 invoked from network); 25 May 2008 14:38:53 -0000\r\n" +
+ "Received: from unknown (HELO p3presmtp01-16.prod.phx3.secureserver.net)\r\n" +
+ " ([208.109.80.165]) (envelope-sender <rd...@locus.apache.org>) by\r\n" +
+ " smtp20-01.prod.mesa1.secureserver.net (qmail-1.03) with SMTP for\r\n" +
+ " <as...@xmlmapt.org>; 25 May 2008 14:38:53 -0000\r\n" +
+ "Received: (qmail 9751 invoked from network); 25 May 2008 14:38:53 -0000\r\n" +
+ "Received: from minotaur.apache.org ([140.211.11.9]) (envelope-sender\r\n" +
+ " <rd...@locus.apache.org>) by\r\n" +
+ " p3presmtp01-16.prod.phx3.secureserver.net (qmail-ldap-1.03) with SMTP for\r\n" +
+ " <as...@xmlmapt.org>; 25 May 2008 14:38:50 -0000\r\n" +
+ "Received: (qmail 46768 invoked by uid 1289); 25 May 2008 14:38:46 -0000\r\n" +
+ "Delivered-To: rdonkin@locus.apache.org\r\n" +
+ "Received: (qmail 46763 invoked from network); 25 May 2008 14:38:46 -0000\r\n" +
+ "Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by\r\n" +
+ " minotaur.apache.org with SMTP; 25 May 2008 14:38:46 -0000\r\n" +
+ "Received: (qmail 61275 invoked by uid 500); 25 May 2008 14:38:48 -0000\r\n" +
+ "Delivered-To: apmail-rdonkin@apache.org\r\n" +
+ "Delivered-To: rob@localhost\r\n" +
+ "Delivered-To: rob@localhost\r\n" +
+ "Received: (qmail 61272 invoked by uid 99); 25 May 2008 14:38:48 -0000\r\n" +
+ "Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136)\r\n" +
+ " by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 25 May 2008 07:38:48 -0700\r\n" +
+ "X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS\r\n" +
+ "X-Spam-Check-By: apache.org\r\n" +
+ "Received-SPF: pass (athena.apache.org: domain of\r\n" +
+ " robertburrelldonkin@blueyonder.co.uk designates 195.188.213.5 as permitted\r\n" +
+ " sender)\r\n" +
+ "Received: from [195.188.213.5] (HELO smtp-out2.blueyonder.co.uk)\r\n" +
+ " (195.188.213.5) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 25 May 2008\r\n" +
+ " 14:38:00 +0000\r\n" +
+ "Received: from [172.23.170.140] (helo=anti-virus02-07) by\r\n" +
+ " smtp-out2.blueyonder.co.uk with smtp (Exim 4.52) id 1K0HMV-00087e-HY for\r\n" +
+ " rdonkin@apache.org; Sun, 25 May 2008 15:38:15 +0100\r\n" +
+ "Received: from [82.38.65.6] (helo=[10.0.0.27]) by\r\n" +
+ " asmtp-out5.blueyonder.co.uk with esmtpa (Exim 4.52) id 1K0HMU-0001A2-3q for\r\n" +
+ " rdonkin@apache.org; Sun, 25 May 2008 15:38:14 +0100\r\n" +
+ "Subject: This is an example of a multipart mixed email with image content\r\n" +
+ "From: Robert Burrell Donkin <ro...@blueyonder.co.uk>\r\n" +
+ "To: Robert Burrell Donkin <rd...@apache.org>\r\n" +
+ "Content-Type: multipart/mixed; boundary=\"=-tIdGYVstQJghyEDATnJ+\"\r\n" +
+ "Date: Sun, 25 May 2008 15:38:13 +0100\r\n" +
+ "Message-Id: <12...@localhost>\r\n" +
+ "Mime-Version: 1.0\r\n" +
+ "X-Mailer: Evolution 2.12.3 \r\n" +
+ "X-Virus-Checked: Checked by ClamAV on apache.org\r\n" +
+ "X-Nonspam: None\r\n" +
+ "X-fetched-from: mail.xmlmapt.org\r\n" +
+ "X-Evolution-Source: imap://rob@thebes/\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "--=-tIdGYVstQJghyEDATnJ+\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "Content-Transfer-Encoding: 7bit\r\n" +
+ "\r\n" +
+ "Licensed to the Apache Software Foundation (ASF) under one\r\n" +
+ "or more contributor license agreements. See the NOTICE file\r\n" +
+ "distributed with this work for additional information\r\n" +
+ "regarding copyright ownership. The ASF licenses this file\r\n" +
+ "to you under the Apache License, Version 2.0 (the\r\n" +
+ "\"License\"); you may not use this file except in compliance\r\n" +
+ "with the License. You may obtain a copy of the License at\r\n" +
+ "\r\n" +
+ " http://www.apache.org/licenses/LICENSE-2.0\r\n" +
+ " \r\n" +
+ "Unless required by applicable law or agreed to in writing,\r\n" +
+ "software distributed under the License is distributed on an\r\n" +
+ "\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n" +
+ "KIND, either express or implied. See the License for the\r\n" +
+ "specific language governing permissions and limitations\r\n" +
+ "under the License.\r\n" +
+ " \r\n" +
+ "\r\n" +
+ "--=-tIdGYVstQJghyEDATnJ+\r\n" +
+ "Content-Disposition: attachment; filename=blob.png\r\n" +
+ "Content-Type: image/png; name=blob.png\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "\r\n" +
+ "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAL\r\n" +
+ "EwAACxMBAJqcGAAAAAd0SU1FB9gFGQ4iJ99ufcYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRo\r\n" +
+ "IEdJTVBXgQ4XAAAA0ElEQVQY02XMwUrDQBhF4XsnkyYhjWJaCloEN77/a/gERVwJLQiiNjYmbTqZ\r\n" +
+ "/7qIG/VsPziMTw+23Wj/ovZdMQJgViCvWNVusfa23djuUf2nugbnI2RynkWF5a2Fwdvrs7q9vhqE\r\n" +
+ "E2QAEIO6BhZBerUf6luMw49NyTR0OLw5kJD9sqk4Ipwc6GAREv5n5piXTDOQfy1JMSs8ZgXKq2kF\r\n" +
+ "iwDgEriEecnLlefFEmGAIvqD4ggJJNMM85qLtXfX9xYGuEQ+4/kIi0g88zlXd66++QaQDG5GPZyp\r\n" +
+ "rQAAAABJRU5ErkJggg==\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "--=-tIdGYVstQJghyEDATnJ+\r\n" +
+ "Content-Disposition: attachment; filename=blob.png\r\n" +
+ "Content-Type: image/png; name=blob.png\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "\r\n" +
+ "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAL\r\n" +
+ "EwAACxMBAJqcGAAAAAd0SU1FB9gFGQ4iJ99ufcYAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRo\r\n" +
+ "IEdJTVBXgQ4XAAAA0ElEQVQY02XMwUrDQBhF4XsnkyYhjWJaCloEN77/a/gERVwJLQiiNjYmbTqZ\r\n" +
+ "/7qIG/VsPziMTw+23Wj/ovZdMQJgViCvWNVusfa23djuUf2nugbnI2RynkWF5a2Fwdvrs7q9vhqE\r\n" +
+ "E2QAEIO6BhZBerUf6luMw49NyTR0OLw5kJD9sqk4Ipwc6GAREv5n5piXTDOQfy1JMSs8ZgXKq2kF\r\n" +
+ "iwDgEriEecnLlefFEmGAIvqD4ggJJNMM85qLtXfX9xYGuEQ+4/kIi0g88zlXd66++QaQDG5GPZyp\r\n" +
+ "rQAAAABJRU5ErkJggg==\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "--=-tIdGYVstQJghyEDATnJ+\r\n" +
+ "Content-Disposition: attachment; filename=rhubarb.txt\r\n" +
+ "Content-Type: text/plain; name=rhubarb.txt; charset=us-ascii\r\n" +
+ "Content-Transfer-Encoding: quoted-printable\r\n" +
+ "\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=\r\n" +
+ "barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=\r\n" +
+ "b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=\r\n" +
+ "hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=\r\n" +
+ "arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=\r\n" +
+ " Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=\r\n" +
+ "ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=\r\n" +
+ "rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=\r\n" +
+ "barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=\r\n" +
+ "b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=\r\n" +
+ "hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=\r\n" +
+ "arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=\r\n" +
+ " Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=\r\n" +
+ "ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=\r\n" +
+ "rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=\r\n" +
+ "barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=\r\n" +
+ "b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=\r\n" +
+ "hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=\r\n" +
+ "arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=\r\n" +
+ " Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=\r\n" +
+ "ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=\r\n" +
+ "rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=\r\n" +
+ "barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=\r\n" +
+ "b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=\r\n" +
+ "hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=\r\n" +
+ "arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=\r\n" +
+ " Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=\r\n" +
+ "ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=\r\n" +
+ "rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhu=\r\n" +
+ "barb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubar=\r\n" +
+ "b Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb R=\r\n" +
+ "hubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhub=\r\n" +
+ "arb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb=\r\n" +
+ " Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rh=\r\n" +
+ "ubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhuba=\r\n" +
+ "rb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb =\r\n" +
+ "Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb Rhubarb\r\n" +
+ "\r\n" +
+ "--=-tIdGYVstQJghyEDATnJ+--\r\n";
+
public static final String ONE_PART_MIME_ASCII_BODY = "A single part MIME mail.\r\n";
public static final String RFC822_SIMPLE_BODY = "This is a very simple email.\r\n";
@@ -246,7 +397,8 @@
public static final byte[] RFC822_SIMPLE_BYTES = US_ASCII.encode(RFC_SIMPLE).array();
public static final byte[] ONE_PART_MIME_ASCII_BYTES = US_ASCII.encode(ONE_PART_MIME_ASCII).array();
public static final byte[] ONE_PART_MIME_8859_BYTES = LATIN1.encode(ONE_PART_MIME_8859).array();
-
+ public static final byte[] MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES = US_ASCII.encode(MULTIPART_WITH_BINARY_ATTACHMENTS).array();
+
public static final byte[] ascii(String text) {
return US_ASCII.encode(text).array();
Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MessageWriteToTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MessageWriteToTest.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MessageWriteToTest.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MessageWriteToTest.java Sun May 25 11:42:23 2008
@@ -41,6 +41,7 @@
assertFalse("Not multipart", message.isMultipart());
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out, MessageUtils.STRICT_IGNORE);
+ assertEquals(out.toByteArray(), ExampleMail.RFC822_SIMPLE_BYTES);
}
public void testSimpleMailStrictError() throws Exception {
@@ -48,6 +49,7 @@
assertFalse("Not multipart", message.isMultipart());
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out, MessageUtils.STRICT_ERROR);
+ assertEquals(out.toByteArray(), ExampleMail.RFC822_SIMPLE_BYTES);
}
public void testSimpleMailLenient() throws Exception {
@@ -55,6 +57,40 @@
assertFalse("Not multipart", message.isMultipart());
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out, MessageUtils.LENIENT);
+ assertEquals(out.toByteArray(), ExampleMail.RFC822_SIMPLE_BYTES);
+ }
+
+ private void assertEquals(byte[] expected, byte[] actual) {
+ StringBuffer buffer = new StringBuffer(expected.length);
+ assertEquals(expected.length, actual.length);
+ for (int i = 0; i < actual.length; i++) {
+ buffer.append((char)actual[i]);
+ assertEquals("Mismatch@" + i, expected[i], actual[i]);
+ }
+ }
+
+ public void testBinaryAttachmentLenient() throws Exception {
+ Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES);
+ assertTrue("Is multipart", message.isMultipart());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ message.writeTo(out, MessageUtils.LENIENT);
+ assertEquals(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES, out.toByteArray());
+ }
+
+ public void testBinaryAttachmentStrictError() throws Exception {
+ Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES);
+ assertTrue("Is multipart", message.isMultipart());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ message.writeTo(out, MessageUtils.STRICT_ERROR);
+ assertEquals(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES, out.toByteArray());
+ }
+
+ public void testBinaryAttachmentStrictIgnore() throws Exception {
+ Message message = createMessage(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES);
+ assertTrue("Is multipart", message.isMultipart());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ message.writeTo(out, MessageUtils.STRICT_IGNORE);
+ assertEquals(ExampleMail.MULTIPART_WITH_BINARY_ATTACHMENTS_BYTES, out.toByteArray());
}
private Message createMessage(byte[] octets) throws Exception {
Modified: james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java
URL: http://svn.apache.org/viewvc/james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java?rev=660013&r1=660012&r2=660013&view=diff
==============================================================================
--- james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java (original)
+++ james/mime4j/trunk/src/test/java/org/apache/james/mime4j/message/MultipartFormTest.java Sun May 25 11:42:23 2008
@@ -85,8 +85,7 @@
"Content-Type: text/plain\r\n" +
"\r\n" +
"all kind of stuff\r\n" +
- "--foo--\r\n" +
- "\r\n";
+ "--foo--\r\n";
String s = out.toString("US-ASCII");
assertEquals(expected, s);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org