mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-20 14:13:19 +00:00
improved handling of EAS Push when no heartbeat is provided
This commit is contained in:
@@ -1065,13 +1065,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
changeDetected: (BOOL *) changeDetected
|
||||
maxSyncResponseSize: (int) theMaxSyncResponseSize
|
||||
{
|
||||
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey;
|
||||
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey, *syncKeyInCache;
|
||||
SOGoMicrosoftActiveSyncFolderType folderType;
|
||||
id collection, value;
|
||||
|
||||
NSMutableString *changeBuffer, *commandsBuffer;
|
||||
BOOL getChanges, first_sync;
|
||||
unsigned int windowSize, v, status;
|
||||
NSMutableDictionary *folderMetadata;
|
||||
|
||||
changeBuffer = [NSMutableString string];
|
||||
commandsBuffer = [NSMutableString string];
|
||||
@@ -1186,6 +1187,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[commandsBuffer appendFormat: @"<Responses>%@</Responses>", s];
|
||||
}
|
||||
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]];
|
||||
|
||||
// If we got any changes or if we have applied any commands
|
||||
// let's regenerate our SyncKey based on the collection tag.
|
||||
if ([changeBuffer length] || [commandsBuffer length])
|
||||
@@ -1196,7 +1199,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
// Use the SyncKey saved by processSyncGetChanges - if processSyncGetChanges is not called (because of getChanges=false)
|
||||
// SyncKey has the value of the previous sync operation.
|
||||
davCollectionTag = [[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncKey"];
|
||||
davCollectionTag = [folderMetadata objectForKey: @"SyncKey"];
|
||||
|
||||
if (!davCollectionTag)
|
||||
davCollectionTag = [collection davCollectionTag];
|
||||
@@ -1206,8 +1209,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (folderType == ActiveSyncMailFolder && [syncKey isEqualToString: @"-1"])
|
||||
davCollectionTag = [collection davCollectionTag];
|
||||
// Make sure that client is updated with the right syncKey. - This keeps vtodo's and vevent's syncKey in sync.
|
||||
syncKeyInCache = [folderMetadata objectForKey: @"SyncKey"];
|
||||
if (syncKeyInCache && !([davCollectionTag isEqualToString:syncKeyInCache]))
|
||||
{
|
||||
davCollectionTag = syncKeyInCache;
|
||||
*changeDetected = YES;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the response buffer
|
||||
@@ -1228,7 +1236,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// MoreAvailable breaks Windows Mobile devices if not between <Status> and <Commands>
|
||||
// https://social.msdn.microsoft.com/Forums/en-US/040b254e-f47e-4cc1-a397-6d8393cdb819/airsyncmoreavailable-breaks-windows-mobile-devices-what-am-i-doing-wrong?forum=os_exchangeprotocols
|
||||
if ([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"MoreAvailable"])
|
||||
if ([folderMetadata objectForKey: @"MoreAvailable"])
|
||||
[theBuffer appendString: @"<MoreAvailable/>"];
|
||||
|
||||
[theBuffer appendString: commandsBuffer];
|
||||
@@ -1373,6 +1381,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
defaultInterval = [defaults maximumSyncInterval];
|
||||
internalInterval = [defaults internalSyncInterval];
|
||||
|
||||
// If the request doesn't contain "HeartbeatInterval" there is no reason to delay the response.
|
||||
if (heartbeatInterval == 0)
|
||||
heartbeatInterval = internalInterval = 1;
|
||||
|
||||
// We check to see if our heartbeat interval falls into the supported ranges.
|
||||
if (heartbeatInterval > defaultInterval || heartbeatInterval < 1)
|
||||
{
|
||||
@@ -1389,7 +1401,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
allCollections = (id)[theDocumentElement getElementsByTagName: @"Collection"];
|
||||
|
||||
// We enter our loop detection change
|
||||
for (i = 0; i < (defaultInterval/internalInterval); i++)
|
||||
for (i = 0; i < (heartbeatInterval/internalInterval); i++)
|
||||
{
|
||||
s = [NSMutableString string];
|
||||
|
||||
@@ -1408,11 +1420,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[self logWithFormat: @"Change detected, we push the content."];
|
||||
break;
|
||||
}
|
||||
else
|
||||
else if (heartbeatInterval > 1)
|
||||
{
|
||||
[self logWithFormat: @"Sleeping %d seconds while detecting changes...", internalInterval];
|
||||
sleep(internalInterval);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only send a response if there are changes otherwise send an empty response.
|
||||
|
||||
@@ -1806,30 +1806,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// We build the list of folders to "ping". When the payload is empty, we use the list
|
||||
// of "cached" folders.
|
||||
allCollections = (id)[theDocumentElement getElementsByTagName: @"Folders"];
|
||||
allCollections = (id)[theDocumentElement getElementsByTagName: @"Folder"];
|
||||
allFoldersID = [NSMutableArray array];
|
||||
|
||||
if (![allCollections count])
|
||||
{
|
||||
SOGoMailAccounts *accountsFolder;
|
||||
SOGoMailAccount *accountFolder;
|
||||
SOGoUserFolder *userFolder;
|
||||
NSArray *allValues;
|
||||
// We received an empty Ping request. Return status '3' to ask client to resend the request with complete body.
|
||||
s = [NSMutableString string];
|
||||
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<Ping xmlns=\"Ping:\">"];
|
||||
[s appendString: @"<Status>3</Status>"];
|
||||
[s appendString: @"</Ping>"];
|
||||
|
||||
userFolder = [[context activeUser] homeFolderInContext: context];
|
||||
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
|
||||
accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
|
||||
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
|
||||
|
||||
allValues = [[accountFolder imapFolderGUIDs] allValues];
|
||||
|
||||
for (i = 0; i < [allValues count]; i++)
|
||||
[allFoldersID addObject: [NSString stringWithFormat: @"mail/%@", [[allValues objectAtIndex: i] substringFromIndex: 6]]];
|
||||
[theResponse setContent: d];
|
||||
|
||||
|
||||
// FIXME: handle multiple GCS collecitons
|
||||
[allFoldersID addObject: @"vcard/personal"];
|
||||
[allFoldersID addObject: @"vevent/personal"];
|
||||
[allFoldersID addObject: @"vtodo/personal"];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user