Improve message attachment handling

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@18 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2007-01-02 09:51:12 +00:00
parent 9fcca726c1
commit dd3e4f9f15
1 changed files with 77 additions and 26 deletions

View File

@ -352,8 +352,17 @@ public class ExchangeSession {
} }
protected Message buildMessage(ResponseEntity responseEntity) throws URIException { protected Message buildMessage(ResponseEntity responseEntity) throws URIException {
return buildMessage(responseEntity, null);
}
protected Message buildMessage(ResponseEntity responseEntity, String webMessageUrl) throws URIException {
Message message = new Message(); Message message = new Message();
message.messageUrl = URIUtil.decode(responseEntity.getHref()); message.messageUrl = URIUtil.decode(responseEntity.getHref());
if (webMessageUrl != null) {
message.webMessageUrl = webMessageUrl;
} else {
message.webMessageUrl = message.messageUrl;
}
Enumeration propertiesEnum = responseEntity.getProperties(); Enumeration propertiesEnum = responseEntity.getProperties();
while (propertiesEnum.hasMoreElements()) { while (propertiesEnum.hasMoreElements()) {
Property prop = (Property) propertiesEnum.nextElement(); Property prop = (Property) propertiesEnum.nextElement();
@ -403,7 +412,12 @@ public class ExchangeSession {
return message; return message;
} }
public Message getMessage(String messageUrl) throws IOException { public Message getMessage(String messageUrl) throws IOException {
return getMessage(messageUrl, null);
}
public Message getMessage(String messageUrl, String webMessageUrl) throws IOException {
// TODO switch according to Log4J log level // TODO switch according to Log4J log level
@ -420,7 +434,7 @@ public class ExchangeSession {
} }
ResponseEntity entity = (ResponseEntity) messageEnum.nextElement(); ResponseEntity entity = (ResponseEntity) messageEnum.nextElement();
return buildMessage(entity); return buildMessage(entity, webMessageUrl);
} }
@ -482,6 +496,8 @@ public class ExchangeSession {
folder.folderUrl = null; folder.folderUrl = null;
if ("INBOX".equals(folderName)) { if ("INBOX".equals(folderName)) {
folder.folderUrl = inboxUrl; folder.folderUrl = inboxUrl;
} else if ("TRASH".equals(folderName)) {
folder.folderUrl = deleteditemsUrl;
} else { } else {
folder.folderUrl = mailPath + folderName; folder.folderUrl = mailPath + folderName;
} }
@ -520,6 +536,10 @@ public class ExchangeSession {
public static final String CONTENT_TYPE_HEADER = "Content-Type: "; public static final String CONTENT_TYPE_HEADER = "Content-Type: ";
public static final String CONTENT_TRANSFER_ENCODING_HEADER = "Content-Transfer-Encoding: "; public static final String CONTENT_TRANSFER_ENCODING_HEADER = "Content-Transfer-Encoding: ";
public String messageUrl; public String messageUrl;
/**
* OWA generated page URL, maybe different from DAV url
*/
public String webMessageUrl;
public String uid; public String uid;
public int size; public int size;
public String fullHeaders; public String fullHeaders;
@ -583,7 +603,7 @@ public class ExchangeSession {
if (priority != null) { if (priority != null) {
fullHeaders += "X-Priority: " + priority + "\n"; fullHeaders += "X-Priority: " + priority + "\n";
} }
if (cc != null) { if (cc != null && cc.length() > 0) {
fullHeaders += "CC: " + cc + "\n"; fullHeaders += "CC: " + cc + "\n";
} }
} catch (ParseException e) { } catch (ParseException e) {
@ -633,7 +653,7 @@ public class ExchangeSession {
// exchange message : create mime part headers // exchange message : create mime part headers
if (boundary != null) { if (boundary != null) {
attachmentsMap = getAttachments(messageUrl); attachmentsMap = getAttachments(webMessageUrl);
// TODO : test actual header values // TODO : test actual header values
result.append("\n--").append(boundary) result.append("\n--").append(boundary)
.append("\nContent-Type: text/html") .append("\nContent-Type: text/html")
@ -704,7 +724,7 @@ public class ExchangeSession {
} else { } else {
attachmentIndex = 0; attachmentIndex = 0;
attachmentsMap = getAttachments(messageUrl); attachmentsMap = getAttachments(webMessageUrl);
writeMimeMessage(reader, os, mimeHeader, attachmentsMap); writeMimeMessage(reader, os, mimeHeader, attachmentsMap);
} }
os.flush(); os.flush();
@ -739,18 +759,18 @@ public class ExchangeSession {
attachmentIndex++; attachmentIndex++;
writeBody(os, partHeader); writeBody(os, partHeader);
} else { } else {
String attachmentUrl = attachmentsMap.get(partHeader.name).href; Attachment attachment = attachmentsMap.get(partHeader.name);
// try to get attachment by index, only if no name found // try to get attachment by index, only if no name found
if (attachmentUrl == null && partHeader.name == null) { if (attachment == null && partHeader.name == null) {
attachmentUrl = attachmentsMap.get(String.valueOf(attachmentIndex)).href; attachment = attachmentsMap.get(String.valueOf(attachmentIndex));
} }
if (attachmentUrl == null) { if (attachment == null) {
// only warn, could happen depending on IIS config // only warn, could happen depending on IIS config
//throw new IOException("Attachment " + partHeader.name + " not found in " + messageUrl); //throw new IOException("Attachment " + partHeader.name + " not found in " + messageUrl);
logger.warn("Attachment " + partHeader.name + " not found in " + messageUrl); logger.warn("Attachment " + partHeader.name + " not found in " + messageUrl);
} else { } else {
attachmentIndex++; attachmentIndex++;
writeAttachment(os, partHeader, attachmentUrl); writeAttachment(os, partHeader, attachment);
} }
} }
} }
@ -763,7 +783,7 @@ public class ExchangeSession {
} }
} }
protected void writeAttachment(OutputStream os, MimeHeader mimeHeader, String attachmentUrl) throws IOException { protected void writeAttachment(OutputStream os, MimeHeader mimeHeader, Attachment attachment) throws IOException {
try { try {
OutputStream quotedOs; OutputStream quotedOs;
try { try {
@ -776,18 +796,26 @@ public class ExchangeSession {
} catch (MessagingException e) { } catch (MessagingException e) {
throw new IOException(e.getMessage()); throw new IOException(e.getMessage());
} }
String decodedPath = URIUtil.decode(attachmentUrl); String decodedPath = URIUtil.decode(attachment.href);
if ("message/rfc822".equals(mimeHeader.contentType)) { if ("message/rfc822".equals(mimeHeader.contentType)) {
// messages are not available at the attachment URL, but
// directly under the main message
String messageAttachmentPath = decodedPath; String messageAttachmentPath = decodedPath;
int index = decodedPath.toLowerCase().lastIndexOf(".eml");
if (index > 0) { // Get real attachment path from owa page content
messageAttachmentPath = decodedPath.substring(0, index + 4); GetMethod method = new GetMethod(URIUtil.encodePath(decodedPath));
wdr.retrieveSessionInstance().executeMethod(method);
String body = method.getResponseBodyAsString();
final String URL_DECLARATION = "var g_szURL\t= \"";
int messageUrlBeginIndex = body.indexOf(URL_DECLARATION);
if (messageUrlBeginIndex >= 0) {
messageUrlBeginIndex = messageUrlBeginIndex + URL_DECLARATION.length();
int messageUrlEndIndex = body.indexOf("/\"", messageUrlBeginIndex);
if (messageUrlBeginIndex >= 0) {
messageAttachmentPath = URIUtil.decode(body.substring(messageUrlBeginIndex, messageUrlEndIndex));
}
} }
Message attachedMessage = getMessage(messageAttachmentPath); Message attachedMessage = getMessage(messageAttachmentPath, decodedPath);
attachedMessage.write(quotedOs); attachedMessage.write(quotedOs);
} else { } else {
@ -1024,11 +1052,18 @@ public class ExchangeSession {
// exclude external URLs // exclude external URLs
if (attachmentHref.startsWith(messageUrl)) { if (attachmentHref.startsWith(messageUrl)) {
String attachmentName = attachmentHref.substring(messageUrl.length() + 1); String attachmentName = attachmentHref.substring(messageUrl.length() + 1);
// yet another case, attached messages ?
final String ANOTHER_MULTIPART_STRING = "1_multipart/2_";
int anotherMultipartIndex = attachmentName.indexOf(ANOTHER_MULTIPART_STRING);
if (anotherMultipartIndex >= 0) {
attachmentName = attachmentName.substring(anotherMultipartIndex + ANOTHER_MULTIPART_STRING.length());
}
int slashIndex = attachmentName.indexOf('/'); int slashIndex = attachmentName.indexOf('/');
if (slashIndex >= 0) { if (slashIndex >= 0) {
attachmentName = attachmentName.substring(0, slashIndex); attachmentName = attachmentName.substring(0, slashIndex);
} }
// attachmentName is now right for Exchange message, need to handle external MIME messages // attachmentName is now right for Exchange messages, need to handle external MIME messages
final String MULTIPART_STRING = "1_multipart_xF8FF_"; final String MULTIPART_STRING = "1_multipart_xF8FF_";
if (attachmentName.startsWith(MULTIPART_STRING)) { if (attachmentName.startsWith(MULTIPART_STRING)) {
attachmentName = attachmentName.substring(MULTIPART_STRING.length()); attachmentName = attachmentName.substring(MULTIPART_STRING.length());
@ -1146,14 +1181,20 @@ public class ExchangeSession {
public String boundary = null; public String boundary = null;
public String name = null; public String name = null;
protected void writeLine(OutputStream os, String line) throws IOException {
if (os != null) {
os.write(line.getBytes());
os.write('\r');
os.write('\n');
}
}
public void processHeaders(BufferedReader reader, OutputStream os) throws IOException { public void processHeaders(BufferedReader reader, OutputStream os) throws IOException {
String line; String line;
line = reader.readLine(); line = reader.readLine();
while (line != null && line.length() > 0) { while (line != null && line.length() > 0) {
os.write(line.getBytes()); writeLine(os, line);
os.write('\r');
os.write('\n');
String lineToCompare = line.toLowerCase(); String lineToCompare = line.toLowerCase();
@ -1165,9 +1206,7 @@ public class ExchangeSession {
line = reader.readLine(); line = reader.readLine();
header.append(line); header.append(line);
os.write(line.getBytes()); writeLine(os, line);
os.write('\r');
os.write('\n');
} }
// decode header with accented file name (URL encoded) // decode header with accented file name (URL encoded)
int encodedIndex = header.indexOf("*="); int encodedIndex = header.indexOf("*=");
@ -1217,8 +1256,20 @@ public class ExchangeSession {
} }
line = reader.readLine(); line = reader.readLine();
} }
os.write('\r'); writeLine(os, "");
os.write('\n');
// strip header content for attached messages
if ("message/rfc822".equals(contentType)) {
MimeHeader internalMimeHeader = new MimeHeader();
internalMimeHeader.processHeaders(reader, null);
if (internalMimeHeader.boundary != null) {
String endBoundary = internalMimeHeader.boundary + "--";
line = reader.readLine();
while (line != null && !endBoundary.equals(line)) {
line = reader.readLine();
}
}
}
} }
} }
} }