Skip to content

Commit

Permalink
Fixes issue #103 : IMAP Fetch using single atomic option fails
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelmay committed Oct 18, 2015
1 parent 912e808 commit 6f046bf
Showing 1 changed file with 52 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@


/**
* Handles processeing for the FETCH imap command.
* Handles processing for the FETCH imap command.
* <p/>
* https://tools.ietf.org/html/rfc3501#section-6.4.5
*
* @author Darrell DeBoer <darrell@apache.org>
* @version $Revision: 109034 $
Expand Down Expand Up @@ -210,36 +212,45 @@ private void handleBodyFetch(MimeMessage mimeMessage,
bytes = doPartial(partial, bytes, response);
addLiteral(bytes, response);
} else if ("TEXT".equalsIgnoreCase(sectionSpecifier)) {
// TODO - need to use an InputStream from the response here.
// TODO - this is a hack. To get just the body content, I'm using a null
// input stream to take the headers. Need to have a way of ignoring headers.

byte[] bytes = GreenMailUtil.getBodyAsBytes(mimeMessage);
bytes = doPartial(partial, bytes, response);
addLiteral(bytes, response);
handleBodyFetchForText(mimeMessage, partial, response);
} else {
if(log.isDebugEnabled()) {
log.debug("Fetching body part for section specifier "+sectionSpecifier);
if (log.isDebugEnabled()) {
log.debug("Fetching body part for section specifier " + sectionSpecifier +
" and mime message (contentType=" + mimeMessage.getContentType());
}
MimeMultipart mp = (MimeMultipart) mimeMessage.getContent();
BodyPart part = null;
String[] nestedIdx = sectionSpecifier.split("\\.");
for(String idx: nestedIdx) {
int partNumber = Integer.parseInt(idx) - 1;
if(null==part) {
part = mp.getBodyPart(partNumber);
}
else {
// Content must be multipart
part = ((Multipart)part.getContent()).getBodyPart(partNumber);
String contentType = mimeMessage.getContentType();
if (contentType.startsWith("text/plain") && "1".equals(sectionSpecifier)) {
handleBodyFetchForText(mimeMessage, partial, response);
} else {
MimeMultipart mp = (MimeMultipart) mimeMessage.getContent();
BodyPart part = null;
String[] nestedIdx = sectionSpecifier.split("\\.");
for (String idx : nestedIdx) {
int partNumber = Integer.parseInt(idx) - 1;
if (null == part) {
part = mp.getBodyPart(partNumber);
} else {
// Content must be multipart
part = ((Multipart) part.getContent()).getBodyPart(partNumber);
}
}
byte[] bytes = GreenMailUtil.getBodyAsBytes(part);
bytes = doPartial(partial, bytes, response);
addLiteral(bytes, response);
}
byte[] bytes = GreenMailUtil.getBodyAsBytes(part);
bytes = doPartial(partial, bytes, response);
addLiteral(bytes, response);
}
}

private void handleBodyFetchForText(MimeMessage mimeMessage, String partial, StringBuilder response) {
// TODO - need to use an InputStream from the response here.
// TODO - this is a hack. To get just the body content, I'm using a null
// input stream to take the headers. Need to have a way of ignoring headers.

byte[] bytes = GreenMailUtil.getBodyAsBytes(mimeMessage);
bytes = doPartial(partial, bytes, response);
addLiteral(bytes, response);
}

private byte[] doPartial(String partial, byte[] bytes, StringBuilder response) {
if (null != partial) {
String[] strs = partial.split("\\.");
Expand Down Expand Up @@ -322,16 +333,23 @@ public FetchRequest fetchRequest(ImapRequestLineReader request)
throws ProtocolException {
FetchRequest fetch = new FetchRequest();

nextNonSpaceChar(request);
consumeChar(request, '(');

// Parenthesis optional if single 'atom'
char next = nextNonSpaceChar(request);
while (next != ')') {
addNextElement(request, fetch);
boolean parenthesis = '(' == next;
if (parenthesis) {
consumeChar(request, '(');

next = nextNonSpaceChar(request);
}
while (next != ')') {
addNextElement(request, fetch);
next = nextNonSpaceChar(request);
}

consumeChar(request, ')');
consumeChar(request, ')');
} else {
// Single item
addNextElement(request, fetch);
}

return fetch;
}
Expand Down Expand Up @@ -401,7 +419,7 @@ private void addNextElement(ImapRequestLineReader command, FetchRequest fetch)
String parameter = sectionIdentifier.toString();

StringBuilder partial = null;
next = nextCharInLine(command);
next = command.nextChar(); // Can be end of line if single option
if ('<' == next) {
partial = new StringBuilder();
consumeChar(command, '<');
Expand All @@ -417,10 +435,10 @@ private void addNextElement(ImapRequestLineReader command, FetchRequest fetch)

if ("BODY".equalsIgnoreCase(name)) {
fetch.add(new BodyFetchElement("BODY[" + parameter + ']', parameter,
null==partial?null:partial.toString()), false);
null == partial ? null : partial.toString()), false);
} else if ("BODY.PEEK".equalsIgnoreCase(name)) {
fetch.add(new BodyFetchElement("BODY[" + parameter + ']', parameter,
null==partial?null:partial.toString()), true);
null == partial ? null : partial.toString()), true);
} else {
throw new ProtocolException("Invalid fetch attibute: " + name + "[]");
}
Expand Down

0 comments on commit 6f046bf

Please sign in to comment.