Communication Protocol
This page is a complete specification of client-server communications in the DataNav portal web application. It describes how the DataNav client-side apps -- DataNav Builder and DataNav Viewer -- send requests to DataNav Server over the HTTPS and HTTP protocols and defines the required format for the payload of each request and its commensurate response. With near code-level details, it is intended only for a developer audience. Portal authors and administrators can skip this entirely!
Access to the portal comes in two flavors: anonymous read-only access over HTTP, or authenticated read-write access secured over HTTPS. In both cases, the MIME content type is JavaScript Object Notation, or JSON (application/json). Builder supports both types of client-server communications, so you can explore a portal anonymously if you wish, or log into any portal on which you are a registered user. DataNav Viewer, as the name implies, offers only anonymous read access to the portal.
Regardless the type of request, the request and response payload are each packaged as a single JSON object. All request payloads include the req field, which holds the request ID as a 32-bit integer. Furthermore, any request requiring authenticated access includes the handle field, a positive 32-bit integer user handle which was assigned to the client at logon. The remaining payload content is request-specific and is detailed in the individual request-response descriptions below; request ID codes are listed in parentheses.
A normal response will include, at a minimum, a req field reflecting the original request ID and a result field set to the integer result code. In addition, any request that retrieves or modifies portal content will include a mod field specifying the 32-bit integer modification stamp for the portal's hub vault. Any time a change is made to portal content, this modification stamp is incremented. It provides a mechanism by which the client can detect whenever a change in the portal's content has occurred, rendering the client's cached content stale.
Additional fields in the response object vary with the request type and are again described in the comments for each request type. A failed response will have three or four fields: req, result, emsg, and mod. The result field holds an integer result code other than 1 ("ok"), and emsg is a string describing why the request failed. The mod field is included only in content-related requests; if the response failed due to a timeout or a connection failure, this field is set to -1 and should be ignored.
Regardless the level of access, all client-server communications follow the usual request-response paradigm. The client app sends a payload as an HTTP or HTTPS POST request to DataNav Server, which parses the request payload, retrieves and/or modifies content in the portal's backing store as needed, then prepares and returns a response. The remainder of this page explains the purpose of each type of client request recognized by Server, along with the format of the request payload and the expected server response.
Client requests targeting the portal's registered users list
All client requests described in this section require authenticated access to the portal; they are sent over HTTPS and are issued by the DataNav Builder client only. Selected requests require administrative-level access.
LOGIN (request code = 100): Request to log onto portal.
Request payload: {req: int32, user: string}. The plain-text string in the user field holds the user's login credentials separated by a colon -- "username:password". Keep in mind that this information is already sent over an encrypted HTTPS connection, so there's no need to encrypt this string.
Response payload: {req: int32, result: int32, handle: int32, role: string}. The client must cache the supplied user handle, since it is required in all further requests to the portal until it logs out. The handle returned will not necessarily be the same each time the user logs in. The role field is set to "1" if the authenticated user has administrator-level access; if "0", the user has the more restrictive author-level access. DataNav Builder uses this flag to enable/disable user account administration commands, which are only available to a portal administrator.
An author must log onto the portal before s/he can mount or unmount an archive, toggle the archive's public/private flag, checkout an archive for revision, etcetera. An administrator must login to make any changes to the portal's registered users list. This request is sent to initiate a log-in "session". DataNav Server keeps track of the user handles for all log-in sessions; any HTTPS client request (other than the LOGIN request) lacking an active user handle will be rejected.
LOGOUT (101): Request to log out of portal.
Request payload: {req: int32, handle: int32}.
Response payload: {req: int32, result: int32}.
There is no additional request or response payload. Of course, the user handle in the request payload must identify a user that is currently logged onto the portal.
GETUSERS (102): Get the list of all registered portal users
Request payload: {req: int32, handle: int32}.
Response payload: {req: int32, result: int32, users: ["user1", "user2", ...]}. Each element in the JSON array users is a string of the form "username:role:loggedIn:name:title:phone:email", listing the login username, access level ("0" for author, "1" for admin), current login state ("0" if not logged in, else "1") for a registered portal user, along with optional contact information -- full name, job title, phone number, and an email address. Any or all of the last four fields could contain only a single dash ("-"), indicating that they are unspecified.
DataNav Builder issues this request after a user logs onto a portal and parses the response payload to populate its summary of registered portal users. Users can check this list to see if another author is currently logged into the portal. An administrator will consult it when adding or removing users, or changing a user's access level.
ADDUSER (103): Add a registered user to the portal.
Request payload: {req: int32, handle: int32, user: "name:pwd:role"}. The user field holds a plain-text string listing the username, password, and access level ("0" for author, "1" for administrator) for the new user, separated by colons. The username must be composed of 3-20 lowercase letters only. The password must have 6-20 characters, and may contain any visible ASCII character except the colon.
Response payload: {req: int32, result: int32}.
This request will fail if the new user's name is already taken, or if the supplied request data is invalid. It will also fail if the user issuing the request lacks administrator-level access. Only a portal administrator can add a new user to the portal.
RMVUSER (104): Remove a registered user from the online portal.
Request payload: {req: int32, handle: int32, user: "name"}.
Response payload: {req: int32, result: int32}.
Only a portal administrator can remove a registered user from the portal. If that user is logged in at the time of removal, s/he is automatically logged out by DataNav Server -- so the next client request from that user will be rejected. Any portal archive that was owned by the removed user is automatically transferred to an archive collaborator or, if the archive's collaborator list is empty, to the administrator that issued this request.
ROLEUSER (105): Change the access level of an existing registered user.
Request payload: {req: int32, handle: int32, user: "name:role"}. The user field is a plain-text string with colon-separated tokens specifying the name of the user and his new access level: "0" for author and "1" for administrator. Note that an administrator cannot change his own access level.
Response payload: {req: int32, result: int32}.
The request will fail if the issuer lacks administrative-level privileges on the portal, or if the request data is invalid.
PWDUSER (106): Change the password of the requesting user.
Request payload: {req: int32, handle: int32, pwd: "pwdOld:pwdNew"}. A The pwd field is a plain-text string with colon-separated tokens specifying the current and new password for the registered user issuing this request. Again, the new password must have 6-20 visible ASCII characters, except the colon.
Response payload: {req: int32, result: int32}.
INFOUSER (107): Change the optional contact information of the requesting user.
Request payload: {req: int32, handle: int32, user: "name:title:phone:email"}. The user field is a plain-text string with colon-separated tokens specifying optional contact information for the registered user issuing this request -- full name, job title, phone number, and an email address. No token may contain a colon, of course; and any exceeding 50 characters in length will be truncated by the server upon processing the request. No token will be empty, but a single dash ("-") character indicates that contact field is unspecified.
Response payload: {req: int32, result: int32}.
Client requests that retrieve portal content
All client requests described in this section may be sent anonymously over HTTP or while logged in via HTTPS. These are the only requests issued by the DataNav Viewer client. When sent over HTTPS (DataNav Builder only), each request must include a valid user login handle in the handle field. When sent over HTTP (by Viewer or Builder), the handle field is still present but is set to -1 and is ignored by DataNav Server.
CHECKVER (10): Check client-server version compatibility.
Request payload: {req: int32, version: int32}. The version field holds the communication protocol version number on client.
Response payload: {req: int32, result: int32}.
This request is issued anonymously over HTTP by both the Viewer and Builder clients prior to attempting any other communication exchanges with DataNav Server. It is sent simply to verify that the client and server are both using the same version of the communication protocol. If your version of Builder is incompatible with the portal's current Server installation, then this request will fail with a result code of -13. Since Viewer is a Javascript-based web app that is downloaded from the portal server in the first place, it should always be compatible with the server (however, if your browser caches JS files, you might see a compatibility error). The current version number for the DataNav client-server communication protocol is 4 (as of app version 4.6.0).
GETVAULT (request code = 200): Get the portal's archive vault structure -- a skeletal summary of portal content that
includes everything a client needs in order to retrieve that content and present it to the end user.
Request payload: {req: int32, handle: int32}.
Response payload: {req: int32, result: int32, mod: int32, archives: [arch1, arch2, ..., archN]}.
The archives field in the response is a JSON array of length N, where N is the number of accessible archives in the portal. Each element, in turn, is a JSON object encapsulating a single archive's structural outline. For a figure archive, the object contains the following fields:
"uid" : The archive's unique integer identifier, or UID (a 32-bit integer).
"fuids": The UIDs of the archived figures, in order of appearance (a JSON array of 32-bit integers).
"meta" : A mixed JSON array of 3-7 elements, [stamp, lastMod, mount (, pub, users, coTime, coHolder)], where the 32-bit integer stamp is the archive's current modification stamp (incremented each time the archive is revised by the check-out and check-in process); lastMod and mount are system times (in milliseconds since midnight GMT, 1/1/1970) when the archive was last modified and when it was originally mounted on the portal, respectively (64-bit integers); pub is non-zero if the archive is public and 0 if private (32-bit integer); users is a JSON array of strings listing login names of the archive's designated owner (the first element) and any collaborators granted write access to the archive (this array cannot be empty, since every archive has an owner); coTime is the system time when the archive was checked out for revisions (64-bit integer); and coHolder is the login name of the user that has checked out the archive (string).
When the GETVAULT request is sent anonymously, the "meta" field contains only the first three elements. When sent by an authenticated client over HTTPS, it will contain the first 5 elements unless the archive is currently checked out of the portal for revision, in which case all 7 elements are present.
For a data archive ("hub"), the JSON object instead contains these fields:
"uid" : The archive's UID (a 32-bit integer).
"evuid" : The UID of the hub's entry-point navigation view (32-bit integer; will be 0 if hub is empty).
"vuids": The UIDs of the hub's navigation views, in no particular order (JSON array of 32-bit integers).
"links": A JSON array of 2N 32-bit integers [src1, dst1, ..., srcN, dstN] listing the N view links that comprise the hub's "navigation map". Here each pair (srcN, dstN) are the UIDs of the source view and destination view for one link. Of course, if the hub is empty, both this field and "vuids" will be empty JSON arrays.
"meta": Same as for a figure archive.
Note that, when the GETVAULT request is sent by an anonymous client, then the response will only include those archives in the portal's vault that are marked as public -- an anonymous client does not have access to private archives.
GETARCHINFO (201): Get textual summary information for a specified archive in the portal.
Request payload: {req: int32, handle: int32, uid: int32}. The uid field holds the UID of the archive requested.
Response payload: {req: int32, result: int32, mod: int32, title: string, authors: string, desc: string}. The authors field is a comma-delimited list of author names, while desc is the archive's HTML-formatted description.
GETVIEWDEF (202): Retrieve the definition of a navigation view for a specified data hub in the portal.
Request payload: {req: int32, handle: int32, uid: int32, vuid: int32}. The uid and vuid fields hold the unique integers (UIDs) identifying the data hub and one of its navigation views, respectively.
Response payload: {req: int32, result: int32, mod: int32, title: string, desc: string, groups: JSONArray, fyp: JSONObject}.
The title and desc fields in the response hold the navigation view's title and HTML-formatted description, respectively. The fyp field is a JSON-formatted version of the FypML markup defining the view's template figure; it conforms to the latest schema for DataNav figures. Sending the template in JSON format makes parsing easier in the Javascript-based DataNav Viewer client.
The groups field is a JSON array of 0-4 JSON objects representing the view's instance configuration groups. Each such object has the following format: {name: string, blk: int32, attrs: JSONArray, ph: JSONArray}. The name field is the configuration group's reader-facing name, blk is its iteration block size, and attrs is an array of 1-6 strings listing the group's "attributes" or "search tags". The ph field is a mixed JSON array [id1, fmt1, iter1, ... idN, fmtN, iterN] containing the triplet (id, fmt, iter) for each template placeholder set assigned to the configuration group. Here id is the placeholder set's ID within the view template (a string), fmt is the data set format code (int32), and iter is an integer flag indicating whether or not data injected into the placeholder participates in an iteration over collection-type data (non-zero == iterable).
GETVIEWINSTANCES (203): Retrieve the entire instance list for a navigation view within a specified data hub.
Request payload: {req: int32, handle: int32, uid: int32, vuid: int32}.
Response payload: {req: int32, result: int32, mod: int32, instances: JSONArray of JSONArrays}.
Each entry in the instances array in a mixed-content JSON array defining a single view instance [g, M, P, av1, ..., avM, duid1, ..., duidP], where:
g = the index (zero-based) of the configuration group to which the instance belongs.
M = the number of attributes for that group.
P = the number of placeholder sets for that group.
av1 ... avM = the search attribute values that uniquely label the instance.
duid1, ..., duidP = the 32-bit integer UIDs of the data sets that are injected into the view template for the group's placeholder sets to "render" the view instance.
GETDATASETS (204): Retrieve one or more data sets from a portal hub's internal data repository.
Request payload: {req: int32, handle: int32, uid: int32, duids: [duid1, duid2, ... duidN]}. The duids field is a JSON array listing the UIDs of the hub data sets to be retrieved.
Response payload: {req: int32, result: int32, mod: int32, datasets: [duid1, ds1, ..., duidM, dsM]}.
For each data set successfully retrieved, the mixed-content JSON array in the datasets field contains the UID of the data set (int32), followed by the data set itself packaged as a base64-encoded binary string. Data sets are cached on the client side to the extent possible to minimize the number of client-server exchanges when a user is browsing hub data. Coordinate range information is included in the base64 string so that, when large data sets are decoded on the client side, it is not necessary to traverse the data to recompute that information.
The order of datasets retrieved may NOT match the order of the UIDs in the request field duids. That is why the UID of each retrieved set is included in the response. Also, if the download size is too large, DataNav Server will send back only 1 <= M < N data sets. In this case, the client must issue an additional GETDATASETS request for the remaining sets.
GETARCHFIG (205): Retrieve a member figure from the specified figure archive in the portal.
Request payload: {req: int32, handle: int32, uid: int32, vuid: int32}. The uid and vuid fields hold the unique integers (UIDs) identifying the figure archived and the requested figure, respectively.
Response payload: {req: int32, result: int32, mod: int32, title: string, desc: string, fyp: JSONObject}.
The title and desc fields in the response hold the archived figure's title and HTML-formatted description, respectively. Together, these serve as a legend when the figure is presented in the client's user interface. The fyp field is a JSON-formatted version of the FypML markup defining the requested figure; again, it conforms to the latest schema for DataNav figures.
Client requests that modify, upload, or download portal content
All client requests described in this section require authenticated access to the portal; they are sent over HTTPS and are issued by the DataNav Builder client only. These constitute the only means by which a portal's content can be changed.
SETARCHPUB (request code = 206): Change the public/private flag for an existing archive in the portal.
Request payload: {req: int32, handle: int32}, uid: int32, pub: int32}. The uid field identifies the archive, while the pub field is non-zero (zero) if the archive should be marked as public (private).
Response payload: {req: int32, result: int32, mod: int32, oldMod: int32}.
This request will fail if the requesting user (identified by the login handle in the request payload) is not the designated owner of the specified archive.
The portal vault modification stamps both before and after the change (oldmod and mod, respectively) are included in the response so that the client that requested the change will be able to determine if any other portal update occurred after the request was issued but before it was actually executed on the server. The client compares the "before" stamp with its cached copy; if they are not the same, then some other change has occurred.
CHECKOUTARCH (request code = 207): Checkout an existing portal archive in order to make revisions to it.
Request payload: {req: int32, handle: int32}, uid: int32}. The uid field identifies the archive to be checked out
Response payload: {req: int32, result: int32, mod: int32, time: int64}. The time field is the approximate system time when the archive was checked out (in milliseconds since midnight GMT, 1/1/1970).
The requesting user must be the archive owner or one of its designated collaborators. If the request succeeds, the user gets a checkout lock on the archive; no one else can checkout the archive until that user checks in the revisions. The portal server makes a private copy of the archive, and all revisions are applied to that copy. The requesting user "sees" and edits the copy, while everyone else sees the current "live" version -- that is, the archive state prior to checkout. On check-in, the updated copy replaces the current version, and the checkout lock is released.
The client must check the vault modification stamp in the server's response against its cached copy to see if the portal's content has changed since the client issued the checkout request. If they don't match, the client must refresh its cached content. Otherwise, the client should mark the subject archive as checked out by the logged-in user that sent this request and cache the checkout time included in the response.
CHECKINARCH (request code = 208): Check in an existing portal archive that was previously checked out for revision. The private internal copy to which all revisions were applied replaces the current "live" version of the archive, and the checkout lock on the archive is released.
Request payload: {req: int32, handle: int32}, uid: int32, discard: int32}. The uid field identifies the archive to be checked in. If the discard field is non-zero, then the revisions are discarded and the "live" version of the archive is left unchanged.
Response payload: {req: int32, result: int32, mod: int32, oldMod: int32, outline: JSONObject}. The outline field contains the structural outline for the just checked-in archive. The content of this object depends on the archive type; for a full description, see the summary of the GETVAULT request.
The server will deny the request if the requesting user (as identified by the handle field) does not hold the checkout lock on the specified archive. As with SETARCHPUB, the portal vault modification stamps both before and after the check-in request was completed on the server (oldmod and mod, respectively) are included in the response so that the client that issued the request will be able to determine if any other portal update occurred while waiting for the server to respond.
EDITARCH (request code = 209): Submit a revision to an existing portal archive that is currently checked out by the requesting user.
Request payload: {req: int32, handle: int32}, edit: JSONObject}. The edit field is a JSON object that indicates what kind of edit to perform; it includes all of the content needed to make the requested change. The exact format of this object is beyond the scope of this online guide; contact the developer if you are interested in the nitty-gritty details.
Response payload: {req: int32, result: int32, mod: int32, retval: various}. The retval field contains a value returned by the server for certain archive revisions. When a figure is added to a figure archive or a navigation view is added to a data hub, this field contains the 32-bit integer ID assigned to the new figure or view. When a view is removed from a data hub, it is the UID of the hub's entry-point view after the removal; if the entry-point view itself was removed, the server must designate a different entry-point, so this ensures the client is informed of the change. Finally, when a data instance is added to a hub navigation view, retval is a JSON array defining the new view instance, formatted in the same manner as each instance returned in the response to the GETVIEWINSTANCES request. For all other archive revisions, retval is set to -1 (32-bit int) and has no meaning.
The server will deny the request if the requesting user (as identified by the handle field) does not hold the checkout lock on the specified archive. Also note that this request, if successfully fulfilled by the server, does NOT actually change the portal's content (its modification stamp is unchanged). This is because all revisions are applied to a private internal copy of the checked-out archive, which is accessible only to the user holding the checkout lock. The archive is updated -- and the portal's modification stamp incremented -- only when the revisions are checked back into the portal.
[NOTE: An archive revision which adds a data instance to a hub navigation view may be split over a sequence of consecutive EDITARCH client requests if the size of the data comprising the instance exceeds a certain "payload size threshold". In this scenario, the retval field is -1 for each successful request-response exchange except the last, which will hold the view instance just added to the private copy of the data hub on the portal. If any request-response exchange in the sequence fails, the client can assume the instance was NOT added to the hub; if the portal has not crashed, the client will have to re-send the entire sequence to try again.]
ARCHMETA (request code = 210): Get current meta-data for portal archives, or change an archive's owner or collaborator list.
Request payload: {req: int32, handle: int32}, type: int32, uid: int32, user: string}. The type field is an integer indicating the operation type: 0 = retrieve current meta-data for all portal archives; 1 = transfer ownership of the archive identified by the uid field to the user whose login name is in the user field; 2 = add the specified user as a collaborator on the archive identified by uid; and 3 = remove the specified user as a collaborator on the archive identified by uid. Note that the uid and user fields are ignored when type = 0.
Response payload: {req: int32, result: int32, mod: int32, archives: JSON array}. The archives array lists the current meta-data for all archives currently mounted on the portal. Each element in the array is a JSON object containing the meta-data for a portal archive. Each JSON object has two fields: uid is the archive UID (32-bit int), and meta is a JSON array listing the archive's current meta-data, in the same manner as it appears in the archive outlines returned by the GETVAULT request.
Only an archive owner may transfer ownership to another user or add/remove archive collaborators. Thus, the server will deny the request if type > 0 and the requesting user (as identified by the handle field) is not the owner of the subject archive.
XFER_BEGIN (220): Begin a multi-request sequence that will transfer an entire archive (either data or figure archive) from the client to the remote portal or vice versa.
Since a typical archive (especially a data hub) will be quite large, it will take a relatively long time and many request-response exchanges to transfer an entire archive to or from a remote portal. There are two use cases involving an archive transfer:
Mount an archive. The Builder client first cleans and compacts the local archive's backing store to minimize its size, then compresses all files in the backing store into a single ZIP file. Next, it issues this request to initiate the mount sequence, followed by many XFER_CHUNK requests that upload the ZIP file to the remote portal server. After the last chunk is delivered, the client issues a XFER_FINISH request to add the uploaded archive to the portal's archive vault. The server decompresses the ZIP file, reconstituting the archive backing store within its own archive vault. The archive is loaded from the backing store to verify its integrity and then mounted on the portal. The logged-in user that issued the mount request becomes the designated owner of the portal archive, which is initially marked as private. After the archive is successfully mounted on the portal, the Builder client will remove the archive from its local workspace vault.
Unmount an archive. The client issues the XFER_BEGIN request to initiate the archive unmount procedure. Prior to responding, the server cleans and compacts the requested archive's backing store to minimize its size, then compresses all files in the backing store into a single ZIP file. It then assigns a unique ID to the archive transfer job and responds with that ID. The client then starts "pulling" the ZIP file from the portal one chunk at a time via a sequence of XFER_CHUNK requests. The server will set the "done" flag in the response that includes the last file chunk. Upon receiving that final chunk, the Builder client decompresses the ZIP file, reconstituting the archive's backing store. The archive is loaded from the backing store to verify its integrity and then integrated into the client's local workspace vault. If the download completes successfully, the client sends the XFER_FINISH request. At this point, with the unmounted archive safely returned to the client's local workspace, the server permanently removes it from the portal's archive vault.
If a problem occurs on the client side during either of these archive transfer operations, or if the user elects to cancel a transfer in progress, the client issues the XFER_CANCEL request to inform the portal server.
Request payload: {req: int32, handle: int32, xfer: int32, size: int64, uid: int32}. The xfer field indicates the type of archive transfer operation being initiated (0 = mount, 1 = unmount). The size field indicates the size of the ZIP file to be uploaded, in bytes; it is ignored for an unmount operation. The uid field is the UID of the target archive to be unmounted from the portal; for a mount operation, the field is ignored.
Response payload: {req: int32, result: int32, job: int32, size: int64}. The job field is the archive transfer job ID, assigned by DataNav Server. It must be included in all requests that are part of the multi-step archive transfer. The size field is the size of the ZIP file to be downloaded during an unmount operation; for a mount transfer, size = 0.
XFER_CHUNK (221): Transfer a file chunk from the ZIP file containing the backing store files for the archive that is currently being transferred to or from the remote portal.
Request payload: {req: int32, handle: int32, job: int32, chunk: string}. The job field is the archive transfer job ID that was assigned by the portal server in response to the initial XFER_BEGIN request. The chunk field contains the actual file chunk being uploaded to the server, a byte array in the form of a base64-encoded string. Obviously, this field does not apply for archive downloads, in which case it is set to an empty string.
Response payload: {req: int32, result: int32, chunk: string, done: int32}. The chunk field contains the file chunk being downloaded to the client (byte array as a base64-encoded string), and the done field is non-zero if this is the last file chunk. Neither field applies during an archive upload, in which case chunk = "" and done = 0.
Regardless the direction, the Builder client controls the progress of the archive transfer, "pushing" content to the portal or pulling content from it. Obviously, the chunks are streamed sequentially. If any chunk transfer request fails, then the transfer operation is automatically aborted on both the server and client sides.
XFER_CANCEL (222): Cancel an archive transfer operation in progress.
Request payload: {req: int32, handle: int32, job: int32}.
Response payload: {req: int32, result: int32}.
This request may be sent at any point after XFER_BEGIN, but before XFER_FINISH. If an archive mount or unmount operation is cancelled, there's no change to the portal.
XFER_FINISH (223): Complete an archive transfer operation in progress. The portal server's response depends on the type of transfer operation; see the description of the XFER_BEGIN request for details.
Request payload: {req: int32, handle: int32, job: int32}.
Response payload: {req: int32, result: int32, mod: int32, oldMod: int32, outline: JSONArray}. The oldMod and mod fields give the value of the portal vault's modification stamp immediately before and after the server updates the vault (mounting the new archive or removing the unmounted archive). The outline field is a JSON object encapsulating the structural outline for the newly mounted archive; it is the same information returned for each archive in the response to the GETVAULT request. For an unmount operation, the field is set to an empty JSON object and is ignored by the client.
NOTE that this is the only request in the archive transfer sequence that actually alters the persisted content of the portal. As with SETARCHPUB, the portal vault modification stamps both before and after the transfer operation was completed on the server (oldmod and mod, respectively) are included in the response so that the client that performed the transfer will be able to determine if any other portal update occurred during the transfer. This could easily happen, since archive transfers can take a significant amount of time to complete.
Server response result codes
Listed below are the various 32-bit integer result codes that may be sent in DataNav Server's response (the result field of the JSON response object) to a client request.
1 = "OK". The server successfully fulfilled the client request.
0 = "Not OK". The client request was not fulfilled. The remainder of the response payload is an ASCII character string describing the reason for the failure. Result codes less than this value are specific failure codes that may trigger a particular action on the client side.
-1 = "Access denied". The server could not honor the client request because the user lacks the required access privileges. This can happen if an unauthenticated user sends a request that requires authentication, an author-level user sends a request requiring administrator-level access, or if someone other than an archive's owner attempts to remove that archive.
-3 = "Request denied". The server refused to execute the client request because the request payload was invalid or the requested operation was not allowed.
-4 = "Out of sync". The server refused to execute the client request because the request data indicated that the client's cache of portal content was out-of-sync with the current state of the portal on the server side. For example, this will be issued on any archive request in which an identified archive is not found on the server side. In this case, the client should issue the necessary request(s) to refresh its cached portal content.
-5 = "Timed out". The server failed to respond within an allotted time, probably because it was too busy handling requests from other clients.
-6 = "Already checked out". The server denied an archive check-out request because the specified archive is already checked out for revisions by another portal user. The client should issue the necessary requests to refresh its cached portal content.
-10 = "No login" (applicable only to requests requiring authenticated access to the portal). The server could not process client request because it contained a stale user handle. This can happen if a user is removed by the portal administrator while logged in, or if the portal server "boots" the user out because of inactivity. Clients should reset their server connection and try to log-in again upon receiving this result code.
-11 = "Unavailable". The server could not process a client request because it has been disabled by a catastrophic failure in the portal's backing store. Once disabled, the server will simply return this result code in response to all requests it receives. Restoring normal server operation requires manual intervention by a portal administrator. Clients should reset their server connection upon receiving this result code.
-12 = "Communication link failed". This failure code is set on the client side if the HTTP response status code is anything other than 200, or if an IO error occurs while sending the request payload or receiving the response payload. Typically it means that the network is down, or the web server hosting the portal is down.
-13 = "Client and server incompatible". This failure code is sent in response to the CHECKVER request if the client's communication protocol version number does not match that on the server side. This could happen if an older version of the client attempts to connect to a newer version of the server.