Merge branch 'master' into module-im

This commit is contained in:
Kegan Dougal 2015-10-05 10:16:44 +01:00
commit 47cf958b54
18 changed files with 473 additions and 192 deletions

View file

@ -3,44 +3,31 @@ Content repository
.. _module:content:
HTTP API
--------
This module allows users to upload content to their homeserver which is
retrievable from other homeservers. Its' purpose is to allow users to share
attachments in a room. Content locations are represented as Matrix Content (MXC)
URIs. They look like::
Uploads are POSTed to a resource which returns a token which is used to GET
the download. Uploads are POSTed to the sender's local homeserver, but are
downloaded from the recipient's local homeserver, which must thus first transfer
the content from the origin homeserver using the same API (unless the origin
and destination homeservers are the same). The upload/download API is::
mxc://<server-name>/<media-id>
=> POST /_matrix/media/v1/upload HTTP/1.1
Content-Type: <media-type>
<server-name> : The name of the homeserver where this content originated, e.g. matrix.org
<media-id> : An opaque ID which identifies the content.
<media>
Uploads are POSTed to a resource on the user's local homeserver which returns a
token which is used to GET the download. Content is downloaded from the
recipient's local homeserver, which must first transfer the content from the
origin homeserver using the same API (unless the origin and destination
homeservers are the same).
<= HTTP/1.1 200 OK
Content-Type: application/json
Client behaviour
----------------
{ "content-uri": "mxc://<server-name>/<media-id>" }
Clients can upload and download content using the following HTTP APIs.
=> GET /_matrix/media/v1/download/<server-name>/<media-id> HTTP/1.1
<= HTTP/1.1 200 OK
Content-Type: <media-type>
Content-Disposition: attachment;filename=<upload-filename>
<media>
Clients can get thumbnails by supplying a desired width and height and
thumbnailing method::
=> GET /_matrix/media/v1/thumbnail/<server_name>
/<media-id>?width=<w>&height=<h>&method=<m> HTTP/1.1
<= HTTP/1.1 200 OK
Content-Type: image/jpeg or image/png
<thumbnail>
{{content_repo_http_api}}
Thumbnails
~~~~~~~~~~
The thumbnail methods are "crop" and "scale". "scale" tries to return an
image where either the width or the height is smaller than the requested
size. The client should then scale and letterbox the image if it needs to
@ -49,6 +36,9 @@ width and height are close to the requested size and the aspect matches
the requested size. The client should scale the image if it needs to fit
within a given rectangle.
Server behaviour
----------------
Homeservers may generate thumbnails for content uploaded to remote
homeservers themselves or may rely on the remote homeserver to thumbnail
the content. Homeservers may return thumbnails of a different size to that
@ -58,13 +48,19 @@ Homeservers must never upscale images.
Security considerations
-----------------------
The HTTP GET endpoint does not require any authentication. Knowing the URL of
the content is sufficient to retrieve the content, even if the entity isn't in
the room.
Homeservers have additional concerns:
- Clients may try to upload very large files. Homeservers should not store files
that are too large and should not serve them to clients.
- Clients may try to upload very large images. Homeservers should not attempt to
generate thumbnails for images that are too large.
- Remote homeservers may host very large files or images. Homeserver should not
- Remote homeservers may host very large files or images. Homeservers should not
proxy or thumbnail large files or images from remote homeservers.
- Clients may try to upload a large number of files. Homeservers should limit the

View file

