diff --git a/lib/Horde/Core/ActiveSync/Driver.php b/lib/Horde/Core/ActiveSync/Driver.php index 0ec40b98..b04361e9 100644 --- a/lib/Horde/Core/ActiveSync/Driver.php +++ b/lib/Horde/Core/ActiveSync/Driver.php @@ -2789,9 +2789,12 @@ public function getSearchResults(Horde_ActiveSync_Search_Params $params): Horde_ { $type = Horde_String::lower($params->type); $rows = null; + $progress = $params->options['progress'] ?? null; + $cacheOptions = $params->options; + unset($cacheOptions['progress'], $cacheOptions['deadline'], $cacheOptions['stats']); if ($this->_cache) { - $cache_key = 'HCASD:' . $type . ':' . $GLOBALS['registry']->getAuth() . ':' . hash('md5', serialize([$params->query, $params->deepTraversal, $params->options])); + $cache_key = 'HCASD:' . $type . ':' . $GLOBALS['registry']->getAuth() . ':' . hash('md5', serialize([$params->query, $params->deepTraversal, $cacheOptions])); if ($this->_cache->exists($cache_key, 0)) { if ($params->rebuildResults) { $this->_cache->expire($cache_key); @@ -2802,7 +2805,12 @@ public function getSearchResults(Horde_ActiveSync_Search_Params $params): Horde_ } if ($rows === null) { - ob_start(); + // A progress callback writes WBXML keep-alives to the client; + // capturing stdout would swallow them. + $captureOutput = !is_callable($progress); + if ($captureOutput) { + ob_start(); + } try { switch ($type) { case 'gal': @@ -2824,10 +2832,16 @@ public function getSearchResults(Horde_ActiveSync_Search_Params $params): Horde_ $rows = null; } - $this->_endBuffer(); + if ($captureOutput) { + $this->_endBuffer(); + } if ($rows !== null && $this->_cache) { - $this->_cache->set($cache_key, json_encode($rows)); + $truncated = is_object($params->options['stats'] ?? null) + && !empty($params->options['stats']->truncated); + if (!$truncated) { + $this->_cache->set($cache_key, json_encode($rows)); + } } }