You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2016/01/26 11:04:59 UTC

svn commit: r1726757 [4/4] - in /james/project/trunk/server/protocols/jmap/doc: ./ spec/

Added: james/project/trunk/server/protocols/jmap/doc/spec/thread.mdwn
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/doc/spec/thread.mdwn?rev=1726757&view=auto
==============================================================================
--- james/project/trunk/server/protocols/jmap/doc/spec/thread.mdwn (added)
+++ james/project/trunk/server/protocols/jmap/doc/spec/thread.mdwn Tue Jan 26 10:04:59 2016
@@ -0,0 +1,120 @@
+## Threads
+
+Replies are grouped together with the original message to form a thread. In JMAP, a thread is simply a flat list of messages, ordered by date. Every message MUST belong to a thread, even if it is the only message in the thread.
+
+The JMAP spec does not require the server to use any particular algorithm for determining whether two messages belong to the same thread, however there is a recommended algorithm in the [implementation guide](server.html).
+
+If messages are delivered out of order for some reason, a user may receive two messages in the same thread but without headers that associate them with each other. The arrival of a third message in the thread may provide the missing references to join them all together into a single thread. Since the `threadId` of a message is immutable, if the server wishes to merge the threads, it MUST handle this by deleting and reinserting (with a new message id) the messages that change threadId.
+
+A **Thread** object has the following properties:
+
+- **id**: `String`
+  The id of the thread. This property is immutable.
+- **messageIds**: `String[]`
+  The ids of the messages in the thread, sorted such that:
+  - Any message with `isDraft == true` and an *inReplyToMessageId* property that corresponds to another message in the thread comes immediately after that message in the sort order.
+  - Other than that, everything is sorted in date order (the same as the *date* property on the Message object), oldest first.
+
+### getThreads
+
+Threads can only be fetched explicitly by id. To fetch threads, make a call to *getThreads*. It takes the following arguments:
+
+- **accountId**: `String|null`
+  The id of the account to use for this call. If not given, defaults to the primary account.
+- **ids**: `String[]`
+  An array of ids for the threads to fetch.
+- **fetchMessages**: `Boolean|null`
+  If true, after outputting a *threads* response, an implicit call will be made to *getMessages* with a list of all message ids in the returned threads as the *ids* argument, and the *fetchMessageProperties* argument as the *properties* argument. If `false` or `null`, no implicit call will be made.
+- **fetchMessageProperties**: `String[]|null`
+  The list of properties to fetch on any fetched messages. See *getMessages* for a full description.
+
+The response to *getThreads* is called *threads*. It has the following arguments:
+
+- **accountId**: `String`
+  The id of the account used for the call.
+- **state**: `String`
+  A string encoding the current state on the server. This string will change
+  if any threads change (that is, new messages arrive, or messages are deleted, as these are the only two events that change thread membership). It can be passed to *getThreadUpdates* to efficiently get the list of changes from the previous state.
+- **list**: `Thread[]`
+  An array of Thread objects for the requested thread ids. This may not be in the same order as the ids were in the request.
+- **notFound**: `String[]|null`
+  An array of thread ids requested which could not be found, or `null` if all ids were found.
+
+The following errors may be returned instead of the `threads` response:
+
+`accountNotFound`: Returned if an *accountId* was explicitly included with the request, but it does not correspond to a valid account.
+
+`accountNoMail`: Returned if the *accountId* given corresponds to a valid account, but does not contain any mail data.
+
+`invalidArguments`: Returned if the request does not include one of the required arguments, or one of the arguments is of the wrong type, or otherwise invalid. A *description* property MAY be present on the response object to help debug with an explanation of what the problem was.
+
+Example of a successful request:
+
+    [ "getThreads", {
+      "ids": ["f123u4", "f41u44"],
+      "fetchMessages": false,
+      "fetchMessageProperties": null
+    }, "#1" ]
+
+and response:
+
+    [ "threads", {
+      "state": "f6a7e214",
+      "list": [
+        {
+          "id": "f123u4",
+          "messageIds": [ "eaa623", "f782cbb"]
+        },
+        {
+          "id": "f41u44",
+          "messageIds": [ "82cf7bb" ]
+        }
+      ],
+      "notFound": null
+    }, "#1" ]
+
+
+### getThreadUpdates
+
+When messages are created or deleted, new threads may be created, or the set of messages belonging to an existing thread may change. If a call to *getThreads* returns with a different *state* string in the response to a previous call, the state of the threads has changed on the server and the client needs to work out which part of its cache is now invalid.
+
+The *getThreadUpdates* call allows a client to efficiently update the state of any cached threads to match the new state on the server. It takes the following arguments:
+
+- **accountId**: `String|null`
+  The id of the account to use for this call. If not given, defaults to the primary account.
+- **sinceState**: `String`
+  The current state of the client. This is the string that was returned as the *state* argument in the *threads* response. The server will return the changes made since this state.
+- **maxChanges**: `Number|null`
+  The maximum number of Thread ids to return in the response. The server MAY choose to clamp this value to a particular maximum or set a maximum if none is given by the client. If supplied by the client, the value MUST be a positive integer greater than 0. If a value outside of this range is given, the server MUST reject the call with an `invalidArguments` error.
+- **fetchRecords**: `Boolean|null`
+  If `true`, after outputting a *threadUpdates* response, an implicit call will be made to *getThreads* with the *changed* property of the response as the *ids* argument, and *fetchMessages* equal to `false`.
+
+The response to *getThreadUpdates* is called *threadUpdates*. It has the following arguments:
+
+- **accountId**: `String`
+  The id of the account used for the call.
+- **oldState**: `String`
+  This is the *sinceState* argument echoed back; the state from which the server is returning changes.
+- **newState**: `String`
+  This is the state the client will be in after applying the set of changes to the old state.
+- **hasMoreUpdates**: `Boolean`
+  If `true`, the client may call *getThreadUpdates* again with the *newState* returned to get further updates. If `false`, *newState* is the current server state.
+- **changed**: `String[]`
+  An array of thread ids where the list of messages within the thread has
+  changed between the old state and the new state, and the thread currently has at least one message in it.
+- **removed**: `String[]`
+  An array of thread ids where the list of messages within the thread has changed since the old state, and there are now no messages in the thread.
+
+If a *maxChanges* is supplied, or set automatically by the server, the server must try to limit the number of ids across *changed* and *removed* to the number given. If there are more changes than this between the client's state and the current server state, the update returned MUST take the client to an intermediate state, from which the client can continue to call *getThreadUpdates* until it is fully up to date. The server MAY return more ids than the *maxChanges* total if this is required for it to be able to produce an update to an intermediate state, but it SHOULD try to keep it close to the maximum requested.
+
+If a thread has been modified AND deleted since the oldState, the server SHOULD just return the id in the *removed* response, but MAY return it in the changed response as well. If a thread has been created AND deleted since the oldState, the server should remove the thread id from the response entirely, but MAY include it in the *removed* response, and optionally the *changed* response as well.
+
+The following errors may be returned instead of the *threadUpdates* response:
+
+`accountNotFound`: Returned if an *accountId* was explicitly included with the request, but it does not correspond to a valid account.
+
+`accountNoMail`: Returned if the *accountId* given corresponds to a valid account, but does not contain any mail data.
+
+`invalidArguments`: Returned if the request does not include one of the required arguments, or one of the arguments is of the wrong type, or otherwise invalid. A *description* property MAY be present on the response object to help debug with an explanation of what the problem was.
+
+`cannotCalculateChanges`: Returned if the server cannot calculate the changes from the state string given by the client. Usually due to the client's state being too old, or the server being unable to produce an update to an intermediate state when there are too many updates. The client MUST invalidate its Thread cache. The error object MUST also include a `newState: String` property with the current state for the type.