@ -2,64 +2,111 @@ Presence
========
.. _module:presence:
Each user has the concept of presence information. This encodes:
* Whether the user is currently online
* How recently the user was last active (as seen by the server)
* Whether a given client considers the user to be currently idle
* Arbitrary information about the user's current status (e.g. "in a meeting").
This information is collated from both per-device (``online``, ``idle``,
``last_active``) and per-user (status) data, aggregated by the user's homeserver
and transmitted as an ``m.presence`` event. This is one of the few events which
are sent *outside the context of a room*. Presence events are sent to all users
who subscribe to this user's presence through a presence list or by sharing
membership of a room.
A presence list is a list of user IDs whose presence the user wants to follow.
To be added to this list, the user being added must be invited by the list owner
who must accept the invitation.
Each user has the concept of presence information. This encodes the
"availability" of that user, suitable for display on other user's clients.
This is transmitted as an ``m.presence`` event and is one of the few events
which are sent *outside the context of a room*. The basic piece of presence
information is represented by the ``presence`` key, which is an enum of one
of the following:
User's presence state is represented by the ``presence`` key, which is an enum
of one of the following:
- ``online`` : The default state when the user is connected to an event
stream.
- ``unavailable`` : The user is not reachable at this time.
- ``offline`` : The user is not connected to an event stream.
- ``unavailable`` : The user is not reachable at this time e.g. they are
idle.
- ``offline`` : The user is not connected to an event stream or is
explicitly suppressing their profile information from being sent.
- ``free_for_chat`` : The user is generally willing to receive messages
moreso than default.
- ``hidden`` : Behaves as offline, but allows the user to see the client
state anyway and generally interact with client features. (Not yet
implemented in synapse).
In addition, the server maintains a timestamp of the last time it saw a
pro-active event from the user; either sending a message to a room, or
changing presence state from a lower to a higher level of availability
(thus: changing state from ``unavailable`` to ``online`` counts as a
proactive event, whereas in the other direction it will not). This timestamp
is presented via a key called ``last_active_ago``, which gives the relative
number of milliseconds since the message is generated/emitted that the user
was last seen active.
Events
------
{{presence_events}}
Presence HTTP API
-----------------
.. TODO-spec
- Define how users receive presence invites, and how they accept/decline them
Client behaviour
----------------
Clients can manually set/get their presence/presence list using the HTTP APIs
listed below.
{{presence_http_api}}
Idle timeout
~~~~~~~~~~~~
Clients SHOULD implement an "idle timeout". This is a timer which fires after
a period of inactivity on the client. The definition of inactivity varies
depending on the client. For example, web implementations may determine
inactivity to be not moving the mouse for a certain period of time. When this
timer fires it should set the presence state to ``unavailable``. When the user
becomes active again (e.g. by moving the mouse) the client should set the
presence state to ``online``. A timeout value between 1 and 5 minutes is
recommended.
Server behaviour
----------------
Each user's home server stores a "presence list" per user. Once a user accepts
a presence list, both user's HSes must track the subscription.
Propagating profile information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because the profile display name and avatar information are likely to be used in
many places of a client's display, changes to these fields SHOULD cause an
automatic propagation event to occur, informing likely-interested parties of the
new values. One of these change mechanisms SHOULD be via ``m.presence`` events.
These events should set ``displayname`` and ``avatar_url`` to the new values
along with the presence-specific keys. This SHOULD be done automatically by the
home server when a user successfully changes their display name or avatar URL.
.. admonition:: Rationale
The intention for sending this information in ``m.presence`` is so that any
"user list" can display the *current* name/presence for a user ID outside the
scope of a room e.g. for a user page. This is bundled into a single event for
several reasons. The user's display name can change per room. This
event provides the "canonical" name for the user. In addition, the name is
bundled into a single event for the ease of client implementations. If this
was not done, the client would need to search all rooms for their own
membership event to pull out the display name.
Last active ago
~~~~~~~~~~~~~~~
The server maintains a timestamp of the last time it saw a
pro-active event from the user. A pro-active event may be sending a message to a
room or changing presence state to a higher level of availability. Levels of
availability are defined from low to high as follows:
- ``offline``
- ``unavailable``
- ``online``
- ``free_for_chat``
Based on this list, changing state from ``unavailable`` to ``online`` counts as
a pro-active event, whereas ``online`` to ``unavailable`` does not. This
timestamp is presented via a key called ``last_active_ago`` which gives the
relative number of milliseconds since the pro-active event.
Security considerations
-----------------------
Events on Change of Profile Information
---------------------------------------
Because the profile displayname and avatar information are likely to be used in
many places of a client's display, changes to these fields cause an automatic
propagation event to occur, informing likely-interested parties of the new
values. This change is conveyed using two separate mechanisms:
- a ``m.room.member`` event is sent to every room the user is a member of,
to update the ``displayname`` and ``avatar_url``.
- a ``m.presence`` presence status update is sent, again containing the new values of the
``displayname`` and ``avatar_url`` keys, in addition to the required
``presence`` key containing the current presence state of the user.
Both of these should be done automatically by the home server when a user
successfully changes their displayname or avatar URL fields.
Additionally, when home servers emit room membership events for their own
users, they should include the displayname and avatar URL fields in these
events so that clients already have these details to hand, and do not have to
perform extra roundtrips to query it.
Presence information is shared with all users who share a room with the target
user. In large public rooms this could be undesirable.

