Caldav: experimental chunked transfer encoding support

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@456 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2009-03-19 07:42:37 +00:00
parent 394c08e9a6
commit df9071c572
2 changed files with 74 additions and 15 deletions

View File

@ -90,9 +90,22 @@ public class AbstractConnection extends Thread {
* @throws IOException on error * @throws IOException on error
*/ */
public void sendClient(byte[] messageBytes) throws IOException { public void sendClient(byte[] messageBytes) throws IOException {
StringBuffer logBuffer = new StringBuffer("> "); sendClient(messageBytes, 0, messageBytes.length);
logBuffer.append(new String(messageBytes)); }
os.write(messageBytes);
/**
* Send only bytes to client.
*
* @param messageBytes content
* @param offset the start offset in the data.
* @param length the number of bytes to write.
* @throws IOException on error
*/
public void sendClient(byte[] messageBytes, int offset, int length) throws IOException {
//StringBuffer logBuffer = new StringBuffer("> ");
//logBuffer.append(new String(messageBytes));
//DavGatewayTray.debug(logBuffer.toString());
os.write(messageBytes, offset, length);
os.flush(); os.flush();
} }

View File

@ -22,6 +22,9 @@ import java.net.SocketException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
/** /**
* Handle a caldav connection. * Handle a caldav connection.
@ -149,7 +152,7 @@ public class CaldavConnection extends AbstractConnection {
DavGatewayTray.debug("Connection closed"); DavGatewayTray.debug("Connection closed");
} catch (IOException e) { } catch (IOException e) {
if (e instanceof HttpException) { if (e instanceof HttpException) {
DavGatewayTray.error(((HttpException)e).getReasonCode()+" "+((HttpException)e).getReason(), e); DavGatewayTray.error(((HttpException) e).getReasonCode() + " " + ((HttpException) e).getReason(), e);
} else { } else {
DavGatewayTray.error(e); DavGatewayTray.error(e);
} }
@ -451,7 +454,7 @@ public class CaldavConnection extends AbstractConnection {
String eventName = getEventFileNameFromPath(href); String eventName = getEventFileNameFromPath(href);
if (eventName == null) { if (eventName == null) {
notFound.add(href); notFound.add(href);
} else if ("inbox".equals(eventName)){ } else if ("inbox".equals(eventName)) {
// Sunbird: just ignore // Sunbird: just ignore
} else { } else {
events.add(session.getEvent(path, eventName)); events.add(session.getEvent(path, eventName));
@ -466,7 +469,11 @@ public class CaldavConnection extends AbstractConnection {
events = session.getAllEvents(); events = session.getAllEvents();
} }
CaldavResponse response = new CaldavResponse(); HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Transfer-Encoding", "chunked");
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, headers, false);
CaldavResponse response = new CaldavResponse(true);
response.startMultistatus(); response.startMultistatus();
appendEventsResponses(response, request, path, events); appendEventsResponses(response, request, path, events);
@ -477,8 +484,7 @@ public class CaldavConnection extends AbstractConnection {
response.endResponse(); response.endResponse();
} }
response.endMultistatus(); response.endMultistatus();
response.close();
sendHttpResponse(HttpStatus.SC_MULTI_STATUS, null, response, true);
} }
public void sendUserRoot(CaldavRequest request, int depth, String principal) throws IOException { public void sendUserRoot(CaldavRequest request, int depth, String principal) throws IOException {
@ -705,7 +711,7 @@ public class CaldavConnection extends AbstractConnection {
sendClient("Connection: " + (closed ? "close" : "keep-alive")); sendClient("Connection: " + (closed ? "close" : "keep-alive"));
if (content != null && content.length > 0) { if (content != null && content.length > 0) {
sendClient("Content-Length: " + content.length); sendClient("Content-Length: " + content.length);
} else { } else if (headers == null || !"chunked".equals(headers.get("Transfer-Encoding"))) {
sendClient("Content-Length: 0"); sendClient("Content-Length: 0");
} }
sendClient(""); sendClient("");
@ -815,15 +821,53 @@ public class CaldavConnection extends AbstractConnection {
} }
} }
protected static class CaldavResponse { protected class CaldavResponse {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream outputStream;
OutputStreamWriter writer; Writer writer;
public CaldavResponse() throws IOException { public CaldavResponse() throws IOException {
writer = new OutputStreamWriter(baos, "UTF-8"); outputStream = new ByteArrayOutputStream();
writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
} }
public CaldavResponse(boolean chunked) throws IOException {
if (chunked) {
writer = new OutputStreamWriter(new BufferedOutputStream(new OutputStream() {
public void write(byte[] data, int offset, int length) throws IOException {
sendClient(Integer.toHexString(length));
sendClient(data, offset, length);
sendClient("");
}
public void write(int b) throws IOException {
throw new UnsupportedOperationException();
}
}), "UTF-8");
/*
writer = new BufferedWriter(new Writer() {
public void write(char[] cbuf, int off, int len) throws IOException {
byte[] data = new String(cbuf, off, len).getBytes("UTF-8");
sendClient(Integer.toHexString(data.length));
sendClient(data);
sendClient("");
}
public void flush() throws IOException {
// ignore
}
public void close() throws IOException {
sendClient("0");
}
});*/
} else {
outputStream = new ByteArrayOutputStream();
writer = new OutputStreamWriter(outputStream, "UTF-8");
}
writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
}
public void startMultistatus() throws IOException { public void startMultistatus() throws IOException {
writer.write("<D:multistatus xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">"); writer.write("<D:multistatus xmlns:D=\"DAV:\" xmlns:C=\"urn:ietf:params:xml:ns:caldav\">");
} }
@ -924,13 +968,15 @@ public class CaldavConnection extends AbstractConnection {
try { try {
writer.close(); writer.close();
} finally { } finally {
baos.close(); if (outputStream != null) {
outputStream.close();
}
} }
} }
public byte[] getBytes() throws IOException { public byte[] getBytes() throws IOException {
close(); close();
return baos.toByteArray(); return outputStream.toByteArray();
} }
} }
} }