diff --git a/src/com/fsck/k9/activity/MessageCompose.java b/src/com/fsck/k9/activity/MessageCompose.java index 5d9d3759a..8a79039a7 100644 --- a/src/com/fsck/k9/activity/MessageCompose.java +++ b/src/com/fsck/k9/activity/MessageCompose.java @@ -78,10 +78,10 @@ import com.fsck.k9.mail.internet.MimeMessage; import com.fsck.k9.mail.internet.MimeMultipart; import com.fsck.k9.mail.internet.MimeUtility; import com.fsck.k9.mail.internet.TextBody; -import com.fsck.k9.mail.store.LocalStore; import com.fsck.k9.mail.store.LocalStore.LocalAttachmentBody; import com.fsck.k9.view.MessageWebView; import org.apache.james.mime4j.codec.EncoderUtil; +import org.apache.james.mime4j.util.MimeUtil; import org.htmlcleaner.CleanerProperties; import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.SimpleHtmlSerializer; @@ -1473,9 +1473,12 @@ public class MessageCompose extends K9Activity implements OnClickListener { private void addAttachmentsToMessage(final MimeMultipart mp) throws MessagingException { for (int i = 0, count = mAttachments.getChildCount(); i < count; i++) { Attachment attachment = (Attachment) mAttachments.getChildAt(i).getTag(); + String contentType = attachment.contentType; + String encoding = (MimeUtil.isMessage(contentType)? "8bit" : "base64"); - MimeBodyPart bp = new MimeBodyPart( - new LocalStore.LocalAttachmentBody(attachment.uri, getApplication())); + LocalAttachmentBody body = new LocalAttachmentBody(attachment.uri, getApplication()); + MimeBodyPart bp = new MimeBodyPart(body); + body.setEncoding(encoding); /* * Correctly encode the filename here. Otherwise the whole @@ -1483,11 +1486,11 @@ public class MessageCompose extends K9Activity implements OnClickListener { * MimeHeader.writeTo(). */ bp.addHeader(MimeHeader.HEADER_CONTENT_TYPE, String.format("%s;\n name=\"%s\"", - attachment.contentType, + contentType, EncoderUtil.encodeIfNecessary(attachment.name, EncoderUtil.Usage.WORD_ENTITY, 7))); - bp.addHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64"); + bp.addHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, encoding); /* * TODO: Oh the joys of MIME... diff --git a/src/com/fsck/k9/mail/Body.java b/src/com/fsck/k9/mail/Body.java index 7deb2a1eb..bb990b3f2 100644 --- a/src/com/fsck/k9/mail/Body.java +++ b/src/com/fsck/k9/mail/Body.java @@ -5,7 +5,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import com.fsck.k9.mail.store.UnavailableStorageException; + public interface Body { public InputStream getInputStream() throws MessagingException; + public void setEncoding(String encoding) throws UnavailableStorageException; public void writeTo(OutputStream out) throws IOException, MessagingException; } diff --git a/src/com/fsck/k9/mail/store/LocalStore.java b/src/com/fsck/k9/mail/store/LocalStore.java index 5575499a7..b75c37375 100644 --- a/src/com/fsck/k9/mail/store/LocalStore.java +++ b/src/com/fsck/k9/mail/store/LocalStore.java @@ -25,6 +25,7 @@ import java.util.UUID; import java.util.regex.Pattern; import org.apache.commons.io.IOUtils; +import org.apache.james.mime4j.util.MimeUtil; import android.app.Application; import android.content.ContentResolver; @@ -1936,6 +1937,7 @@ public class LocalStore extends Store implements Serializable { String contentUri = cursor.getString(5); String contentId = cursor.getString(6); String contentDisposition = cursor.getString(7); + String encoding = (MimeUtil.isMessage(type)? "8bit" : "base64"); Body body = null; if (contentDisposition == null) { @@ -1944,10 +1946,11 @@ public class LocalStore extends Store implements Serializable { if (contentUri != null) { body = new LocalAttachmentBody(Uri.parse(contentUri), mApplication); + ((LocalAttachmentBody) body).setEncoding(encoding); } MimeBodyPart bp = new LocalAttachmentBodyPart(body, id); - bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, "base64"); + bp.setHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING, encoding); if (name != null) { bp.setHeader(MimeHeader.HEADER_CONTENT_TYPE, String.format("%s;\n name=\"%s\"", @@ -3988,6 +3991,7 @@ public class LocalStore extends Store implements Serializable { private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; private Application mApplication; private Uri mUri; + private String mEncoding; public LocalAttachmentBody(Uri uri, Application application) { mApplication = application; @@ -4011,11 +4015,21 @@ public class LocalStore extends Store implements Serializable { public void writeTo(OutputStream out) throws IOException, MessagingException { InputStream in = getInputStream(); try { - Base64OutputStream base64Out = new Base64OutputStream(out); + + // TODO: attachments of type rfc822 are sent with 8bit encoding + // without regard to the SMTP server's support of 8BITMIME, whereas + // strict protocol compliance requires that they be converted to + // 7bit in the (unlikely) event that 8BITMIME is not supported. + + if (MimeUtil.isBase64Encoding(mEncoding)) { + out = new Base64OutputStream(out); + } try { - IOUtils.copy(in, base64Out); + IOUtils.copy(in, out); } finally { - base64Out.close(); + if (MimeUtil.isBase64Encoding(mEncoding)) { + out.close(); + } } } finally { in.close(); @@ -4025,6 +4039,10 @@ public class LocalStore extends Store implements Serializable { public Uri getContentUri() { return mUri; } + + public void setEncoding(String encoding) { + mEncoding = encoding; + } } static class ThreadInfo {