IMAP: experimental implementation of header only FETCH, do not download full message content and send approximate RFC822.SIZE (MAPI size)
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1961 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
d6092e10df
commit
08abcc0514
|
@ -40,10 +40,7 @@ import org.htmlcleaner.TagNode;
|
|||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.mail.internet.MimePart;
|
||||
import javax.mail.internet.*;
|
||||
import javax.mail.util.SharedByteArrayInputStream;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
|
@ -1798,6 +1795,23 @@ public abstract class ExchangeSession {
|
|||
return mimeMessage;
|
||||
}
|
||||
|
||||
public Enumeration getMatchingHeaderLines(String[] headerNames) throws MessagingException, IOException {
|
||||
Enumeration result = null;
|
||||
if (mimeMessage == null) {
|
||||
// message not loaded, try to get headers only
|
||||
InputStream headers = getMimeHeaders();
|
||||
if (headers != null) {
|
||||
result = new InternetHeaders(headers).getMatchingHeaderLines(headerNames);
|
||||
}
|
||||
}
|
||||
if (result == null) {
|
||||
result = getMimeMessage().getMatchingHeaderLines(headerNames);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract InputStream getMimeHeaders();
|
||||
|
||||
/**
|
||||
* Get message body size.
|
||||
*
|
||||
|
|
|
@ -1078,6 +1078,21 @@ public class DavExchangeSession extends ExchangeSession {
|
|||
public String getPermanentId() {
|
||||
return permanentUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getMimeHeaders() {
|
||||
InputStream result = null;
|
||||
try {
|
||||
String messageHeaders = getItemProperty(permanentUrl, "messageheaders");
|
||||
if (messageHeaders != null) {
|
||||
result = new ByteArrayInputStream(messageHeaders.getBytes("UTF-8"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1309,32 +1324,11 @@ public class DavExchangeSession extends ExchangeSession {
|
|||
protected byte[] getICSFromInternetContentProperty() throws IOException, DavException, MessagingException {
|
||||
byte[] result = null;
|
||||
// PropFind PR_INTERNET_CONTENT
|
||||
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
|
||||
davPropertyNameSet.add(Field.getPropertyName("internetContent"));
|
||||
PropFindMethod propFindMethod = new PropFindMethod(encodeAndFixUrl(permanentUrl), davPropertyNameSet, 0);
|
||||
try {
|
||||
try {
|
||||
DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propFindMethod);
|
||||
} catch (UnknownHostException e) {
|
||||
propFindMethod.releaseConnection();
|
||||
// failover for misconfigured Exchange server, replace host name in url
|
||||
restoreHostName = true;
|
||||
propFindMethod = new PropFindMethod(encodeAndFixUrl(permanentUrl), davPropertyNameSet, 0);
|
||||
DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propFindMethod);
|
||||
}
|
||||
|
||||
MultiStatus responses = propFindMethod.getResponseBodyAsMultiStatus();
|
||||
if (responses.getResponses().length > 0) {
|
||||
DavPropertySet properties = responses.getResponses()[0].getProperties(HttpStatus.SC_OK);
|
||||
String propertyValue = getPropertyIfExists(properties, "internetContent");
|
||||
String propertyValue = getItemProperty(permanentUrl, "internetContent");
|
||||
if (propertyValue != null) {
|
||||
byte[] byteArray = Base64.decodeBase64(propertyValue.getBytes());
|
||||
result = getICS(new ByteArrayInputStream(byteArray));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
propFindMethod.releaseConnection();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2059,6 +2053,7 @@ public class DavExchangeSession extends ExchangeSession {
|
|||
* Common item properties
|
||||
*/
|
||||
protected static final Set<String> ITEM_PROPERTIES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
ITEM_PROPERTIES.add("etag");
|
||||
ITEM_PROPERTIES.add("displayname");
|
||||
|
@ -2974,6 +2969,33 @@ public class DavExchangeSession extends ExchangeSession {
|
|||
LOGGER.debug("Deleted to :" + destination);
|
||||
}
|
||||
|
||||
protected String getItemProperty(String permanentUrl, String propertyName) throws IOException, DavException, MessagingException {
|
||||
String result = null;
|
||||
DavPropertyNameSet davPropertyNameSet = new DavPropertyNameSet();
|
||||
davPropertyNameSet.add(Field.getPropertyName(propertyName));
|
||||
PropFindMethod propFindMethod = new PropFindMethod(encodeAndFixUrl(permanentUrl), davPropertyNameSet, 0);
|
||||
try {
|
||||
try {
|
||||
DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propFindMethod);
|
||||
} catch (UnknownHostException e) {
|
||||
propFindMethod.releaseConnection();
|
||||
// failover for misconfigured Exchange server, replace host name in url
|
||||
restoreHostName = true;
|
||||
propFindMethod = new PropFindMethod(encodeAndFixUrl(permanentUrl), davPropertyNameSet, 0);
|
||||
DavGatewayHttpClientFacade.executeHttpMethod(httpClient, propFindMethod);
|
||||
}
|
||||
|
||||
MultiStatus responses = propFindMethod.getResponseBodyAsMultiStatus();
|
||||
if (responses.getResponses().length > 0) {
|
||||
DavPropertySet properties = responses.getResponses()[0].getProperties(HttpStatus.SC_OK);
|
||||
result = getPropertyIfExists(properties, propertyName);
|
||||
}
|
||||
} finally {
|
||||
propFindMethod.releaseConnection();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected String convertDateFromExchange(String exchangeDateValue) throws DavMailException {
|
||||
String zuluDateValue = null;
|
||||
if (exchangeDateValue != null) {
|
||||
|
|
|
@ -143,6 +143,7 @@ public class Field {
|
|||
createField(URN_SCHEMAS_HTTPMAIL, "subject"); // DistinguishedPropertySetType.InternetHeaders/Subject/String
|
||||
//createField("subject", 0x0037, PropertyType.String);//PR_SUBJECT
|
||||
createField("body", 0x1000, PropertyType.String);//PR_BODY
|
||||
createField("messageheaders", 0x007D, PropertyType.String);// PR_TRANSPORT_MESSAGE_HEADERS
|
||||
createField(URN_SCHEMAS_HTTPMAIL, "from");
|
||||
//createField("from", DistinguishedPropertySetType.PublicStrings, 0x001f);//urn:schemas:httpmail:from
|
||||
createField(URN_SCHEMAS_MAILHEADER, "to"); // DistinguishedPropertySetType.InternetHeaders/To/String
|
||||
|
|
|
@ -41,10 +41,7 @@ import javax.mail.Session;
|
|||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.util.SharedByteArrayInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.SocketException;
|
||||
import java.text.ParseException;
|
||||
|
@ -368,6 +365,26 @@ public class EwsExchangeSession extends ExchangeSession {
|
|||
public String getPermanentId() {
|
||||
return itemId.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream getMimeHeaders() {
|
||||
InputStream result = null;
|
||||
try {
|
||||
GetItemMethod getItemMethod = new GetItemMethod(BaseShape.ID_ONLY, itemId, false);
|
||||
getItemMethod.addAdditionalProperty(Field.get("messageheaders"));
|
||||
executeMethod(getItemMethod);
|
||||
EWSMethod.Item item = getItemMethod.getResponseItem();
|
||||
|
||||
String messageHeaders = item.get(Field.get("messageheaders").getResponseName());
|
||||
if (messageHeaders != null) {
|
||||
result = new ByteArrayInputStream(messageHeaders.getBytes("UTF-8"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.warn(e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -79,6 +79,8 @@ public final class Field {
|
|||
FIELD_MAP.put("cc", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "cc"));
|
||||
FIELD_MAP.put("from", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "from"));
|
||||
|
||||
FIELD_MAP.put("messageheaders", new ExtendedFieldURI(0x007D, ExtendedFieldURI.PropertyType.String)); // PR_TRANSPORT_MESSAGE_HEADERS
|
||||
|
||||
FIELD_MAP.put("contentclass", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "content-class"));
|
||||
FIELD_MAP.put("message-id", new ExtendedFieldURI(ExtendedFieldURI.DistinguishedPropertySetType.InternetHeaders, "message-id"));
|
||||
|
||||
|
|
|
@ -713,7 +713,14 @@ public class ImapConnection extends AbstractConnection {
|
|||
if ("FLAGS".equals(param)) {
|
||||
buffer.append(" FLAGS (").append(message.getImapFlags()).append(')');
|
||||
} else if ("RFC822.SIZE".equals(param)) {
|
||||
buffer.append(" RFC822.SIZE ").append(message.getMimeMessageSize());
|
||||
int size;
|
||||
if (parameters.indexOf("BODY.PEEK[HEADER.FIELDS (") >= 0) {
|
||||
// Header request, send approximate size
|
||||
size = message.size;
|
||||
} else {
|
||||
size = message.getMimeMessageSize();
|
||||
}
|
||||
buffer.append(" RFC822.SIZE ").append(size);
|
||||
} else if ("ENVELOPE".equals(param)) {
|
||||
appendEnvelope(buffer, message);
|
||||
} else if ("BODYSTRUCTURE".equals(param)) {
|
||||
|
@ -769,11 +776,12 @@ public class ImapConnection extends AbstractConnection {
|
|||
if (requestedHeaders != null) {
|
||||
// OSX Lion special flags request
|
||||
if (requestedHeaders.length == 1 && "content-class".equals(requestedHeaders[0]) && message.contentClass != null) {
|
||||
baos.write("Content-class: ".getBytes("UTF-8"));
|
||||
baos.write(message.contentClass.getBytes("UTF-8"));
|
||||
baos.write(13);
|
||||
baos.write(10);
|
||||
} else {
|
||||
Enumeration headerEnumeration = message.getMimeMessage().getMatchingHeaderLines(requestedHeaders);
|
||||
Enumeration headerEnumeration = message.getMatchingHeaderLines(requestedHeaders);
|
||||
while (headerEnumeration.hasMoreElements()) {
|
||||
baos.write(((String) headerEnumeration.nextElement()).getBytes("UTF-8"));
|
||||
baos.write(13);
|
||||
|
|
|
@ -388,4 +388,10 @@ public class TestImap extends AbstractImapTestCase {
|
|||
writeLine(". FETCH 1:* (FLAGS UID BODY.PEEK[HEADER.FIELDS (content-class)])");
|
||||
assertEquals(". OK FETCH completed", readFullAnswer("."));
|
||||
}
|
||||
|
||||
public void testFetchHeadersThunderbird() throws IOException {
|
||||
testSelectInbox();
|
||||
writeLine(". FETCH 1:* (UID RFC822.SIZE FLAGS BODY.PEEK[HEADER.FIELDS (From To Cc Bcc Subject Date Message-ID Priority X-Priority References Newsgroups In-Reply-To Content-Type)])");
|
||||
assertEquals(". OK FETCH completed", readFullAnswer("."));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue