Skip to content

Commit 3fb2a60

Browse files
tulirturt2live
andauthored
MSC2659: Application service ping endpoint (#2659)
* Proposal for an application service ping endpoint Signed-off-by: Tulir Asokan <[email protected]> * Apply suggestions from code review Co-authored-by: Travis Ralston <[email protected]> * Change unstable prefix and add appserviceId parameter to path Signed-off-by: Tulir Asokan <[email protected]> * Redo MSC to use dedicated endpoint Signed-off-by: Tulir Asokan <[email protected]> * Re-add appservice ID path parameter and txn ID body field * Add some alternatives * Fix path in unstable prefix * Add some optional extra behavior to endpoints * Specify transaction_id type and mention it in both endpoints * Add note about homeservers not calling ping randomly * Make it more explicit which request duration is being measured * Add example of full ping flow * Fix markdown list * Add /versions endpoint under alternatives * Add MSC number to title Co-authored-by: Travis Ralston <[email protected]> * Rename duration field * Document unstable_features flags --------- Signed-off-by: Tulir Asokan <[email protected]> Co-authored-by: Travis Ralston <[email protected]>
1 parent 126ca85 commit 3fb2a60

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

proposals/2659-appservice-ping.md

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# MSC2659: Application service ping endpoint
2+
3+
## Problem
4+
A relatively common problem when setting up appservices is the connection
5+
between the appservice and homeserver not working in one or both directions.
6+
If the appservice is unable to connect to the homeserver, it can simply show
7+
the error message to the user. However, there's currently no easy way for the
8+
appservice to know if the homeserver is unable to connect to it. This means
9+
that the appservice might start up fine, but not actually work, because the
10+
homeserver isn't sending events to it.
11+
12+
## Proposed solution
13+
The proposed solution is a new endpoint in homeservers that appservices can use
14+
to trigger a ping. A new endpoint is also added to the appservice side for the
15+
homeserver to call without any side-effects.
16+
17+
Appservices can use the endpoint at startup to ensure communication works in
18+
both directions, and show an error to the user if it doesn't.
19+
20+
### `POST /_matrix/app/v1/ping`
21+
This endpoint is on the appservice side. Like all other appservice-side
22+
endpoints, it is authenticated using the `hs_token`. When the token is correct,
23+
this returns HTTP 200 and an empty JSON object as the body.
24+
25+
The request body contains an optional `transaction_id` string field, which
26+
comes from the client ping request defined below.
27+
28+
Appservices don't need to have any special behavior on this endpoint, but they
29+
may use the incoming request to verify that an outgoing ping actually pinged
30+
the appservice rather than going somewhere else.
31+
32+
This proposal doesn't define any cases where a homeserver would call the ping
33+
endpoint unless explicitly requested by the appservice (using the client
34+
endpoint below). Therefore, appservices don't necessarily have to implement
35+
this endpoint if they never call the client ping endpoint.
36+
37+
### `POST /_matrix/client/v1/appservice/{appserviceId}/ping`
38+
When the endpoint is called, the homeserver makes a `/_matrix/app/v1/ping`
39+
request to the appservice.
40+
41+
The request body may contain a `transaction_id` string field, which, if present,
42+
must be passed through to the appservice `/ping` request body as-is.
43+
44+
This endpoint is only allowed when using a valid appservice token, and it can
45+
only ping the appservice associated with the token. If the token or appservice
46+
ID in the path is wrong, the server may return `M_FORBIDDEN`. However,
47+
implementations and future spec proposals may extend what kinds of pings are
48+
allowed.
49+
50+
In case the homeserver had backed off on sending transactions, it may treat a
51+
successful ping as a sign that the appservice is up again and transactions
52+
should be retried.
53+
54+
#### Response
55+
If the ping request returned successfully, the endpoint returns HTTP 200. The
56+
response body has a `duration_ms` field containing the `/_matrix/app/v1/ping`
57+
request roundtrip time as milliseconds.
58+
59+
If the request fails, the endpoint returns a standard error response with
60+
`errcode`s and HTTP status codes as specified below:
61+
62+
* If the appservice doesn't have a URL configured, `M_URL_NOT_SET` and HTTP 400.
63+
* For non-2xx responses, `M_BAD_STATUS` and HTTP 502. Additionally, the response
64+
may include `status` (integer) and `body` (string) fields containing the HTTP
65+
status code and response body text respectively to aid with debugging.
66+
* For connection timeouts, `M_CONNECTION_TIMEOUT` and HTTP 504.
67+
* For other connection errors, `M_CONNECTION_FAILED` and HTTP 502.
68+
It is recommended to put a more detailed explanation in the `error` field.
69+
70+
### Example flow
71+
72+
1. bridge -> homeserver (request #1): `POST http://synapse:8008/_matrix/client/v1/appservice/whatsapp/ping`
73+
* Header `Authorization: Bearer as_token`
74+
* Body: `{"transaction_id": "meow"}`
75+
2. homeserver -> bridge (request #2): `POST http://bridge:29318/_matrix/app/v1/ping`
76+
* Header `Authorization: Bearer hs_token`
77+
* Body: `{"transaction_id": "meow"}`
78+
3. bridge -> homeserver (response to #2): 200 OK with body `{}`
79+
4. homeserver -> bridge (response to #1): 200 OK with body `{"duration_ms": 123}`
80+
(123 milliseconds being the time it took for request #2 to complete).
81+
82+
## Alternatives
83+
84+
* The ping could make an empty `/transactions` request instead of adding a new
85+
ping endpoint. A new endpoint was found to be cleaner while implementing, and
86+
there didn't seem to be any significant benefits to reusing transactions.
87+
* A `/versions` endpoint could be introduced to work for both pinging and
88+
checking what spec versions an appservice supports. However, it's not clear
89+
that a new endpoint is the best way to detect version support (a simple flag
90+
in the registration file may be preferable), so this MSC proposes a `/ping`
91+
endpoint that doesn't have other behavior.
92+
* Appservices could be switched to using websockets instead of the server
93+
pushing events. This option is already used by some bridges, but implementing
94+
websocket support on the homeserver side is much more complicated than a
95+
simple ping endpoint.
96+
97+
## Unstable prefix
98+
The endpoints can be implemented as `/_matrix/app/unstable/fi.mau.msc2659/ping`
99+
and `/_matrix/client/unstable/fi.mau.msc2659/appservice/{appserviceId}/ping`.
100+
Error codes can use `FI.MAU.MSC2659_` instead of `M_` as the prefix.
101+
102+
`fi.mau.msc2659` can be used as an `unstable_features` flag in `/versions` to
103+
indicate support for the unstable prefixed endpoint. Once the MSC is approved,
104+
`fi.mau.msc2659.stable` can be used to indicate support for the stable endpoint
105+
until the spec release containing the endpoint is supported.

0 commit comments

Comments
 (0)