1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-08-13 17:03:48 -04:00
k-9/src/com/fsck/k9/mail/Body.java

29 lines
980 B
Java
Raw Normal View History

package com.fsck.k9.mail;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Don't base64 encode attachments of type message/rfc822. The problem: Receive a message with an attachment of type message/rfc822 and forward it. When the message is sent, K-9 Mail uses base64 encoding for the attachment. (Alternatively, you could compose a new message and add such an attachment from a file using a filing-picking app, but that is not 100% effective because the app may not choose the correct message/rfc822 MIME type for the attachment.) Such encoding is prohibited per RFC 2046 (5.2.1) and RFC 2045 (6.4). Only 8bit or 7bit encoding is permitted for attachments of type message/rfc822. Thunderbird refuses to decode such attachments. All that is shown is the base64 encoded body. This commit implements LocalAttachmentBody.setEncoding. If an attachment to a newly composed message is itself a message, then setEncoding("8bit") is called, otherwise setEncoding("base64") is called for the attachment. Similar behavior occurs when an attachment is retrieved from LocalStore. The setEncoding method was added to the Body interface, since all implementations of Body now declare the method. The problem here differs from that in the preceding commit: Here, the encoding problem occurs on sending, not on receipt. Here, the entire message (headers and body) is base64 encoded, not just the body. Here, the headers correctly identify the encoding used; it's just that the RFC does not permit such encoding of attached messages. The problem here could in fact occur in combination with the preceding problem.
2013-09-01 16:25:09 -04:00
import com.fsck.k9.mail.store.UnavailableStorageException;
public interface Body {
/**
* Returns the raw data of the body, without transfer encoding etc applied.
* TODO perhaps it would be better to have an intermediate "simple part" class where this method could reside
* because it makes no sense for multiparts
*/
public InputStream getInputStream() throws MessagingException;
/**
* Sets the content transfer encoding (7bit, 8bit, quoted-printable or base64).
*/
Recursively convert attachments of type message/rfc822 to 7bit if necessary. The preceding commit resulted in attachments of type message/rfc822 being sent with 8bit encoding even when the SMTP server did not support 8BITMIME. This commit assures that messages will be converted to 7bit when necessary. A new interface CompositeBody was created that extends Body, and classes Message and Multipart were changed from implementing Body to CompositeBody. Additional classes BinaryTempFileMessageBody and LocalAttachmentMessageBody were created (by extending BinaryTempFileBody and LocalAttachmentBody, respectively), and they too implement CompositeBody. A CompositeBody is a Body containing a composite-type that can contain subparts that may require recursive processing when converting from 8bit to 7bit. The Part to which a CompositeBody belongs is only permitted to use 8bit or 7bit encoding for the CompositeBody. Previously, a Message was created so that it was 7bit clean by default (even though that meant base64 encoding all attachments, including messages). Then, if the SMTP server supported 8BITMIME, Message.setEncoding("8bit") was called so that bodies of type TextBody would been transmitted using 8bit encoding rather than quoted-printable. Now, messages are created with 8bit encoding by default. Then, if the SMTP server does not support 8BITMIME, Message.setUsing7bitTransport is called to recursively convert the message and its subparts to 7bit. The method setUsing7bitTransport was added to the interfaces Part and CompositeBody. setEncoding no longer iterates over parts in Multipart. That task belongs to setUsing7bitTransport, which may in turn call setEncoding on the parts. MimeUtility.getEncodingforType was created as a helper function for choosing a default encoding that should be used for a given MIME type when an attachment is added to a message (either while composing or when retrieving from LocalStore). setEncoding was implemented in MimeBodyPart to assure that the encoding set in the Part's headers was the same as set for the Part's Body. (The method already existed in MimeMessage, which has similarities with MimeBodyPart.) MimeMessage.parse(InputStream in, boolean recurse) was implemented so that the parser could be told to recursively process nested messages read from the InputStream, thus giving access to all subparts at any level that may need to be converted from 8bit to 7bit.
2013-09-02 23:49:28 -04:00
public void setEncoding(String encoding) throws UnavailableStorageException, MessagingException;
/**
* Writes the body's data to the given {@link OutputStream}.
* The written data is transfer encoded (e.g. transformed to Base64 when needed).
*/
public void writeTo(OutputStream out) throws IOException, MessagingException;
}