specification.rst 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. ===========================
  2. Matrix Server-to-Server API
  3. ===========================
  4. A description of the protocol used to communicate between Matrix home servers;
  5. also known as Federation.
  6. Overview
  7. ========
  8. The server-server API is a mechanism by which two home servers can exchange
  9. Matrix event messages, both as a real-time push of current events, and as a
  10. historic fetching mechanism to synchronise past history for clients to view. It
  11. uses HTTP connections between each pair of servers involved as the underlying
  12. transport. Messages are exchanged between servers in real-time by active pushing
  13. from each server's HTTP client into the server of the other. Queries to fetch
  14. historic data for the purpose of back-filling scrollback buffers and the like
  15. can also be performed.
  16. { Matrix clients } { Matrix clients }
  17. ^ | ^ |
  18. | events | | events |
  19. | V | V
  20. +------------------+ +------------------+
  21. | |---------( HTTP )---------->| |
  22. | Home Server | | Home Server |
  23. | |<--------( HTTP )-----------| |
  24. +------------------+ +------------------+
  25. There are three main kinds of communication that occur between home servers:
  26. * Queries
  27. These are single request/response interactions between a given pair of
  28. servers, initiated by one side sending an HTTP request to obtain some
  29. information, and responded by the other. They are not persisted and contain
  30. no long-term significant history. They simply request a snapshot state at the
  31. instant the query is made.
  32. * EDUs - Ephemeral Data Units
  33. These are notifications of events that are pushed from one home server to
  34. another. They are not persisted and contain no long-term significant history,
  35. nor does the receiving home server have to reply to them.
  36. * PDUs - Persisted Data Units
  37. These are notifications of events that are broadcast from one home server to
  38. any others that are interested in the same "context" (namely, a Room ID).
  39. They are persisted to long-term storage and form the record of history for
  40. that context.
  41. Where Queries are presented directly across the HTTP connection as GET requests
  42. to specific URLs, EDUs and PDUs are further wrapped in an envelope called a
  43. Transaction, which is transferred from the origin to the destination home server
  44. using a PUT request.
  45. Transactions and EDUs/PDUs
  46. ==========================
  47. The transfer of EDUs and PDUs between home servers is performed by an exchange
  48. of Transaction messages, which are encoded as JSON objects with a dict as the
  49. top-level element, passed over an HTTP PUT request. A Transaction is meaningful
  50. only to the pair of home servers that exchanged it; they are not globally-
  51. meaningful.
  52. Each transaction has an opaque ID and timestamp (UNIX epoch time in
  53. milliseconds) generated by its origin server, an origin and destination server
  54. name, a list of "previous IDs", and a list of PDUs - the actual message payload
  55. that the Transaction carries.
  56. {"transaction_id":"916d630ea616342b42e98a3be0b74113",
  57. "ts":1404835423000,
  58. "origin":"red",
  59. "destination":"blue",
  60. "prev_ids":["e1da392e61898be4d2009b9fecce5325"],
  61. "pdus":[...],
  62. "edus":[...]}
  63. The "previous IDs" field will contain a list of previous transaction IDs that
  64. the origin server has sent to this destination. Its purpose is to act as a
  65. sequence checking mechanism - the destination server can check whether it has
  66. successfully received that Transaction, or ask for a retransmission if not.
  67. The "pdus" field of a transaction is a list, containing zero or more PDUs.[*]
  68. Each PDU is itself a dict containing a number of keys, the exact details of
  69. which will vary depending on the type of PDU. Similarly, the "edus" field is
  70. another list containing the EDUs. This key may be entirely absent if there are
  71. no EDUs to transfer.
  72. (* Normally the PDU list will be non-empty, but the server should cope with
  73. receiving an "empty" transaction, as this is useful for informing peers of other
  74. transaction IDs they should be aware of. This effectively acts as a push
  75. mechanism to encourage peers to continue to replicate content.)
  76. All PDUs have an ID, a context, a declaration of their type, a list of other PDU
  77. IDs that have been seen recently on that context (regardless of which origin
  78. sent them), and a nested content field containing the actual event content.
  79. [[TODO(paul): Update this structure so that 'pdu_id' is a two-element
  80. [origin,ref] pair like the prev_pdus are]]
  81. {"pdu_id":"a4ecee13e2accdadf56c1025af232176",
  82. "context":"#example.green",
  83. "origin":"green",
  84. "ts":1404838188000,
  85. "pdu_type":"m.text",
  86. "prev_pdus":[["blue","99d16afbc857975916f1d73e49e52b65"]],
  87. "content":...
  88. "is_state":false}
  89. In contrast to the transaction layer, it is important to note that the prev_pdus
  90. field of a PDU refers to PDUs that any origin server has sent, rather than
  91. previous IDs that this origin has sent. This list may refer to other PDUs sent
  92. by the same origin as the current one, or other origins.
  93. Because of the distributed nature of participants in a Matrix conversation, it
  94. is impossible to establish a globally-consistent total ordering on the events.
  95. However, by annotating each outbound PDU at its origin with IDs of other PDUs it
  96. has received, a partial ordering can be constructed allowing causallity
  97. relationships to be preserved. A client can then display these messages to the
  98. end-user in some order consistent with their content and ensure that no message
  99. that is semantically in reply of an earlier one is ever displayed before it.
  100. PDUs fall into two main categories: those that deliver Events, and those that
  101. synchronise State. For PDUs that relate to State synchronisation, additional
  102. keys exist to support this:
  103. {...,
  104. "is_state":true,
  105. "state_key":TODO
  106. "power_level":TODO
  107. "prev_state_id":TODO
  108. "prev_state_origin":TODO}
  109. [[TODO(paul): At this point we should probably have a long description of how
  110. State management works, with descriptions of clobbering rules, power levels, etc
  111. etc... But some of that detail is rather up-in-the-air, on the whiteboard, and
  112. so on. This part needs refining. And writing in its own document as the details
  113. relate to the server/system as a whole, not specifically to server-server
  114. federation.]]
  115. EDUs, by comparison to PDUs, do not have an ID, a context, or a list of
  116. "previous" IDs. The only mandatory fields for these are the type, origin and
  117. destination home server names, and the actual nested content.
  118. {"edu_type":"m.presence",
  119. "origin":"blue",
  120. "destination":"orange",
  121. "content":...}
  122. Protocol URLs
  123. =============
  124. All these URLs are namespaced within a prefix of
  125. /_matrix/federation/v1/...
  126. For active pushing of messages representing live activity "as it happens":
  127. PUT .../send/:transaction_id/
  128. Body: JSON encoding of a single Transaction
  129. Response: [[TODO(paul): I don't actually understand what
  130. ReplicationLayer.on_transaction() is doing here, so I'm not sure what the
  131. response ought to be]]
  132. The transaction_id path argument will override any ID given in the JSON body.
  133. The destination name will be set to that of the receiving server itself. Each
  134. embedded PDU in the transaction body will be processed.
  135. To fetch a particular PDU:
  136. GET .../pdu/:origin/:pdu_id/
  137. Response: JSON encoding of a single Transaction containing one PDU
  138. Retrieves a given PDU from the server. The response will contain a single new
  139. Transaction, inside which will be the requested PDU.
  140. To fetch all the state of a given context:
  141. GET .../state/:context/
  142. Response: JSON encoding of a single Transaction containing multiple PDUs
  143. Retrieves a snapshot of the entire current state of the given context. The
  144. response will contain a single Transaction, inside which will be a list of
  145. PDUs that encode the state.
  146. To backfill events on a given context:
  147. GET .../backfill/:context/
  148. Query args: v, limit
  149. Response: JSON encoding of a single Transaction containing multiple PDUs
  150. Retrieves a sliding-window history of previous PDUs that occurred on the
  151. given context. Starting from the PDU ID(s) given in the "v" argument, the
  152. PDUs that preceeded it are retrieved, up to a total number given by the
  153. "limit" argument. These are then returned in a new Transaction containing all
  154. off the PDUs.
  155. To stream events all the events:
  156. GET .../pull/
  157. Query args: origin, v
  158. Response: JSON encoding of a single Transaction consisting of multiple PDUs
  159. Retrieves all of the transactions later than any version given by the "v"
  160. arguments. [[TODO(paul): I'm not sure what the "origin" argument does because
  161. I think at some point in the code it's got swapped around.]]
  162. To make a query:
  163. GET .../query/:query_type
  164. Query args: as specified by the individual query types
  165. Response: JSON encoding of a response object
  166. Performs a single query request on the receiving home server. The Query Type
  167. part of the path specifies the kind of query being made, and its query
  168. arguments have a meaning specific to that kind of query. The response is a
  169. JSON-encoded object whose meaning also depends on the kind of query.