Skip to content

Commit e5da0ba

Browse files
committed
Fixed download attachments. | #107.
1 parent ca9aef2 commit e5da0ba

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

FlowCrypt/src/main/java/com/flowcrypt/email/api/email/protocol/ImapProtocolUtil.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.flowcrypt.email.api.email.protocol;
88

9+
import com.flowcrypt.email.database.dao.source.AccountDao;
910
import com.sun.mail.iap.ProtocolException;
1011
import com.sun.mail.imap.IMAPFolder;
1112
import com.sun.mail.imap.protocol.BODY;
@@ -29,20 +30,33 @@ public class ImapProtocolUtil {
2930
/**
3031
* Return the MIME format stream of headers for this body part.
3132
*
33+
* @param accountDao The object which contains information about an email account.
3234
* @param imapFolder The {@link IMAPFolder} which contains the parent message;
3335
* @param messageNumber This number will be used for fetching {@link Part} details;
3436
* @param sectionId The {@link Part} section id.
3537
* @return
3638
* @throws MessagingException
3739
*/
38-
public static InputStream getHeaderStream(IMAPFolder imapFolder, final int messageNumber, final int sectionId)
39-
throws MessagingException {
40+
public static InputStream getHeaderStream(AccountDao accountDao, IMAPFolder imapFolder, final int messageNumber,
41+
int sectionId) throws MessagingException {
42+
43+
final String section;
44+
45+
switch (accountDao.getAccountType()) {
46+
case AccountDao.ACCOUNT_TYPE_GOOGLE:
47+
section = sectionId + ".MIME";
48+
break;
49+
50+
default:
51+
section = sectionId + ".HEADER";
52+
break;
53+
}
4054

4155
return (InputStream) imapFolder.doCommand(new IMAPFolder.ProtocolCommand() {
4256
public Object doCommand(IMAPProtocol imapProtocol)
4357
throws ProtocolException {
4458

45-
BODY body = imapProtocol.peekBody(messageNumber, sectionId + ".HEADER");
59+
BODY body = imapProtocol.peekBody(messageNumber, section);
4660
if (body != null) {
4761
return body.getByteArrayInputStream();
4862
} else return null;

FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailSyncService.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,8 @@ private void updateAttachmentTable(AccountDao accountDao, com.flowcrypt.email.ap
326326
ArrayList<AttachmentInfo> attachmentInfoList = null;
327327

328328
try {
329-
attachmentInfoList = getAttachmentsInfoFromPart(imapFolder, message.getMessageNumber(), message);
329+
attachmentInfoList = getAttachmentsInfoFromPart(accountDao, imapFolder, message.getMessageNumber(),
330+
message);
330331
} catch (IOException e) {
331332
e.printStackTrace();
332333
}
@@ -345,6 +346,7 @@ private void updateAttachmentTable(AccountDao accountDao, com.flowcrypt.email.ap
345346
/**
346347
* Find attachments in the {@link Part}.
347348
*
349+
* @param accountDao The object which contains information about an email account.
348350
* @param imapFolder The {@link IMAPFolder} which contains the parent message;
349351
* @param messageNumber This number will be used for fetching {@link Part} details;
350352
* @param part The parent part.
@@ -353,7 +355,8 @@ private void updateAttachmentTable(AccountDao accountDao, com.flowcrypt.email.ap
353355
* @throws IOException
354356
*/
355357
@NonNull
356-
private ArrayList<AttachmentInfo> getAttachmentsInfoFromPart(IMAPFolder imapFolder, int messageNumber, Part part)
358+
private ArrayList<AttachmentInfo> getAttachmentsInfoFromPart(AccountDao accountDao, IMAPFolder imapFolder, int
359+
messageNumber, Part part)
357360
throws MessagingException, IOException {
358361
ArrayList<AttachmentInfo> attachmentInfoList = new ArrayList<>();
359362

@@ -364,13 +367,13 @@ private ArrayList<AttachmentInfo> getAttachmentsInfoFromPart(IMAPFolder imapFold
364367
for (int partCount = 0; partCount < numberOfParts; partCount++) {
365368
BodyPart bodyPart = multiPart.getBodyPart(partCount);
366369
if (bodyPart.isMimeType(JavaEmailConstants.MIME_TYPE_MULTIPART)) {
367-
ArrayList<AttachmentInfo> attachmentInfoLists = getAttachmentsInfoFromPart(imapFolder,
370+
ArrayList<AttachmentInfo> attachmentInfoLists = getAttachmentsInfoFromPart(accountDao, imapFolder,
368371
messageNumber, bodyPart);
369372
if (!attachmentInfoLists.isEmpty()) {
370373
attachmentInfoList.addAll(attachmentInfoLists);
371374
}
372375
} else if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
373-
InputStream inputStream = ImapProtocolUtil.getHeaderStream(imapFolder, messageNumber,
376+
InputStream inputStream = ImapProtocolUtil.getHeaderStream(accountDao, imapFolder, messageNumber,
374377
partCount + 1);
375378

376379
if (inputStream == null) {

FlowCrypt/src/main/java/com/flowcrypt/email/service/attachment/AttachmentDownloadManagerService.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.flowcrypt.email.R;
3030
import com.flowcrypt.email.api.email.JavaEmailConstants;
3131
import com.flowcrypt.email.api.email.model.AttachmentInfo;
32+
import com.flowcrypt.email.api.email.protocol.ImapProtocolUtil;
3233
import com.flowcrypt.email.api.email.protocol.OpenStoreHelper;
3334
import com.flowcrypt.email.database.dao.source.AccountDao;
3435
import com.flowcrypt.email.database.dao.source.AccountDaoSource;
@@ -56,6 +57,7 @@
5657
import javax.mail.Part;
5758
import javax.mail.Session;
5859
import javax.mail.Store;
60+
import javax.mail.internet.InternetHeaders;
5961

6062
/**
6163
* This service will be use to download email attachments. To start load an attachment just run service via the intent
@@ -464,7 +466,8 @@ public void run() {
464466
imapFolder.open(Folder.READ_ONLY);
465467

466468
javax.mail.Message message = imapFolder.getMessageByUID(attachmentInfo.getUid());
467-
Part attachment = getAttachmentPart(message, attachmentInfo.getId());
469+
Part attachment = getAttachmentPartById(accountDao, imapFolder, message.getMessageNumber(), message,
470+
attachmentInfo.getId());
468471

469472
if (attachment != null) {
470473
InputStream input = attachment.getInputStream();
@@ -567,28 +570,48 @@ private File prepareAttachmentFile() {
567570
/**
568571
* Get {@link Part} which has an attachment with such attachment id.
569572
*
570-
* @param part The parent part.
573+
* @param accountDao The object which contains information about an email account.
574+
* @param imapFolder The {@link IMAPFolder} which contains the parent message;
575+
* @param messageNumber This number will be used for fetching {@link Part} details;
576+
* @param part The parent part.
571577
* @return {@link Part} which has attachment or null if message doesn't have such attachment.
572578
* @throws MessagingException
573579
* @throws IOException
574580
*/
575-
private Part getAttachmentPart(Part part, String attachmentId) throws MessagingException, IOException {
581+
private Part getAttachmentPartById(AccountDao accountDao, IMAPFolder imapFolder, int messageNumber, Part
582+
part, String attachmentId)
583+
throws MessagingException, IOException {
576584
if (part != null && part.isMimeType(JavaEmailConstants.MIME_TYPE_MULTIPART)) {
577585
Multipart multiPart = (Multipart) part.getContent();
578586
int numberOfParts = multiPart.getCount();
579587
String[] headers;
580588
for (int partCount = 0; partCount < numberOfParts; partCount++) {
581589
BodyPart bodyPart = multiPart.getBodyPart(partCount);
582590
if (bodyPart.isMimeType(JavaEmailConstants.MIME_TYPE_MULTIPART)) {
583-
Part innerPart = getAttachmentPart(bodyPart, attachmentId);
591+
Part innerPart = getAttachmentPartById(accountDao, imapFolder, messageNumber, bodyPart,
592+
attachmentId);
584593
if (innerPart != null) {
585594
return innerPart;
586595
}
587-
} else if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())
588-
&& (headers = bodyPart.getHeader(JavaEmailConstants.HEADER_X_ATTACHMENT_ID)) != null
589-
&& headers.length > 0
590-
&& attachmentId.equals(headers[0])) {
591-
return bodyPart;
596+
} else if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition())) {
597+
InputStream inputStream = ImapProtocolUtil.getHeaderStream(accountDao, imapFolder,
598+
messageNumber, partCount + 1);
599+
600+
if (inputStream == null) {
601+
throw new MessagingException("Failed to fetch headers");
602+
}
603+
604+
InternetHeaders internetHeaders = new InternetHeaders(inputStream);
605+
headers = internetHeaders.getHeader(JavaEmailConstants.HEADER_CONTENT_ID);
606+
607+
if (headers == null) {
608+
//try to receive custom Gmail attachments header X-Attachment-Id
609+
headers = internetHeaders.getHeader(JavaEmailConstants.HEADER_X_ATTACHMENT_ID);
610+
}
611+
612+
if (headers != null && attachmentId.equals(headers[0])) {
613+
return bodyPart;
614+
}
592615
}
593616
}
594617
return null;

0 commit comments

Comments
 (0)