mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-30 13:12:25 -05:00
Add helper method to decode message bodies
Depending on whether a Body implements RawDataBody (which indicates the class retains the original encoding) the helper method either strips the transfer encoding or simply returns the result of Body.getInputStream(). This should restore the original functionality. So saving messages in the database should work fine again.
This commit is contained in:
parent
f7d3eaa006
commit
d1d7b60a09
@ -15,7 +15,7 @@ import java.io.*;
|
||||
* and writeTo one time. After writeTo is called, or the InputStream returned from
|
||||
* getInputStream is closed the file is deleted and the Body should be considered disposed of.
|
||||
*/
|
||||
public class BinaryTempFileBody implements Body {
|
||||
public class BinaryTempFileBody implements RawDataBody {
|
||||
private static File mTempDirectory;
|
||||
|
||||
private File mFile;
|
||||
@ -26,6 +26,11 @@ public class BinaryTempFileBody implements Body {
|
||||
mTempDirectory = tempDirectory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncoding() {
|
||||
return mEncoding;
|
||||
}
|
||||
|
||||
public void setEncoding(String encoding) throws MessagingException {
|
||||
if (mEncoding != null && mEncoding.equalsIgnoreCase(encoding)) {
|
||||
return;
|
||||
|
@ -2,6 +2,7 @@
|
||||
package com.fsck.k9.mail.internet;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import com.fsck.k9.K9;
|
||||
import com.fsck.k9.R;
|
||||
@ -10,6 +11,7 @@ import com.fsck.k9.mail.*;
|
||||
import com.fsck.k9.mail.Message.RecipientType;
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody.BinaryTempFileBodyInputStream;
|
||||
|
||||
import com.fsck.k9.view.MessageHeader;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.james.mime4j.codec.Base64InputStream;
|
||||
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;
|
||||
@ -1026,7 +1028,7 @@ public class MimeUtility {
|
||||
* determine the charset from HTML message.
|
||||
*/
|
||||
if (mimeType.equalsIgnoreCase("text/html") && charset == null) {
|
||||
InputStream in = part.getBody().getInputStream();
|
||||
InputStream in = MimeUtility.decodeBody(part.getBody());
|
||||
try {
|
||||
byte[] buf = new byte[256];
|
||||
in.read(buf, 0, buf.length);
|
||||
@ -1062,7 +1064,7 @@ public class MimeUtility {
|
||||
* Now we read the part into a buffer for further processing. Because
|
||||
* the stream is now wrapped we'll remove any transfer encoding at this point.
|
||||
*/
|
||||
InputStream in = part.getBody().getInputStream();
|
||||
InputStream in = MimeUtility.decodeBody(part.getBody());
|
||||
try {
|
||||
String text = readToString(in, charset);
|
||||
|
||||
@ -1151,6 +1153,49 @@ public class MimeUtility {
|
||||
return tempBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decoded contents of a body.
|
||||
* <p/>
|
||||
* Right now only some classes retain the original encoding of the body contents. Those classes have to implement
|
||||
* the {@link RawDataBody} interface in order for this method to decode the data delivered by
|
||||
* {@link Body#getInputStream()}.
|
||||
* <p/>
|
||||
* The ultimate goal is to get to a point where all classes retain the original data and {@code RawDataBody} can be
|
||||
* merged into {@link Body}.
|
||||
*/
|
||||
public static InputStream decodeBody(Body body) throws MessagingException {
|
||||
InputStream inputStream;
|
||||
if (body instanceof RawDataBody) {
|
||||
RawDataBody rawDataBody = (RawDataBody) body;
|
||||
String encoding = rawDataBody.getEncoding();
|
||||
final InputStream rawInputStream = rawDataBody.getInputStream();
|
||||
if (MimeUtil.ENC_7BIT.equalsIgnoreCase(encoding) || MimeUtil.ENC_8BIT.equalsIgnoreCase(encoding)) {
|
||||
inputStream = rawInputStream;
|
||||
} else if (MimeUtil.ENC_BASE64.equalsIgnoreCase(encoding)) {
|
||||
inputStream = new Base64InputStream(rawInputStream, false) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
rawInputStream.close();
|
||||
}
|
||||
};
|
||||
} else if (MimeUtil.ENC_QUOTED_PRINTABLE.equalsIgnoreCase(encoding)) {
|
||||
inputStream = new QuotedPrintableInputStream(rawInputStream) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
rawInputStream.close();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
throw new RuntimeException("Encoding for RawDataBody not supported: " + encoding);
|
||||
}
|
||||
} else {
|
||||
inputStream = body.getInputStream();
|
||||
}
|
||||
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty base class for the class hierarchy used by
|
||||
|
12
src/com/fsck/k9/mail/internet/RawDataBody.java
Normal file
12
src/com/fsck/k9/mail/internet/RawDataBody.java
Normal file
@ -0,0 +1,12 @@
|
||||
package com.fsck.k9.mail.internet;
|
||||
|
||||
|
||||
import com.fsck.k9.mail.Body;
|
||||
|
||||
|
||||
/**
|
||||
* See {@link MimeUtility#decodeBody(Body)}
|
||||
*/
|
||||
public interface RawDataBody extends Body {
|
||||
String getEncoding();
|
||||
}
|
@ -1561,7 +1561,7 @@ public class LocalFolder extends Folder implements Serializable {
|
||||
* If the attachment has a body we're expected to save it into the local store
|
||||
* so we copy the data into a cached attachment file.
|
||||
*/
|
||||
InputStream in = attachment.getBody().getInputStream();
|
||||
InputStream in = MimeUtility.decodeBody(attachment.getBody());
|
||||
try {
|
||||
tempAttachmentFile = File.createTempFile("att", null, attachmentDirectory);
|
||||
FileOutputStream out = new FileOutputStream(tempAttachmentFile);
|
||||
|
@ -63,7 +63,7 @@ public class MimeMessageParseTest extends AndroidTestCase {
|
||||
private static void checkLeafParts(MimeMessage msg, String... expectedParts) throws Exception {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
for (Body leaf : getLeafParts(msg.getBody())) {
|
||||
actual.add(streamToString(leaf.getInputStream()));
|
||||
actual.add(streamToString(MimeUtility.decodeBody(leaf)));
|
||||
}
|
||||
assertEquals(Arrays.asList(expectedParts), actual);
|
||||
}
|
||||
@ -83,7 +83,7 @@ public class MimeMessageParseTest extends AndroidTestCase {
|
||||
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
|
||||
assertEquals("Testmail", msg.getSubject());
|
||||
assertEquals("text/plain", msg.getContentType());
|
||||
assertEquals("this is some test text.", streamToString(msg.getBody().getInputStream()));
|
||||
assertEquals("this is some test text.", streamToString(MimeUtility.decodeBody(msg.getBody())));
|
||||
}
|
||||
|
||||
public static void testSinglePart8BitRecurse() throws Exception {
|
||||
@ -101,7 +101,7 @@ public class MimeMessageParseTest extends AndroidTestCase {
|
||||
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
|
||||
assertEquals("Testmail", msg.getSubject());
|
||||
assertEquals("text/plain; encoding=ISO-8859-1", msg.getContentType());
|
||||
assertEquals("gefährliche Umlaute", streamToString(msg.getBody().getInputStream()));
|
||||
assertEquals("gefährliche Umlaute", streamToString(MimeUtility.decodeBody(msg.getBody())));
|
||||
}
|
||||
|
||||
public static void testSinglePartBase64NoRecurse() throws Exception {
|
||||
@ -119,7 +119,7 @@ public class MimeMessageParseTest extends AndroidTestCase {
|
||||
checkAddresses(msg.getRecipients(RecipientType.TO), "eva@example.org");
|
||||
assertEquals("Testmail", msg.getSubject());
|
||||
assertEquals("text/plain", msg.getContentType());
|
||||
assertEquals("this is some more test text.", streamToString(msg.getBody().getInputStream()));
|
||||
assertEquals("this is some more test text.", streamToString(MimeUtility.decodeBody(msg.getBody())));
|
||||
}
|
||||
|
||||
public static void testMultipartSingleLayerNoRecurse() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user