mirror of
https://github.com/moparisthebest/davmail
synced 2024-11-15 05:45:12 -05:00
Caldav: Replace substrings with real MIME message parser to retrieve events, handle ics objects in Inbox
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@398 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
49b4301ce0
commit
9bd3a96b13
@ -175,7 +175,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
|
||||
public void handleRequest(String command, String path, Map<String, String> headers, String body) throws IOException {
|
||||
int depth = getDepth(headers);
|
||||
String[] paths = path.split("/");
|
||||
String[] paths = path.replaceAll("//", "/").split("/");
|
||||
|
||||
// full debug trace
|
||||
if (wireLogger.isDebugEnabled()) {
|
||||
@ -216,7 +216,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "inbox".equals(paths[3])) {
|
||||
sendInbox(request, depth, paths[2]);
|
||||
} else if ("REPORT".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "inbox".equals(paths[3])) {
|
||||
reportEvents(request);
|
||||
reportEvents(request, "INBOX");
|
||||
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
||||
sendOutbox(request, paths[2]);
|
||||
} else if ("POST".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
||||
@ -231,7 +231,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
} else if ("REPORT".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "calendar".equals(paths[3])
|
||||
// only current user for now
|
||||
&& session.getEmail().equalsIgnoreCase(paths[2])) {
|
||||
reportEvents(request);
|
||||
reportEvents(request, "calendar");
|
||||
|
||||
} else if ("PUT".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
|
||||
// only current user for now
|
||||
@ -247,15 +247,18 @@ public class CaldavConnection extends AbstractConnection {
|
||||
sendHttpResponse(eventResult.status, true);
|
||||
}
|
||||
|
||||
} else if ("DELETE".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
|
||||
} else if ("DELETE".equals(command) && "users".equals(paths[1]) && paths.length == 5
|
||||
// only current user for now
|
||||
&& session.getEmail().equalsIgnoreCase(paths[2])) {
|
||||
int status = session.deleteEvent(paths[4]);
|
||||
if ("inbox".equals(paths[3])) {
|
||||
paths[3] = "INBOX";
|
||||
}
|
||||
int status = session.deleteEvent(paths[3]+"/"+paths[4]);
|
||||
sendHttpResponse(status, true);
|
||||
} else if ("GET".equals(command) && "users".equals(paths[1]) && paths.length == 5 && "calendar".equals(paths[3])
|
||||
// only current user for now
|
||||
&& session.getEmail().equalsIgnoreCase(paths[2])) {
|
||||
ExchangeSession.Event event = session.getEvent(paths[4]);
|
||||
ExchangeSession.Event event = session.getEvent(paths[3]+"/"+paths[4]);
|
||||
sendHttpResponse(HttpStatus.SC_OK, null, "text/calendar;charset=UTF-8", event.getICS(), true);
|
||||
|
||||
} else {
|
||||
@ -267,19 +270,19 @@ public class CaldavConnection extends AbstractConnection {
|
||||
}
|
||||
}
|
||||
|
||||
protected void appendEventsResponses(StringBuilder buffer, CaldavRequest request, List<ExchangeSession.Event> events) throws IOException {
|
||||
protected void appendEventsResponses(StringBuilder buffer, CaldavRequest request, String path, List<ExchangeSession.Event> events) throws IOException {
|
||||
int size = events.size();
|
||||
int count = 0;
|
||||
for (ExchangeSession.Event event : events) {
|
||||
DavGatewayTray.debug("Retrieving event " + (++count) + "/" + size);
|
||||
appendEventResponse(buffer, request, event);
|
||||
appendEventResponse(buffer, request, path, event);
|
||||
}
|
||||
}
|
||||
|
||||
protected void appendEventResponse(StringBuilder buffer, CaldavRequest request, ExchangeSession.Event event) throws IOException {
|
||||
protected void appendEventResponse(StringBuilder buffer, CaldavRequest request, String path, ExchangeSession.Event event) throws IOException {
|
||||
String eventPath = event.getPath().replaceAll("<", "<").replaceAll(">", ">");
|
||||
buffer.append("<D:response>");
|
||||
buffer.append("<D:href>/users/").append(session.getEmail()).append("/calendar").append(URIUtil.encodeWithinQuery(eventPath)).append("</D:href>");
|
||||
buffer.append("<D:href>/users/").append(session.getEmail()).append("/").append(path).append("/").append(URIUtil.encodeWithinQuery(eventPath)).append("</D:href>");
|
||||
buffer.append("<D:propstat>");
|
||||
buffer.append("<D:prop>");
|
||||
if (request.hasProperty("calendar-data")) {
|
||||
@ -408,7 +411,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
DavGatewayTray.debug("Searching calendar messages...");
|
||||
List<ExchangeSession.Event> events = session.getEventMessages();
|
||||
DavGatewayTray.debug("Found " + events.size() + " calendar messages");
|
||||
appendEventsResponses(buffer, request, events);
|
||||
appendEventsResponses(buffer, request, "inbox", events);
|
||||
}
|
||||
buffer.append("</D:multistatus>");
|
||||
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, null, "text/xml;charset=UTF-8", buffer.toString(), true);
|
||||
@ -432,22 +435,22 @@ public class CaldavConnection extends AbstractConnection {
|
||||
DavGatewayTray.debug("Searching calendar events...");
|
||||
List<ExchangeSession.Event> events = session.getAllEvents();
|
||||
DavGatewayTray.debug("Found " + events.size() + " calendar events");
|
||||
appendEventsResponses(buffer, request, events);
|
||||
appendEventsResponses(buffer, request, "calendar", events);
|
||||
}
|
||||
buffer.append("</D:multistatus>");
|
||||
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, null, "text/xml;charset=UTF-8", buffer.toString(), true);
|
||||
}
|
||||
|
||||
protected String getEventFileNameFromPath(String path) {
|
||||
int index = path.indexOf("/calendar/");
|
||||
int index = path.lastIndexOf('/');
|
||||
if (index < 0) {
|
||||
return null;
|
||||
} else {
|
||||
return path.substring(index + "/calendar/".length());
|
||||
return path.substring(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void reportEvents(CaldavRequest request) throws IOException {
|
||||
public void reportEvents(CaldavRequest request, String path) throws IOException {
|
||||
List<ExchangeSession.Event> events;
|
||||
List<String> notFound = new ArrayList<String>();
|
||||
if (request.isMultiGet()) {
|
||||
@ -461,12 +464,14 @@ public class CaldavConnection extends AbstractConnection {
|
||||
if (eventName == null) {
|
||||
notFound.add(href);
|
||||
} else {
|
||||
events.add(session.getEvent(eventName));
|
||||
events.add(session.getEvent(path+"/"+eventName));
|
||||
}
|
||||
} catch (HttpException e) {
|
||||
notFound.add(href);
|
||||
}
|
||||
}
|
||||
} else if ("INBOX".equals(path)){
|
||||
events = session.getEventMessages();
|
||||
} else {
|
||||
events = session.getAllEvents();
|
||||
}
|
||||
@ -474,7 +479,7 @@ public class CaldavConnection extends AbstractConnection {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<D:multistatus xmlns:D=\"DAV:\">");
|
||||
appendEventsResponses(buffer, request, events);
|
||||
appendEventsResponses(buffer, request, path, events);
|
||||
|
||||
// send not found events errors
|
||||
for (String href : notFound) {
|
||||
|
@ -21,6 +21,11 @@ import org.htmlcleaner.CommentToken;
|
||||
import org.htmlcleaner.HtmlCleaner;
|
||||
import org.htmlcleaner.TagNode;
|
||||
|
||||
import javax.mail.BodyPart;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
@ -815,6 +820,8 @@ public class ExchangeSession {
|
||||
folderPath = folderName.replaceFirst("Drafts", draftsUrl);
|
||||
} else if (folderName.startsWith("Sent")) {
|
||||
folderPath = folderName.replaceFirst("Sent", sentitemsUrl);
|
||||
} else if (folderName.startsWith("calendar")) {
|
||||
folderPath = folderName.replaceFirst("calendar", calendarUrl);
|
||||
// absolute folder path
|
||||
} else if (folderName.startsWith("/")) {
|
||||
folderPath = folderName;
|
||||
@ -1069,7 +1076,6 @@ public class ExchangeSession {
|
||||
URIUtil.encodePath(destination));
|
||||
method.addRequestHeader("Overwrite", "f");
|
||||
method.addRequestHeader("Allow-rename", "t");
|
||||
method.setDebug(4);
|
||||
|
||||
int status = wdr.retrieveSessionInstance().executeMethod(method);
|
||||
if (status != HttpStatus.SC_CREATED) {
|
||||
@ -1118,49 +1124,50 @@ public class ExchangeSession {
|
||||
protected String etag;
|
||||
|
||||
public String getICS() throws IOException {
|
||||
String result = null;
|
||||
LOGGER.debug("Get event: " + href);
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
GetMethod method = new GetMethod(URIUtil.encodePath(href));
|
||||
method.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
|
||||
method.setRequestHeader("Translate", "f");
|
||||
BufferedReader eventReader = null;
|
||||
try {
|
||||
int status = wdr.retrieveSessionInstance().executeMethod(method);
|
||||
if (status != HttpStatus.SC_OK) {
|
||||
LOGGER.warn("Unable to get event at " + href + " status: " + status);
|
||||
}
|
||||
eventReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
|
||||
String line;
|
||||
boolean inbody = false;
|
||||
while ((line = eventReader.readLine()) != null) {
|
||||
if ("BEGIN:VCALENDAR".equals(line)) {
|
||||
inbody = true;
|
||||
}
|
||||
if (inbody) {
|
||||
buffer.append(line);
|
||||
buffer.append((char) 13);
|
||||
buffer.append((char) 10);
|
||||
}
|
||||
if ("END:VCALENDAR".equals(line)) {
|
||||
inbody = false;
|
||||
MimeMessage mimeMessage = new MimeMessage(null, method.getResponseBodyAsStream());
|
||||
MimeMultipart multiPart = (MimeMultipart) mimeMessage.getContent();
|
||||
MimeBodyPart bodyPart = null;
|
||||
for (int i = 0; i < multiPart.getCount(); i++) {
|
||||
String contentType = multiPart.getBodyPart(i).getContentType();
|
||||
if (contentType.startsWith("text/calendar") || contentType.startsWith("application/ics") ) {
|
||||
bodyPart = (MimeBodyPart) multiPart.getBodyPart(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (bodyPart == null) {
|
||||
throw new IOException("Invalid message content");
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bodyPart.getDataHandler().writeTo(baos);
|
||||
baos.close();
|
||||
result = fixICS(new String(baos.toByteArray(), "UTF-8"), true);
|
||||
|
||||
} catch (MessagingException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
} finally {
|
||||
if (eventReader != null) {
|
||||
try {
|
||||
eventReader.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Error parsing event at " + method.getPath());
|
||||
}
|
||||
}
|
||||
method.releaseConnection();
|
||||
}
|
||||
return fixICS(buffer.toString(), true);
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return href.substring(calendarUrl.length());
|
||||
int index = href.lastIndexOf('/');
|
||||
if (index >= 0) {
|
||||
return href.substring(index + 1);
|
||||
} else {
|
||||
return href;
|
||||
}
|
||||
}
|
||||
|
||||
public String getEtag() {
|
||||
@ -1225,7 +1232,7 @@ public class ExchangeSession {
|
||||
}
|
||||
|
||||
public Event getEvent(String path) throws IOException {
|
||||
Enumeration calendarEnum = wdr.propfindMethod(calendarUrl + "/" + URIUtil.decode(path), 0, EVENT_REQUEST_PROPERTIES);
|
||||
Enumeration calendarEnum = wdr.propfindMethod(getFolderPath(URIUtil.decode(path)), 0, EVENT_REQUEST_PROPERTIES);
|
||||
if (!calendarEnum.hasMoreElements()) {
|
||||
throw new IOException("Unable to get calendar event");
|
||||
}
|
||||
@ -1563,7 +1570,7 @@ public class ExchangeSession {
|
||||
}
|
||||
|
||||
public int deleteEvent(String path) throws IOException {
|
||||
wdr.deleteMethod(calendarUrl + "/" + URIUtil.decode(path));
|
||||
wdr.deleteMethod(getFolderPath(URIUtil.decode(path)));
|
||||
return wdr.getStatusCode();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user