mirror of
https://github.com/moparisthebest/davmail
synced 2025-02-28 09:21:49 -05:00
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1132,7 +1147,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
if (!"photo".equals(key)) {
|
||||
propertyValues.add(Field.createPropertyValue(key, entry.getValue()));
|
||||
if (key.startsWith("email")) {
|
||||
propertyValues.add(Field.createPropertyValue(key+"type", "SMTP"));
|
||||
propertyValues.add(Field.createPropertyValue(key + "type", "SMTP"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1309,31 +1324,10 @@ 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");
|
||||
if (propertyValue != null) {
|
||||
byte[] byteArray = Base64.decodeBase64(propertyValue.getBytes());
|
||||
result = getICS(new ByteArrayInputStream(byteArray));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
propFindMethod.releaseConnection();
|
||||
String propertyValue = getItemProperty(permanentUrl, "internetContent");
|
||||
if (propertyValue != null) {
|
||||
byte[] byteArray = Base64.decodeBase64(propertyValue.getBytes());
|
||||
result = getICS(new ByteArrayInputStream(byteArray));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1940,7 +1934,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
}
|
||||
|
||||
protected String getURLPropertyIfExists(DavPropertySet properties, String alias) throws URIException {
|
||||
String result = getPropertyIfExists(properties, alias);
|
||||
String result = getPropertyIfExists(properties, alias);
|
||||
if (result != null) {
|
||||
result = URIUtil.decode(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");
|
||||
@ -2114,7 +2109,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
boolean caldavEnableLegacyTasks = Settings.getBooleanProperty("davmail.caldavEnableLegacyTasks", false);
|
||||
if (caldavEnableLegacyTasks) {
|
||||
// return tasks created in calendar folder
|
||||
return or(isNull("instancetype"),
|
||||
return or(isNull("instancetype"),
|
||||
isEqualTo("instancetype", 1),
|
||||
and(isEqualTo("instancetype", 0), dateCondition));
|
||||
} else {
|
||||
@ -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) {
|
||||
@ -3002,7 +3024,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
priorityToImportanceMap.put("9", "low");
|
||||
}
|
||||
|
||||
protected String convertPriorityFromExchange(String exchangeImportanceValue) {
|
||||
protected String convertPriorityFromExchange(String exchangeImportanceValue) {
|
||||
String value = null;
|
||||
if (exchangeImportanceValue != null) {
|
||||
value = importanceToPriorityMap.get(exchangeImportanceValue);
|
||||
@ -3010,7 +3032,7 @@ public class DavExchangeSession extends ExchangeSession {
|
||||
return value;
|
||||
}
|
||||
|
||||
protected String convertPriorityToExchange(String vTodoPriorityValue) {
|
||||
protected String convertPriorityToExchange(String vTodoPriorityValue) {
|
||||
String value = null;
|
||||
if (vTodoPriorityValue != null) {
|
||||
value = priorityToImportanceMap.get(vTodoPriorityValue);
|
||||
|
@ -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…
x
Reference in New Issue
Block a user