Allow sync data to arrive via the chunked transfer encoding.
* Fixes #2216885 * The bug is that the sync adapters weren't set up to handle chunked encoding, primarily because 1) I hadn't seen any servers use it, and 2) when we changed from HttpUrlConnection to HttpClient, support for chunked wasn't added (HttpUrlConnection didn't support it) * The fix for xml data is trivial, since the Content-Length returned in the chunked case (-1) was being disallowed, but works perfectly well with HttpClient. * The fix for attachments is less trivial, but still straightforward. * With this change, we are no longer dependent on receiving content-length, which is highly desirable Change-Id: Ie3bd6af0cf68f3afa190711d96b1dbd2e6341f79
This commit is contained in:
parent
e7965e975f
commit
ccd29c33ed
@ -314,19 +314,44 @@ public class EasSyncService extends AbstractSyncService {
|
||||
destDir.mkdirs();
|
||||
}
|
||||
FileOutputStream os = new FileOutputStream(f);
|
||||
if (len > 0) {
|
||||
// len > 0 means that Content-Length was set in the headers
|
||||
// len < 0 means "chunked" transfer-encoding
|
||||
if (len != 0) {
|
||||
try {
|
||||
mPendingPartRequest = req;
|
||||
byte[] bytes = new byte[CHUNK_SIZE];
|
||||
int length = len;
|
||||
while (len > 0) {
|
||||
int n = (len > CHUNK_SIZE ? CHUNK_SIZE : len);
|
||||
int read = is.read(bytes, 0, n);
|
||||
// Loop terminates 1) when EOF is reached or 2) if an IOException occurs
|
||||
// One of these is guaranteed to occur
|
||||
int totalRead = 0;
|
||||
userLog("Attachment content-length: ", len);
|
||||
while (true) {
|
||||
int read = is.read(bytes, 0, CHUNK_SIZE);
|
||||
|
||||
// read < 0 means that EOF was reached
|
||||
if (read < 0) {
|
||||
userLog("Attachment load reached EOF, totalRead: ", totalRead);
|
||||
break;
|
||||
}
|
||||
|
||||
// Keep track of how much we've read for progress callback
|
||||
totalRead += read;
|
||||
|
||||
// Write these bytes out
|
||||
os.write(bytes, 0, read);
|
||||
len -= read;
|
||||
int pct = ((length - len) * 100 / length);
|
||||
doProgressCallback(msg.mId, att.mId, pct);
|
||||
}
|
||||
|
||||
// We can't report percentages if this is chunked; by definition, the
|
||||
// length of incoming data is unknown
|
||||
if (length > 0) {
|
||||
// Belt and suspenders check to prevent runaway reading
|
||||
if (totalRead > length) {
|
||||
errorLog("totalRead is greater than attachment length?");
|
||||
break;
|
||||
}
|
||||
int pct = (totalRead * 100 / length);
|
||||
doProgressCallback(msg.mId, att.mId, pct);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mPendingPartRequest = null;
|
||||
}
|
||||
@ -562,7 +587,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
if (code == HttpStatus.SC_OK) {
|
||||
HttpEntity entity = resp.getEntity();
|
||||
int len = (int)entity.getContentLength();
|
||||
if (len > 0) {
|
||||
if (len != 0) {
|
||||
InputStream is = entity.getContent();
|
||||
// Returns true if we need to sync again
|
||||
if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
|
||||
@ -747,7 +772,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
HttpEntity e = res.getEntity();
|
||||
int len = (int)e.getContentLength();
|
||||
InputStream is = res.getEntity().getContent();
|
||||
if (len > 0) {
|
||||
if (len != 0) {
|
||||
int pingResult = parsePingResult(is, mContentResolver, pingErrorMap);
|
||||
// If our ping completed (status = 1), and we weren't forced and we're
|
||||
// not at the maximum, try increasing timeout by two minutes
|
||||
@ -1019,7 +1044,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
HttpResponse resp = sendHttpClientPost("Sync", s.toByteArray());
|
||||
int code = resp.getStatusLine().getStatusCode();
|
||||
if (code == HttpStatus.SC_OK) {
|
||||
InputStream is = resp.getEntity().getContent();
|
||||
InputStream is = resp.getEntity().getContent();
|
||||
if (is != null) {
|
||||
moreAvailable = target.parse(is);
|
||||
target.cleanup();
|
||||
|
Loading…
Reference in New Issue
Block a user