[commits] [Wiki] created: ActiveSync/Development
Michael Rubinsky
mrubinsk at horde.org
Wed Nov 23 15:08:25 UTC 2016
mrubinsk Wed, 23 Nov 2016 15:08:25 +0000
Created page: https://wiki.horde.org/ActiveSync/Development
[[toc]]
+ ActiveSync Library Technical Information
This page is designed to give anyone working on the ActiveSync library
in Horde 5.x a general overview of logic flow and what happens where
and when.
++ General Library Structure
The logic for handling ActiveSync requests is split between 3
different libraries currently - //Horde_Rpc//, //Horde_Core//, and
obviously //Horde_ActiveSync//. Horde_Rpc only handles the initial
request and basically just passes on control to Horde_ActiveSync so
this page will focus only on the other two libraries.
+++ Horde_ActiveSync
This library contains the main logic for decoding WBXML from EAS
requests, passing the request to the appropriate controller and then
sending properly encoded responses back to the client.
++++ TODO general description of the classes
+++ Horde_Core
Core contains any code specific to handling Horde Groupware
collections. This is where requests for information and changes to
information are actually handled.
++++ Factories
: [[# activesyncserver Horde_Core_Factory_ActiveSyncServer]] : Creates
the main //Horde_ActiveSync// object. Injects the
//Horde_Core_ActiveSync_Driver//, the WBXML encoder/decoder objects,
the //Horde_ActiveSync_State_[Sql|Mongo]// storage object and the
//Horde_Controller_Request// object.
: Horde_Core_Factory_ActiveSyncState : Creates the state storage
handler. The name is misleading (and will change in Horde 6) as this
class has evolved to be more of a general storage handler and now
handles more than just device state. We will assume a Sql storage
backend for this document.
: Horde_Core_Factory_ActiveSyncBackend : Creates the
//Horde_Core_ActiveSync_Driver// backend driver. Injects
//Horde_Core_ActiveSync_Connector//, //Horde_ActiveSync_Imap_Adapter//
(if needed), the state storage driver, and the
//Horde_Core_ActiveSync_Auth// object.
++++ TODO ....
++ Protocol Overview
It's beyond the scope to explain the ActiveSync protocol in detail.
For that, there is the official
[https://msdn.microsoft.com/en-us/library/cc425499(v=exchg.80).aspx
documentation]. The most useful of these are
: MS-ASCMD : Details every command/request and it's schema.
: MS-ASHTTP : Documents the requirements and flow of the HTTP protocol
as used in the EAS protocol.
There are also the individual documents for each collection type, such
as //MS-ASEMAIL//, //MS-ASTASKS// etc... These documents are the best
place to start when trying to track down issues such as "Protocol
Error" issues with certain clients.
++ Logic Flow
I have a long-standing item on my todo list to generate an activity
diagram for the program flow of an EAS request, but in the meantime
here is a description of what happens.
EAS requests hit rpc.php first. There are a number of ways that these
are differentiated from other RPC requests, but the main give-away is
the REQUEST_URI containing //Microsoft-Server-ActiveSync//. A few
things happen here before continuing. First, EAS requests are
session-less, meaning that the entire Horde environment needs to be
setup for each request. This is handled by explicitly setting
$session_control = 'None' to force the use of the Null session driver
in Horde. From there, we perform the same logic and checks like every
other Horde RPC request. This includes having to initialize the Horde
environment with NO authentication.
From here, we instantiate a //Horde_Rpc_ActiveSync// object and
inject a //Horde_ActiveSync// object (which is created using
//Horde_Core_Factory_ActiveSyncServer//).
Here, we perform some sanity checking on the request and sniff out
what type of request we are handling. OPTIONS and Autodiscover
requests are handled a little differently, but for now we will
concentrate on the "normal" request handling.
The client must send certain data with each request. This data is
either present as "normal" GET variables or is sent as BASE64 encoded
binary data sent in QUERY_STRING (see
//**Horde_ActiveSync::getGetVars()**//). The format of this binary
data is beyond the scope of this page, but the data is decoded in
//**Horde_ActiveSync_Utils::decodeBase64()**//.
: Cmd : This is the command or request type. E.g., SYNC, PING, FOLDESYNC
: !DeviceId : This is a unique identifier for the client. This value
is only unique to the client, not to the account. I.e., the same
physical device/application will have the same !DeviceId. Multiple
users can be associated with the same !DeviceId.
Flow is turned over to //**Horde_ActiveSync::handleRequest()**//. This
is where the interesting stuff starts to happen.
++ Life Cycle of a Client.
What we will describe is the life cycle of a client-server pairing
from the initial connection to be able to synchronize changes. Let's
start with a fresh, never before connected client. The first thing
that happens is the OPTIONS request. This essentially tells the server
what protocol versions the client supports and the server responds
with (among other things) the version that it will be using.
More information about the commits
mailing list