feat(activesync): add EAS 16.0 Find command support#44
Merged
Conversation
Implement the Find command for protocol version 16.0 so clients such as iOS can search mail via KQL instead of the legacy Search command. - Add Find request handler, DTOs, and QueryMapper (Find → shared IMAP search) - Add Kql parser with OR support for iPhone query patterns - Register Find WBXML code page 0x19 and advertise command for v16.0 - Extend IMAP adapter with deepTraversal, subfolder search, and UID resolution - Handle iOS virtual All Mailboxes folder IDs in ItemOperations fetch - Add unit tests for KQL and QueryMapper; update ServerTest expectations
Check connection_aborted() during IMAP mailbox search and result encoding so cancelled Find requests stop scanning folders and fetching message previews instead of running to completion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add EAS 16.0 Find command support
Summary
Implements the Exchange ActiveSync Find command (protocol version 16.0) so modern clients— notably iOS Mail— can search mailbox content via KQL instead of relying on the legacy Search command.
Find is exposed as a thin protocol layer on top of the existing IMAP search backend used by Search. A companion PR for
horde/corewiresgetFindResults()to IMP; this PR contains allhorde/activesyncchanges.Motivation
iOS 16+ sends
Cmd=Findfor unified mailbox search. Horde previously had no Find handler, which resulted in HTTP 400 (Find not supported). This change adds full request parsing, WBXML encoding, IMAP query execution, and the ItemOperations follow-up needed to open search hits on iPhone.Tested on iPhone (EAS 16.0): global search, subfolder hits, result list, and opening messages from search results.
Changes
Protocol and request handling
Horde_ActiveSync_Request_Find— parses Find requests (SearchId,ExecuteSearch,MailBoxSearchCriterion,GALSearchCriterion,Query,FreeText,Options,Range,DeepTraversal)0x19with token order per MS-ASWBXML / Z-Push (code page 25)Findin supported commands forVERSION_SIXTEENinHorde_ActiveSync.phpStatus,Response,Result, mail properties,Preview,HasAttachments,Range,Total)Range0-100to server maximum (100) instead of returning status 12Find support types
lib/Horde/ActiveSync/Find/Params.phplib/Horde/ActiveSync/Find/Results.phplib/Horde/ActiveSync/Find/QueryMapper.phplib/Horde/ActiveSync/Find/Kql.phpHorde_Imap_Client_Search_Query(incl.ORfor iOS patterns)IMAP search backend
Horde_ActiveSync_Imap_Adapter::_doQuery()for Find/Search-shared mailbox queries_getSubMailboxes()forDeepTraversal(search folder + subfolders)resolveLongIdForUid()— locatemailbox:uidwhen client uses a virtual folder idItemOperations (iOS follow-up)
When the user taps a Find result, iOS sends ItemOperations Fetch with a virtual All Mailboxes folder id (
M<uid>), which is not in the device folder cache.ItemOperations.phpnow falls back to UID-based long-id resolution instead of failing with “Folder not found in cache”.Driver interface
getFindResults()toHorde_ActiveSync_Driver_BaseHorde_ActiveSync_Driver_MockPreview encoding fix
Find result encoding reads body preview from stream resources via
_extractPreview()and requests a defaultpreview: 255bodypref when fetching hit metadata.Files in this PR
New
lib/Horde/ActiveSync/Request/Find.phplib/Horde/ActiveSync/Find/Params.phplib/Horde/ActiveSync/Find/Results.phplib/Horde/ActiveSync/Find/QueryMapper.phplib/Horde/ActiveSync/Find/Kql.phptest/Horde/ActiveSync/FindKqlTest.phptest/Horde/ActiveSync/FindQueryMapperTest.phpModified
lib/Horde/ActiveSync.phplib/Horde/ActiveSync/Wbxml.phplib/Horde/ActiveSync/Driver/Base.phplib/Horde/ActiveSync/Driver/Mock.phplib/Horde/ActiveSync/Imap/Adapter.phplib/Horde/ActiveSync/Request/Base.phplib/Horde/ActiveSync/Request/ItemOperations.phptest/Horde/ActiveSync/ServerTest.phpArchitecture
Test plan
horde/coreFind wiring deployed, test on EAS 16.0 client (iPhone):Preview,Range, andTotalin device logFollow-up
Requires a separate
horde/corePR addingHorde_Core_ActiveSync_Driver::getFindResults()andresolveLongIdForUid()delegation to the IMAP adapter. Without that PR, Find requests will fail at the driver layer.Author
Torben Dannhauer torben@dannhauer.de
requires horde/Core#137