From 3eb300a96d4d6f337dc13dc47002d7480ea073fc Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 May 2023 16:37:07 +0300 Subject: [PATCH] Start writing spec for MSC2659: application service ping endpoint --- content/application-service-api.md | 42 ++++++ data/api/application-service/ping.yaml | 72 ++++++++++ data/api/client-server/appservice_ping.yaml | 148 ++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 data/api/application-service/ping.yaml create mode 100644 data/api/client-server/appservice_ping.yaml diff --git a/content/application-service-api.md b/content/application-service-api.md index 7a14869a..e433186b 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -207,6 +207,48 @@ processed the events. {{% http-api spec="application-service" api="transactions" %}} +#### Pinging + +{{% added-in v="1.7" %}} + +The application service API includes a ping mechanism to allow +appservices to ensure that the homeserver can reach the appservice. +Appservices may use this mechanism to detect misconfigurations and +report them appropriately. + +Implementations using this mechanism should take care to not fail +entirely in the event of temporary issues, e.g. gracefully handling +cases where the appservice is started before the homeserver. + +The mechanism works as follows: + +``` + Typical + AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"} + HS ---> AS : /_matrix/app/v1/ping {"transaction_id": "meow"} + HS <--- AS : 200 OK {} + AS <--- HS : 200 OK {"duration_ms": 123} +``` + +``` + Incorrect hs_token + AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"} + HS ---> AS : /_matrix/app/v1/ping {"transaction_id": "meow"} + HS <--- AS : 401 Unauthorized {"errcode": "M_UNKNOWN_TOKEN"} + AS <--- HS : 502 Bad Gateway {"errcode": "M_BAD_STATUS", "status": 401, "body": "{\"errcode\": \"M_UNKNOWN_TOKEN\"}"} +``` + +``` + Can't connect to appservice + AS ---> HS : /_matrix/client/v1/appservice/{appserviceId}/ping {"transaction_id": "meow"} + HS -/-> AS : /_matrix/app/v1/ping {"transaction_id": "meow"} + AS <--- HS : 502 Bad Gateway {"errcode": "M_CONNECTION_FAILED"} +``` + +{{% http-api spec="client-server" api="appservice_ping" %}} + +{{% http-api spec="application-service" api="ping" %}} + #### Querying The application service API includes two querying APIs: for room aliases diff --git a/data/api/application-service/ping.yaml b/data/api/application-service/ping.yaml new file mode 100644 index 00000000..f6e7bf66 --- /dev/null +++ b/data/api/application-service/ping.yaml @@ -0,0 +1,72 @@ +# Copyright 2023 Tulir Asokan +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Application Service API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/app/v1 +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/ping": + post: + x-addedInMatrixVersion: "1.7" + summary: Ping the application service + description: |- + This API is called by the homeserver to ensure that the connection works + and the `hs_token` the homeserver has is correct. + + Currently this is only called by the homeserver as a direct result of + the application service calling the appservice ping endpoint in the + client API. + operationId: ping + security: + - homeserverAccessToken: [] + parameters: + - in: path + name: txnId + type: string + description: |- + The transaction ID for this set of events. Homeservers generate + these IDs and they are used to ensure idempotency of requests. + required: true + x-example: "35" + - in: body + name: body + description: Ping body with optional transaction ID. + schema: + type: object + example: { + "transaction_id": "mautrix-go_1683636478256400935_123" + } + properties: + transaction_id: + type: string + description: |- + A transaction ID for the ping, copied directly from the + client API appservice ping call. + required: ["events"] + responses: + 200: + description: The hs_token is valid and the ping request was successful. + examples: + application/json: {} + schema: + type: object diff --git a/data/api/client-server/appservice_ping.yaml b/data/api/client-server/appservice_ping.yaml new file mode 100644 index 00000000..c5e54f13 --- /dev/null +++ b/data/api/client-server/appservice_ping.yaml @@ -0,0 +1,148 @@ +# Copyright 2023 Tulir Asokan +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Client-Server Application Service Ping API" + version: "1.0.0" +host: localhost:8008 +schemes: + - https + - http +basePath: /_matrix/client/v1 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + # Note: this is the same access_token definition used elsewhere in the client + # server API, however this expects an access token for an application service. + $ref: definitions/security.yaml +paths: + "/appservice/{appserviceId}/ping": + post: + x-addedInMatrixVersion: "1.7" + summary: |- + Ask the homeserver to ping the application service to ensure the connection works. + description: |- + This API asks the homeserver to call the `/_matrix/app/v1/ping` endpoint + on the application service to ensure that the homeserver can communicate + with the application service. + + This API requires the use of an application service access token (`as_token`) + instead of a typical client's access_token. This API cannot be invoked by + users who are not identified as application services. Additionally, the + appservice ID in the path must be the same as the appservice whose `as_token` + is being used. + operationId: pingAppservice + parameters: + - in: path + type: string + name: appserviceId + description: |- + The appservice ID of the appservice to ping. This must be the same + as the appservice whose `as_token` is being used to authenticate the + request. + required: true + x-example: "telegram" + - in: body + name: body + required: true + schema: + type: object + properties: + transaction_id: + type: string + description: |- + An optional transaction ID that is passed through to the `/_matrix/app/v1/ping` call. + example: "mautrix-go_1683636478256400935_123" + security: + # again, this is the appservice's token - not a typical client's + - accessToken: [] + responses: + 200: + description: The ping was successful + schema: + type: object + properties: + duration_ms: + type: integer + description: |- + The duration that the `/_matrix/app/v1/ping` request took + from the homeserver's point of view. + examples: + application/json: {"duration_ms": 123} + 400: + description: The application service doesn't have a URL configured. The errcode is `M_URL_NOT_SET`. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_URL_NOT_SET", + "error": "Application service doesn't have a URL configured" + } + 403: + description: The access token used to authenticate the request doesn't belong to an appservice, or belongs to a different appservice than the one in the path. The errcode is `M_FORBIDDEN`. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_FORBIDDEN", + "error": "Provided access token is not the appservice's as_token" + } + 502: + description: |- + The application service returned a bad status, or the connection failed. + The errcode is `M_BAD_STATUS` or `M_CONNECTION_FAILED`. + + For bad statuses, the response may include `status` and `body` + fields containing the HTTP status code and response body text + respectively to aid with debugging. + schema: + type: object + title: Error + description: A Matrix-level Error + properties: + errcode: + type: string + description: An error code. + enum: [M_BAD_STATUS, M_CONNECTION_FAILED] + error: + type: string + description: A human-readable error message. + example: Ping returned status 401 + status: + type: integer + description: The HTTP status code returned by the appservice. + example: 401 + body: + type: string + description: The HTTP response body returned by the appservice. + example: "{\"errcode\": \"M_UNKNOWN_TOKEN\"}" + required: ["errcode"] + examples: + application/json: { + "errcode": "M_BAD_STATUS", + "error": "Ping returned status 401", + "status": 401, + "body": "{\"errcode\": \"M_UNKNOWN_TOKEN\"}" + } + 504: + description: The connection to the application service timed out. The errcode is `M_CONNECTION_TIMEOUT`. + schema: + $ref: "definitions/errors/error.yaml" + examples: + application/json: { + "errcode": "M_CONNECTION_TIMEOUT", + "error": "Connection to application service timed out" + }