EWS: fix urlcompname encoding issues

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1269 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2010-07-25 14:36:27 +00:00
parent efeaec5935
commit 5b9e18cda5
6 changed files with 89 additions and 23 deletions

View File

@ -556,6 +556,7 @@ public abstract class ExchangeSession {
static { static {
IMAP_MESSAGE_ATTRIBUTES.add("permanenturl"); IMAP_MESSAGE_ATTRIBUTES.add("permanenturl");
IMAP_MESSAGE_ATTRIBUTES.add("urlcompname");
IMAP_MESSAGE_ATTRIBUTES.add("uid"); IMAP_MESSAGE_ATTRIBUTES.add("uid");
IMAP_MESSAGE_ATTRIBUTES.add("messageSize"); IMAP_MESSAGE_ATTRIBUTES.add("messageSize");
IMAP_MESSAGE_ATTRIBUTES.add("imapUid"); IMAP_MESSAGE_ATTRIBUTES.add("imapUid");

View File

@ -433,7 +433,11 @@ public class DavExchangeSession extends ExchangeSession {
if (Operator.Like == operator) { if (Operator.Like == operator) {
buffer.append('%'); buffer.append('%');
} }
buffer.append(value); if ("urlcompname".equals(field.alias)) {
buffer.append(StringUtil.encodeUrlcompname(value));
} else {
buffer.append(value);
}
if (Operator.Like == operator || Operator.StartsWith == operator) { if (Operator.Like == operator || Operator.StartsWith == operator) {
buffer.append('%'); buffer.append('%');
} }
@ -1202,22 +1206,7 @@ public class DavExchangeSession extends ExchangeSession {
@Override @Override
public Item getItem(String folderPath, String itemName) throws IOException { public Item getItem(String folderPath, String itemName) throws IOException {
String itemPath = getFolderPath(folderPath) + '/' + convertItemNameToEML(itemName); String itemPath = getFolderPath(folderPath) + '/' + convertItemNameToEML(itemName);
Item item; return getItem(itemPath);
try {
item = getItem(itemPath);
} catch (HttpNotFoundException hnfe) {
// failover for Exchange 2007 plus encoding issue
String decodedEventName = convertItemNameToEML(itemName).replaceAll("_xF8FF_", "/").replaceAll("_x003F_", "?").replaceAll("'", "''");
LOGGER.debug("Item not found at " + itemPath + ", search by displayname: '" + decodedEventName + '\'');
ExchangeSession.MessageList messages = searchMessages(folderPath, equals("displayname", decodedEventName));
if (!messages.isEmpty()) {
item = getItem(messages.get(0).getPermanentUrl());
} else {
throw hnfe;
}
}
return item;
} }
@Override @Override

View File

@ -174,7 +174,7 @@ public class EwsExchangeSession extends ExchangeSession {
fieldUpdates.add(Field.createFieldUpdate("messageFlags", "0")); fieldUpdates.add(Field.createFieldUpdate("messageFlags", "0"));
} }
} }
fieldUpdates.add(Field.createFieldUpdate("urlcompname", messageName)); fieldUpdates.add(Field.createFieldUpdate("urlcompname", StringUtil.encodeUrlcompname(messageName)));
item.setFieldUpdates(fieldUpdates); item.setFieldUpdates(fieldUpdates);
CreateItemMethod createItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), item); CreateItemMethod createItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), item);
executeMethod(createItemMethod); executeMethod(createItemMethod);
@ -363,10 +363,16 @@ public class EwsExchangeSession extends ExchangeSession {
containmentComparison.appendTo(buffer); containmentComparison.appendTo(buffer);
} }
buffer.append('>'); buffer.append('>');
getFieldURI(attributeName).appendTo(buffer); FieldURI fieldURI = getFieldURI(attributeName);
fieldURI.appendTo(buffer);
buffer.append("<t:FieldURIOrConstant><t:Constant Value=\""); buffer.append("<t:FieldURIOrConstant><t:Constant Value=\"");
buffer.append(StringUtil.xmlEncode(value)); // encode urlcompname
if (fieldURI instanceof ExtendedFieldURI && "0x10f3".equals(((ExtendedFieldURI) fieldURI).propertyTag)) {
buffer.append(StringUtil.xmlEncode(StringUtil.encodeUrlcompname(value)));
} else {
buffer.append(StringUtil.xmlEncode(value));
}
buffer.append("\"/></t:FieldURIOrConstant>"); buffer.append("\"/></t:FieldURIOrConstant>");
buffer.append("</t:").append(operator.toString()).append('>'); buffer.append("</t:").append(operator.toString()).append('>');
@ -577,7 +583,7 @@ public class EwsExchangeSession extends ExchangeSession {
* @inheritDoc * @inheritDoc
*/ */
@Override @Override
public int createFolder(String folderPath, String folderClass, Map<String,String> properties) throws IOException { public int createFolder(String folderPath, String folderClass, Map<String, String> properties) throws IOException {
FolderPath path = new FolderPath(folderPath); FolderPath path = new FolderPath(folderPath);
EWSMethod.Item folder = new EWSMethod.Item(); EWSMethod.Item folder = new EWSMethod.Item();
folder.type = "Folder"; folder.type = "Folder";
@ -1112,7 +1118,7 @@ public class EwsExchangeSession extends ExchangeSession {
parentFolderId, parentFolderId,
FOLDER_PROPERTIES, FOLDER_PROPERTIES,
new TwoOperandExpression(TwoOperandExpression.Operator.IsEqualTo, new TwoOperandExpression(TwoOperandExpression.Operator.IsEqualTo,
Field.get("urlcompname"), StringUtil.urlEncodeAmpersand(folderName)) Field.get("urlcompname"), folderName)
); );
executeMethod(findFolderMethod); executeMethod(findFolderMethod);
EWSMethod.Item item = findFolderMethod.getResponseItem(); EWSMethod.Item item = findFolderMethod.getResponseItem();

View File

@ -51,7 +51,12 @@ public class TwoOperandExpression implements SearchExpression {
fieldURI.appendTo(buffer); fieldURI.appendTo(buffer);
buffer.append("<t:FieldURIOrConstant><t:Constant Value=\""); buffer.append("<t:FieldURIOrConstant><t:Constant Value=\"");
buffer.append(StringUtil.xmlEncode(value)); // encode urlcompname
if (fieldURI instanceof ExtendedFieldURI && "0x10f3".equals(((ExtendedFieldURI) fieldURI).propertyTag)) {
buffer.append(StringUtil.xmlEncode(StringUtil.encodeUrlcompname(value)));
} else {
buffer.append(StringUtil.xmlEncode(value));
}
buffer.append("\"/></t:FieldURIOrConstant>"); buffer.append("\"/></t:FieldURIOrConstant>");
buffer.append("</t:").append(operator.toString()).append('>'); buffer.append("</t:").append(operator.toString()).append('>');

View File

@ -135,6 +135,18 @@ public final class StringUtil {
private static final Pattern ENCODED_LT_PATTERN = Pattern.compile("&lt;"); private static final Pattern ENCODED_LT_PATTERN = Pattern.compile("&lt;");
private static final Pattern ENCODED_GT_PATTERN = Pattern.compile("&gt;"); private static final Pattern ENCODED_GT_PATTERN = Pattern.compile("&gt;");
private static final Pattern F8FF_PATTERN = Pattern.compile("_xF8FF_");
private static final Pattern PLUS_PATTERN = Pattern.compile("\\+");
public static String urlEncodeSlash(String name) {
String result = name;
if (name.indexOf("_xF8FF_") >= 0) {
result = F8FF_PATTERN.matcher(result).replaceAll(String.valueOf((char)0xF8FF));
}
return result;
}
/** /**
* Encode & to %26 for urlcompname. * Encode & to %26 for urlcompname.
* *
@ -232,4 +244,17 @@ public final class StringUtil {
return base64Value; return base64Value;
} }
public static String encodeUrlcompname(String value) {
String result = value;
if (result.indexOf("_xF8FF_") >= 0) {
result = F8FF_PATTERN.matcher(result).replaceAll(String.valueOf((char)0xF8FF));
}
if (result.indexOf('&') >= 0) {
result = AMP_PATTERN.matcher(result).replaceAll("%26");
}
if (result.indexOf('+') >= 0) {
result = PLUS_PATTERN.matcher(result).replaceAll("%2B");
}
return result;
}
} }

View File

@ -96,6 +96,46 @@ public class TestExchangeSessionMessage extends AbstractExchangeSessionTestCase
assertEquals(0, messageList.size()); assertEquals(0, messageList.size());
} }
public void testSpecialMessageCharacter() throws IOException, MessagingException {
session.deleteFolder("testfolder");
session.createMessageFolder("testfolder");
MimeMessage mimeMessage = createMimeMessage();
messageName = "Special & accenté.EML";
HashMap<String, String> properties = new HashMap<String, String>();
properties.put("draft", "0");
session.createMessage("testfolder", messageName, properties, getMimeBody(mimeMessage));
ExchangeSession.MessageList messageList = session.searchMessages("testfolder", session.equals("urlcompname", messageName));
assertNotNull(messageList);
assertEquals(1, messageList.size());
}
public void testSlashMessageName() throws IOException, MessagingException {
session.deleteFolder("testfolder");
session.createMessageFolder("testfolder");
MimeMessage mimeMessage = createMimeMessage();
messageName = "test _xF8FF_ slash.EML";
HashMap<String, String> properties = new HashMap<String, String>();
properties.put("draft", "0");
session.createMessage("testfolder", messageName, properties, getMimeBody(mimeMessage));
ExchangeSession.MessageList messageList = session.searchMessages("testfolder", session.equals("urlcompname", messageName));
assertNotNull(messageList);
assertEquals(1, messageList.size());
}
public void testPlusMessageName() throws IOException, MessagingException {
// fails on Exchange 2003
session.deleteFolder("testfolder");
session.createMessageFolder("testfolder");
MimeMessage mimeMessage = createMimeMessage();
messageName = "test + plus.EML";
HashMap<String, String> properties = new HashMap<String, String>();
properties.put("draft", "0");
session.createMessage("testfolder", messageName, properties, getMimeBody(mimeMessage));
ExchangeSession.MessageList messageList = session.searchMessages("testfolder", session.equals("urlcompname", messageName));
assertNotNull(messageList);
assertEquals(1, messageList.size());
}
/** /**
* Cleanup * Cleanup
*/ */