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 {
IMAP_MESSAGE_ATTRIBUTES.add("permanenturl");
IMAP_MESSAGE_ATTRIBUTES.add("urlcompname");
IMAP_MESSAGE_ATTRIBUTES.add("uid");
IMAP_MESSAGE_ATTRIBUTES.add("messageSize");
IMAP_MESSAGE_ATTRIBUTES.add("imapUid");

View File

@ -433,7 +433,11 @@ public class DavExchangeSession extends ExchangeSession {
if (Operator.Like == operator) {
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) {
buffer.append('%');
}
@ -1202,22 +1206,7 @@ public class DavExchangeSession extends ExchangeSession {
@Override
public Item getItem(String folderPath, String itemName) throws IOException {
String itemPath = getFolderPath(folderPath) + '/' + convertItemNameToEML(itemName);
Item item;
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;
return getItem(itemPath);
}
@Override

View File

@ -174,7 +174,7 @@ public class EwsExchangeSession extends ExchangeSession {
fieldUpdates.add(Field.createFieldUpdate("messageFlags", "0"));
}
}
fieldUpdates.add(Field.createFieldUpdate("urlcompname", messageName));
fieldUpdates.add(Field.createFieldUpdate("urlcompname", StringUtil.encodeUrlcompname(messageName)));
item.setFieldUpdates(fieldUpdates);
CreateItemMethod createItemMethod = new CreateItemMethod(MessageDisposition.SaveOnly, getFolderId(folderPath), item);
executeMethod(createItemMethod);
@ -363,10 +363,16 @@ public class EwsExchangeSession extends ExchangeSession {
containmentComparison.appendTo(buffer);
}
buffer.append('>');
getFieldURI(attributeName).appendTo(buffer);
FieldURI fieldURI = getFieldURI(attributeName);
fieldURI.appendTo(buffer);
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:").append(operator.toString()).append('>');
@ -577,7 +583,7 @@ public class EwsExchangeSession extends ExchangeSession {
* @inheritDoc
*/
@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);
EWSMethod.Item folder = new EWSMethod.Item();
folder.type = "Folder";
@ -1112,7 +1118,7 @@ public class EwsExchangeSession extends ExchangeSession {
parentFolderId,
FOLDER_PROPERTIES,
new TwoOperandExpression(TwoOperandExpression.Operator.IsEqualTo,
Field.get("urlcompname"), StringUtil.urlEncodeAmpersand(folderName))
Field.get("urlcompname"), folderName)
);
executeMethod(findFolderMethod);
EWSMethod.Item item = findFolderMethod.getResponseItem();

View File

@ -51,7 +51,12 @@ public class TwoOperandExpression implements SearchExpression {
fieldURI.appendTo(buffer);
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:").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_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.
*
@ -232,4 +244,17 @@ public final class StringUtil {
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());
}
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
*/