mirror of
https://github.com/moparisthebest/davmail
synced 2024-12-13 11:12:22 -05:00
Caldav: Fix Connection: close handling and ensure full content read
git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@351 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
parent
bb71ebf95a
commit
0ac3b1a938
@ -62,11 +62,20 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
throw new IOException("Invalid content length: " + contentLength);
|
throw new IOException("Invalid content length: " + contentLength);
|
||||||
}
|
}
|
||||||
char[] buffer = new char[size];
|
char[] buffer = new char[size];
|
||||||
int actualSize = in.read(buffer);
|
StringBuilder builder = new StringBuilder();
|
||||||
if (actualSize < 0) {
|
int actualSize = in.read(buffer);
|
||||||
throw new IOException("End of stream reached reading content");
|
builder.append(buffer, 0, actualSize);
|
||||||
|
if (actualSize < 0) {
|
||||||
|
throw new IOException("End of stream reached reading content");
|
||||||
|
}
|
||||||
|
// dirty hack to ensure full content read
|
||||||
|
// TODO : replace with a dedicated reader
|
||||||
|
while (builder.toString().getBytes("UTF-8").length < size) {
|
||||||
|
actualSize = in.read(buffer);
|
||||||
|
builder.append(buffer, 0, actualSize);
|
||||||
}
|
}
|
||||||
return new String(buffer, 0, actualSize);
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +114,8 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
String path = tokens.nextToken();
|
String path = tokens.nextToken();
|
||||||
String content = getContent(headers.get("content-length"));
|
String content = getContent(headers.get("content-length"));
|
||||||
setSocketTimeout(headers.get("keep-alive"));
|
setSocketTimeout(headers.get("keep-alive"));
|
||||||
|
// client requested connection close
|
||||||
|
closed = "close".equals(headers.get("connection"));
|
||||||
if ("OPTIONS".equals(command)) {
|
if ("OPTIONS".equals(command)) {
|
||||||
sendOptions();
|
sendOptions();
|
||||||
} else if (!headers.containsKey("authorization")) {
|
} else if (!headers.containsKey("authorization")) {
|
||||||
@ -209,8 +220,8 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
} else if ("PROPFIND".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
||||||
sendOutbox(request, paths[2]);
|
sendOutbox(request, paths[2]);
|
||||||
} else if ("POST".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
} else if ("POST".equals(command) && "users".equals(paths[1]) && paths.length == 4 && "outbox".equals(paths[3])) {
|
||||||
if (body.indexOf("VFREEBUSY") >=0) {
|
if (body.indexOf("VFREEBUSY") >= 0) {
|
||||||
sendFreeBusy(body);
|
sendFreeBusy(body);
|
||||||
} else {
|
} else {
|
||||||
int status = session.sendEvent(body);
|
int status = session.sendEvent(body);
|
||||||
sendHttpResponse(status, true);
|
sendHttpResponse(status, true);
|
||||||
@ -227,8 +238,14 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
&& session.getEmail().equalsIgnoreCase(paths[2])) {
|
&& session.getEmail().equalsIgnoreCase(paths[2])) {
|
||||||
String etag = headers.get("if-match");
|
String etag = headers.get("if-match");
|
||||||
String noneMatch = headers.get("if-none-match");
|
String noneMatch = headers.get("if-none-match");
|
||||||
int status = session.createOrUpdateEvent(paths[4], body, etag, noneMatch);
|
ExchangeSession.EventResult eventResult = session.createOrUpdateEvent(paths[4], body, etag, noneMatch);
|
||||||
sendHttpResponse(status, true);
|
if (eventResult.etag != null) {
|
||||||
|
HashMap<String, String> responseHeaders = new HashMap<String, String>();
|
||||||
|
responseHeaders.put("GetETag", eventResult.etag);
|
||||||
|
sendHttpResponse(eventResult.status, responseHeaders, "text/html", "", true);
|
||||||
|
} else {
|
||||||
|
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 && "calendar".equals(paths[3])
|
||||||
// only current user for now
|
// only current user for now
|
||||||
@ -417,7 +434,7 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
if (depth == 1) {
|
if (depth == 1) {
|
||||||
DavGatewayTray.debug("Searching calendar events...");
|
DavGatewayTray.debug("Searching calendar events...");
|
||||||
List<ExchangeSession.Event> events = session.getAllEvents();
|
List<ExchangeSession.Event> events = session.getAllEvents();
|
||||||
DavGatewayTray.debug("Found "+events.size()+" calendar events");
|
DavGatewayTray.debug("Found " + events.size() + " calendar events");
|
||||||
appendEventsResponses(buffer, request, events);
|
appendEventsResponses(buffer, request, events);
|
||||||
}
|
}
|
||||||
buffer.append("</D:multistatus>");
|
buffer.append("</D:multistatus>");
|
||||||
@ -441,7 +458,7 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
int total = request.getHrefs().size();
|
int total = request.getHrefs().size();
|
||||||
for (String href : request.getHrefs()) {
|
for (String href : request.getHrefs()) {
|
||||||
DavGatewayTray.debug("Report event "+(++count)+"/"+total);
|
DavGatewayTray.debug("Report event " + (++count) + "/" + total);
|
||||||
try {
|
try {
|
||||||
String eventName = getEventFileNameFromPath(href);
|
String eventName = getEventFileNameFromPath(href);
|
||||||
if (eventName == null) {
|
if (eventName == null) {
|
||||||
@ -586,20 +603,20 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
String line;
|
String line;
|
||||||
String key;
|
String key;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
int index = line.indexOf(':');
|
int index = line.indexOf(':');
|
||||||
if (index <= 0) {
|
if (index <= 0) {
|
||||||
throw new IOException("Invalid request: " + body);
|
throw new IOException("Invalid request: " + body);
|
||||||
}
|
}
|
||||||
String fullkey = line.substring(0, index);
|
String fullkey = line.substring(0, index);
|
||||||
String value = line.substring(index + 1);
|
String value = line.substring(index + 1);
|
||||||
int semicolonIndex = fullkey.indexOf(";");
|
int semicolonIndex = fullkey.indexOf(";");
|
||||||
if (semicolonIndex > 0) {
|
if (semicolonIndex > 0) {
|
||||||
key = fullkey.substring(0, semicolonIndex);
|
key = fullkey.substring(0, semicolonIndex);
|
||||||
} else {
|
} else {
|
||||||
key = fullkey;
|
key = fullkey;
|
||||||
}
|
}
|
||||||
valueMap.put(key, value);
|
valueMap.put(key, value);
|
||||||
keyMap.put(key, fullkey);
|
keyMap.put(key, fullkey);
|
||||||
}
|
}
|
||||||
String freeBusy = session.getFreebusy(valueMap);
|
String freeBusy = session.getFreebusy(valueMap);
|
||||||
if (freeBusy != null) {
|
if (freeBusy != null) {
|
||||||
@ -690,8 +707,8 @@ public class CaldavConnection extends AbstractConnection {
|
|||||||
if (contentType != null) {
|
if (contentType != null) {
|
||||||
sendClient("Content-Type: " + contentType);
|
sendClient("Content-Type: " + contentType);
|
||||||
}
|
}
|
||||||
sendClient("Connection: " + (keepAlive ? "keep-alive" : "close"));
|
closed = closed || !keepAlive;
|
||||||
closed = !keepAlive;
|
sendClient("Connection: " + (closed ? "close" : "keep-alive"));
|
||||||
if (content != null && content.length() > 0) {
|
if (content != null && content.length() > 0) {
|
||||||
sendClient("Content-Length: " + content.getBytes("UTF-8").length);
|
sendClient("Content-Length: " + content.getBytes("UTF-8").length);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1329,9 +1329,14 @@ public class ExchangeSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class EventResult {
|
||||||
|
public int status;
|
||||||
|
public String etag;
|
||||||
|
}
|
||||||
|
|
||||||
public int sendEvent(String icsBody) throws IOException {
|
public int sendEvent(String icsBody) throws IOException {
|
||||||
String messageUrl = URIUtil.encodePathQuery(draftsUrl + "/" + UUID.randomUUID().toString() + ".EML");
|
String messageUrl = URIUtil.encodePathQuery(draftsUrl + "/" + UUID.randomUUID().toString() + ".EML");
|
||||||
int status = internalCreateOrUpdateEvent(messageUrl, icsBody, null, null);
|
int status = internalCreateOrUpdateEvent(messageUrl, icsBody, null, null).status;
|
||||||
if (status != HttpStatus.SC_CREATED) {
|
if (status != HttpStatus.SC_CREATED) {
|
||||||
return status;
|
return status;
|
||||||
} else {
|
} else {
|
||||||
@ -1344,12 +1349,12 @@ public class ExchangeSession {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int createOrUpdateEvent(String path, String icsBody, String etag, String noneMatch) throws IOException {
|
public EventResult createOrUpdateEvent(String path, String icsBody, String etag, String noneMatch) throws IOException {
|
||||||
String messageUrl = URIUtil.encodePathQuery(calendarUrl + "/" + URIUtil.decode(path));
|
String messageUrl = URIUtil.encodePathQuery(calendarUrl + "/" + URIUtil.decode(path));
|
||||||
return internalCreateOrUpdateEvent(messageUrl, icsBody, etag, noneMatch);
|
return internalCreateOrUpdateEvent(messageUrl, icsBody, etag, noneMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int internalCreateOrUpdateEvent(String messageUrl, String icsBody, String etag, String noneMatch) throws IOException {
|
protected EventResult internalCreateOrUpdateEvent(String messageUrl, String icsBody, String etag, String noneMatch) throws IOException {
|
||||||
String uid = UUID.randomUUID().toString();
|
String uid = UUID.randomUUID().toString();
|
||||||
PutMethod putmethod = new PutMethod(messageUrl);
|
PutMethod putmethod = new PutMethod(messageUrl);
|
||||||
putmethod.setRequestHeader("Translate", "f");
|
putmethod.setRequestHeader("Translate", "f");
|
||||||
@ -1391,7 +1396,12 @@ public class ExchangeSession {
|
|||||||
} finally {
|
} finally {
|
||||||
putmethod.releaseConnection();
|
putmethod.releaseConnection();
|
||||||
}
|
}
|
||||||
return status;
|
EventResult eventResult = new EventResult();
|
||||||
|
eventResult.status = status;
|
||||||
|
if (putmethod.getResponseHeader("GetETag") != null) {
|
||||||
|
eventResult.etag = putmethod.getResponseHeader("GetETag").getValue();
|
||||||
|
}
|
||||||
|
return eventResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user