Added: james/project/trunk/server/protocols/jmap/doc/spec/upload.mdwn
URL: http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/doc/spec/upload.mdwn?rev=1726757&view=auto
==============================================================================
--- james/project/trunk/server/protocols/jmap/doc/spec/upload.mdwn (added)
+++ james/project/trunk/server/protocols/jmap/doc/spec/upload.mdwn Tue Jan 26 10:04:59 2016
@@ -0,0 +1,50 @@
+## File Uploads
+
+There is a single endpoint which handles all file uploads, regardless of what they are to be used for. To upload a file, submit a POST request to the file upload endpoint (see the authentication section for information on how to obtain this URL). The Content-Type MUST be correctly set for the type of the file being uploaded. The request MUST be authenticated as per any HTTP request. The request MAY include an "X-JMAP-AccountId" header, with the value being the account to use for the request. Otherwise, the default account will be used.
+
+The server will respond with one of the following HTTP response codes:
+
+#### `201`: File uploaded successfully
+
+The content of the response is a single JSON object with the following properties:
+
+- **accountId**: `String`
+  The id of the account used for the call.
+- **blobId**: `String`,
+  The id representing the binary data uploaded. The data for this id is immutable. The id *only* refers to the binary data, not any metadata.
+- **type**: `String`
+  The content type of the file.
+- **size**: `Number`
+  The size of the file in bytes.
+- **expires**: `Date`
+  The date the file will be deleted from temp storage if not referenced by another object, e.g. used in a draft.
+
+Once the file has been used, for example attached to a draft message, the file will no longer expire, and is instead guaranteed to exist while at least one other object references it. Once no other object references it, the server MAY immediately delete the file at any time. It MUST NOT delete the file during the method call which removed the last reference, so that if there is a create and a delete within the same call which both reference the file, this always works.
+
+If uploading a file would take the user over quota, the server SHOULD delete previously uploaded (but unused) files before their expiry time. This means a client does not have to explicitly delete unused temporary files (indeed, there is no way for it to do so).
+
+If identical binary content is uploaded, the same *blobId* SHOULD be returned.
+
+#### `400`: Bad request
+
+The request was malformed (this includes the case where an `X-JMAP-AccountId` header is sent with a value that does not exist). The client SHOULD NOT retry the same request.
+
+#### `401`: Unauthorized
+
+The `Authorization` header was missing or did not contain a valid token. Reauthenticate and then retry the request. There is no content in the response.
+
+#### `404`: Not Found
+
+The upload endpoint has moved. See the Authentication section of the spec for how to rediscover the current URL to use. There is no content in the response.
+
+#### `413`:  Request Entity Too Large
+
+The file is larger than the maximum size the server is willing to accept for a single file. The client SHOULD NOT retry uploading the same file. There is no content in the response. The client may discover the maximum size the server is prepared to accept by inspecting the capabilities property of the Account object.
+
+#### `415`: Unsupported Media Type
+
+The server MAY choose to not allow certain content types to be uploaded, such as executable files. This error response is returned if an unacceptable type is uploaded. The client SHOULD NOT retry uploading the same file. There is no content in the response.
+
+#### `503`: Service Unavailable
+
+The server is currently down. The client should try again later with exponential backoff. There is no content in the response.



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org