View file

@ -1,49 +1,46 @@
Typing Notifications
--------------------
====================
.. _module:typing:
Client APIs
~~~~~~~~~~~
Users may wish to be informed when another user is typing in a room. This can be
achieved using typing notifications. These are ephemeral events scoped to a
``room_id``. This means they do not form part of the `Event Graph`_ but still
have a ``room_id`` key.
To set "I am typing for the next N msec"::
.. _Event Graph: `sect:event-graph`_
PUT .../rooms/<room_id>/typing/<user_id>
Content: { "typing": true, "timeout": N }
# timeout is in milliseconds; suggested no more than 20 or 30 seconds
Events
------
This should be re-sent by the client to continue informing the server the user
is still typing; a safety margin of 5 seconds before the expected
timeout runs out is recommended. Just keep declaring a new timeout, it will
replace the old one.
{{m_typing_event}}
To set "I am no longer typing"::
Client behaviour
----------------
PUT ../rooms/<room_id>/typing/<user_id>
Content: { "typing": false }
When a client receives an ``m.typing`` event, it MUST use the user ID list to
**REPLACE** its knowledge of every user who is currently typing. The reason for
this is that the server *does not remember* users who are not currently typing
as that list gets big quickly. The client should mark as not typing any user ID
who is not in that list.
Client Events
~~~~~~~~~~~~~
It is recommended that clients store a ``boolean`` indicating whether the user
is typing or not. Whilst this value is ``true`` a timer should fire periodically
every N seconds to send a typing HTTP request. The value of N is recommended to
be no more than 20-30 seconds. This request should be re-sent by the client to
continue informing the server the user is still typing. As subsequent
requests will replace older requests, a safety margin of 5 seconds before the
expected timeout runs out is recommended. When the user stops typing, the
state change of the ``boolean`` to ``false`` should trigger another HTTP request
to inform the server that the user has stopped typing.
All room members will receive an event on the event stream::
{{typing_http_api}}
{
"type": "m.typing",
"room_id": "!room-id-here:matrix.org",
"content": {
"user_ids": ["list of", "every user", "who is", "currently typing"]
}
}
Server behaviour
----------------
The client must use this list to *REPLACE* its knowledge of every user who is
currently typing. The reason for this is that the server DOES NOT remember
users who are not currently typing, as that list gets big quickly. The client
should mark as not typing, any user ID who is not in that list.
Server APIs
~~~~~~~~~~~
Servers will emit EDUs in the following form::
Servers MUST emit typing EDUs in a different form to ``m.typing`` events which
are shown to clients. This form looks like::
{
"type": "m.typing",
@ -54,10 +51,16 @@ Servers will emit EDUs in the following form::
}
}
Server EDUs don't (currently) contain timing information; it is up to
originating HSes to ensure they eventually send "stop" notifications.
This does not contain timing information so it is up to originating homeservers
to ensure they eventually send "stop" notifications.
.. TODO
((This will eventually need addressing, as part of the wider typing/presence
timer addition work))
Security considerations
-----------------------
Clients may not wish to inform everyone in a room that they are typing and
instead only specific users in the room.