From f155fdcc3e4e7ba6f34006b4665a6fe6c545d11d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:43:44 -0600 Subject: [PATCH 01/21] C2S: Deprecate now-legacy endpoints --- data/api/client-server/content-repo.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data/api/client-server/content-repo.yaml b/data/api/client-server/content-repo.yaml index e6d55b51a..e8691a4ab 100644 --- a/data/api/client-server/content-repo.yaml +++ b/data/api/client-server/content-repo.yaml @@ -217,6 +217,7 @@ paths: - Media "/media/v3/download/{serverName}/{mediaId}": get: + deprecated: true summary: Download content from the content repository. operationId: getContent parameters: @@ -254,6 +255,7 @@ paths: - Media "/media/v3/download/{serverName}/{mediaId}/{fileName}": get: + deprecated: true summary: Download content from the content repository overriding the file name description: |- This will download content from the content repository (same as @@ -304,6 +306,7 @@ paths: - Media "/media/v3/thumbnail/{serverName}/{mediaId}": get: + deprecated: true summary: Download a thumbnail of content from the content repository description: |- Download a thumbnail of content from the content repository. @@ -455,6 +458,7 @@ paths: - Media /media/v3/preview_url: get: + deprecated: true summary: Get information about a URL for a client description: |- Get information about a URL for the client. Typically this is called when a @@ -525,6 +529,7 @@ paths: - Media /media/v3/config: get: + deprecated: true summary: Get the configuration for the content repository. description: |- This endpoint allows clients to retrieve the configuration of the content @@ -625,7 +630,7 @@ components: Indicates to the server that it should not attempt to fetch the media if it is deemed remote. This is to prevent routing loops where the server contacts itself. - + Defaults to `true` if not provided. example: false schema: From bd0353072f0c29481d99d727fa240b57d137d5a4 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:44:31 -0600 Subject: [PATCH 02/21] C2S: Fix MXC URI code block while we're here --- content/client-server-api/modules/content_repo.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index cef70b3dc..37c13e70c 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -28,10 +28,12 @@ interacting with the media repository. Content locations are represented as Matrix Content (`mxc://`) URIs. They look like: - mxc:/// +``` +mxc:/// - : The name of the homeserver where this content originated, e.g. matrix.org - : An opaque ID which identifies the content. + : The name of the homeserver where this content originated, e.g. matrix.org + : An opaque ID which identifies the content. +``` #### Client behaviour From 214e38ae40c931ea40abf337b6a1900ea228a628 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:44:55 -0600 Subject: [PATCH 03/21] C2S: Describe the authentication and deprecation requirements --- .../client-server-api/modules/content_repo.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 37c13e70c..66ef86a1b 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -23,6 +23,15 @@ When serving content, the server SHOULD provide a interacting with the media repository. {{% /boxes/added-in-paragraph %}} +{{% boxes/added-in-paragraph %}} +{{< changed-in v="1.11" >}} The unauthenticated download endpoints have been +deprecated in favour of newer, authenticated, ones. This change included updating +the pathing of all media endpoints from `/_matrix/media/*` to `/_matrix/client/{version}/media/*`, +with the exception of the `/upload` and `/create` endpoints. The upload/create +endpoints are expected to undergo a similar transition in a later version of the +specification. +{{% /boxes/added-in-paragraph %}} + #### Matrix Content (`mxc://`) URIs Content locations are represented as Matrix Content (`mxc://`) URIs. They @@ -37,7 +46,14 @@ mxc:/// #### Client behaviour -Clients can upload and download content using the following HTTP APIs. +Clients can access the content repository using the following endpoints. + +{{% boxes/added-in-paragraph %}} +{{< changed-in v="1.11" >}} Clients SHOULD NOT use the deprecated media endpoints +described below. Instead, they SHOULD use the new endpoints which require authentication. +{{% /boxes/added-in-paragraph %}} + +{{% http-api spec="client-server" api="authed-content-repo" %}} {{% http-api spec="client-server" api="content-repo" %}} From b19e73add500b9cbf78b3015673195ce6c0fc1ba Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:45:17 -0600 Subject: [PATCH 04/21] C2S: Intro the upload/download endpoints differently --- content/client-server-api/_index.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 71f92bec2..cdb43ae3c 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -22,17 +22,15 @@ recommended outside test environments. Clients are authenticated using opaque `access_token` strings (see [Client Authentication](#client-authentication) for details). -All `POST` and `PUT` endpoints, with the exception of [`POST -/_matrix/media/v3/upload`](#post_matrixmediav3upload) and [`PUT -/_matrix/media/v3/upload/{serverName}/{mediaId}`](#put_matrixmediav3uploadservernamemediaid), +All `POST` and `PUT` endpoints, with the exception of media upload endpoints +in the [Content Repository module](#content-repository), require the client to supply a request body containing a (potentially empty) JSON object. Clients should supply a `Content-Type` header of `application/json` for all requests with JSON bodies, but this is not required. Similarly, all endpoints require the server to return a JSON object, -with the exception of 200 responses to -[`GET /_matrix/media/v3/download/{serverName}/{mediaId}`](#get_matrixmediav3downloadservernamemediaid) -and [`GET /_matrix/media/v3/thumbnail/{serverName}/{mediaId}`](#get_matrixmediav3thumbnailservernamemediaid). +with the exception of 200 responses to the media download endpoints in the +[Content Repository module](#content-repository). Servers must include a `Content-Type` header of `application/json` for all JSON responses. All JSON data, in requests or responses, must be encoded using UTF-8. From f10abb3613a6f249133d85f3815887f553ee0826 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:45:44 -0600 Subject: [PATCH 05/21] C2S: Literally copy/paste the `content-repo.yaml` spec --- .../client-server/authed-content-repo.yaml | 740 ++++++++++++++++++ 1 file changed, 740 insertions(+) create mode 100644 data/api/client-server/authed-content-repo.yaml diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml new file mode 100644 index 000000000..e8691a4ab --- /dev/null +++ b/data/api/client-server/authed-content-repo.yaml @@ -0,0 +1,740 @@ +# Copyright 2016 OpenMarket Ltd +# Copyright 2019 The Matrix.org Foundation C.I.C. +# +# 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. +openapi: 3.1.0 +info: + title: Matrix Client-Server Content Repository API + version: 1.0.0 +paths: + /media/v3/upload: + post: + summary: Upload some content to the content repository. + operationId: uploadContent + security: + - accessTokenQuery: [] + - accessTokenBearer: [] + parameters: + - $ref: '#/components/parameters/contentType' + - $ref: '#/components/parameters/filename' + requestBody: + $ref: '#/components/requestBodies/bytes' + responses: + "200": + description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for + the uploaded content. + content: + application/json: + schema: + type: object + required: + - content_uri + properties: + content_uri: + type: string + format: mx-mxc-uri + pattern: "^mxc:\\/\\/" + description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to + the uploaded content. + examples: + response: + value: { + "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw" + } + "403": + description: |- + The user does not have permission to upload the content. Some reasons for this error include: + + - The server does not permit the file type. + - The user has reached a quota for uploaded content. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_FORBIDDEN", + "error": "Cannot upload this content" + } + "413": + $ref: '#/components/responses/uploadTooLarge' + "429": + $ref: '#/components/responses/rateLimited' + tags: + - Media + "/media/v3/upload/{serverName}/{mediaId}": + put: + summary: Upload content to an `mxc://` URI that was created earlier. + description: |- + This endpoint permits uploading content to an `mxc://` URI that was created + earlier via [POST /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create). + operationId: uploadContentToMXC + x-addedInMatrixVersion: "1.7" + parameters: + - $ref: '#/components/parameters/serverName' + description: | + The server name from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the authority component). + - $ref: '#/components/parameters/mediaId' + description: | + The media ID from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the path component). + - $ref: '#/components/parameters/contentType' + - $ref: '#/components/parameters/filename' + requestBody: + $ref: '#/components/requestBodies/bytes' + responses: + "200": + description: The upload was successful. + content: + application/json: + schema: + type: object + examples: + response: + value: {} + "403": + description: |- + The user does not have permission to upload the content. Some reasons for this error include: + + - The server does not permit the file type. + - The user has reached a quota for uploaded content. + - The request comes from a different user than the one that called + [POST /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create). + + A [standard error response](/client-server-api/#standard-error-response) + will be returned with the `errcode` `M_FORBIDDEN`. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_FORBIDDEN", + "error": "Cannot upload this content" + } + "409": + description: |- + The endpoint was called with a media ID that already has content. A + [standard error response](/client-server-api/#standard-error-response) + will be returned with the `errcode` `M_CANNOT_OVERWRITE_MEDIA`. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_CANNOT_OVERWRITE_MEDIA", + "error": "Media already uploaded" + } + "413": + $ref: '#/components/responses/uploadTooLarge' + "429": + $ref: '#/components/responses/rateLimited' + tags: + - Media + /media/v1/create: + post: + summary: Create a new `mxc://` URI without uploading the content. + description: |- + Creates a new `mxc://` URI, independently of the content being uploaded. The content must be provided later + via [`PUT /_matrix/media/v3/upload/{serverName}/{mediaId}`](/client-server-api/#put_matrixmediav3uploadservernamemediaid). + + The server may optionally enforce a maximum age for unused IDs, + and delete media IDs when the client doesn't start the upload in time, + or when the upload was interrupted and not resumed in time. The server + should include the maximum POSIX millisecond timestamp to complete the + upload in the `unused_expires_at` field in the response JSON. The + recommended default expiration is 24 hours which should be enough time + to accommodate users on poor connection who find a better connection to + complete the upload. + + As well as limiting the rate of requests to create `mxc://` URIs, the server + should limit the number of concurrent *pending media uploads* a given + user can have. A pending media upload is a created `mxc://` URI where (a) + the media has not yet been uploaded, and (b) has not yet expired (the + `unused_expires_at` timestamp has not yet passed). In both cases, the + server should respond with an HTTP 429 error with an errcode of + `M_LIMIT_EXCEEDED`. + operationId: createContent + x-addedInMatrixVersion: "1.7" + security: + - accessTokenQuery: [] + - accessTokenBearer: [] + # empty json object + responses: + "200": + description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for + the uploaded content. + content: + application/json: + schema: + type: object + required: + - content_uri + properties: + content_uri: + type: string + format: mx-mxc-uri + pattern: "^mxc:\\/\\/" + description: |- + The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at + which the content will be available, once it is uploaded. + example: mxc://example.com/AQwafuaFswefuhsfAFAgsw + unused_expires_at: + type: integer + format: int64 + description: |- + The timestamp (in milliseconds since the unix epoch) when the + generated media id will expire, if media is not uploaded. + example: 1647257217083 + "403": + description: The user does not have permission to upload the content. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_FORBIDDEN", + "error": "Cannot upload this content" + } + "429": + $ref: '#/components/responses/rateLimited' + tags: + - Media + "/media/v3/download/{serverName}/{mediaId}": + get: + deprecated: true + summary: Download content from the content repository. + operationId: getContent + parameters: + - $ref: '#/components/parameters/serverName' + - $ref: '#/components/parameters/mediaId' + - $ref: '#/components/parameters/allow_remote' + - $ref: '#/components/parameters/timeout_ms' + - $ref: '#/components/parameters/allow_redirect' + responses: + "200": + description: The content that was previously uploaded. + headers: + Content-Type: + $ref: '#/components/headers/downloadContentType' + Content-Disposition: + description: The name of the file that was previously uploaded, if set. + schema: + type: string + content: + application/octet-stream: + schema: + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the uploaded file." + "307": + $ref: '#/components/responses/downloadRedirect' + "308": + $ref: '#/components/responses/downloadRedirect' + "429": + $ref: '#/components/responses/rateLimited' + "502": + $ref: '#/components/responses/downloadTooLarge' + "504": + $ref: '#/components/responses/notYetUploaded' + tags: + - Media + "/media/v3/download/{serverName}/{mediaId}/{fileName}": + get: + deprecated: true + summary: Download content from the content repository overriding the file name + description: |- + This will download content from the content repository (same as + the previous endpoint) but replace the target file name with the one + provided by the caller. + operationId: getContentOverrideName + parameters: + - $ref: '#/components/parameters/serverName' + - $ref: '#/components/parameters/mediaId' + - in: path + name: fileName + required: true + description: A filename to give in the `Content-Disposition` header. + example: filename.jpg + schema: + type: string + - $ref: '#/components/parameters/allow_remote' + - $ref: '#/components/parameters/timeout_ms' + - $ref: '#/components/parameters/allow_redirect' + responses: + "200": + description: The content that was previously uploaded. + headers: + Content-Type: + $ref: '#/components/headers/downloadContentType' + Content-Disposition: + description: |- + The `fileName` requested or the name of the file that was previously + uploaded, if set. + schema: + type: string + content: + application/octet-stream: + schema: + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the uploaded file." + "307": + $ref: '#/components/responses/downloadRedirect' + "308": + $ref: '#/components/responses/downloadRedirect' + "429": + $ref: '#/components/responses/rateLimited' + "502": + $ref: '#/components/responses/downloadTooLarge' + "504": + $ref: '#/components/responses/notYetUploaded' + tags: + - Media + "/media/v3/thumbnail/{serverName}/{mediaId}": + get: + deprecated: true + summary: Download a thumbnail of content from the content repository + description: |- + Download a thumbnail of content from the content repository. + See the [Thumbnails](/client-server-api/#thumbnails) section for more information. + operationId: getContentThumbnail + parameters: + - $ref: '#/components/parameters/serverName' + - $ref: '#/components/parameters/mediaId' + - in: query + name: width + required: true + description: |- + The *desired* width of the thumbnail. The actual thumbnail may be + larger than the size specified. + example: 64 + schema: + type: integer + - in: query + name: height + required: true + description: |- + The *desired* height of the thumbnail. The actual thumbnail may be + larger than the size specified. + example: 64 + schema: + type: integer + - in: query + name: method + description: |- + The desired resizing method. See the [Thumbnails](/client-server-api/#thumbnails) + section for more information. + example: scale + schema: + type: string + enum: + - crop + - scale + - $ref: '#/components/parameters/allow_remote' + - $ref: '#/components/parameters/timeout_ms' + - $ref: '#/components/parameters/allow_redirect' + - in: query + name: animated + x-addedInMatrixVersion: "1.11" + required: false + description: | + Indicates preference for an animated thumbnail from the server, if possible. Animated + thumbnails typically use the content types `image/gif`, `image/png` (with APNG format), + `image/apng`, and `image/webp` instead of the common static `image/png` or `image/jpeg` + content types. + + When `true`, the server SHOULD return an animated thumbnail if possible and supported. + When `false`, the server MUST NOT return an animated thumbnail. For example, returning a + static `image/png` or `image/jpeg` thumbnail. When not provided, the server SHOULD NOT + return an animated thumbnail. + + Servers SHOULD prefer to return `image/webp` thumbnails when supporting animation. + + When `true` and the media cannot be animated, such as in the case of a JPEG or PDF, the + server should behave as though `animated` is `false`. + example: false + schema: + type: boolean + responses: + "200": + description: A thumbnail of the requested content. + headers: + Content-Type: + description: The content type of the thumbnail. + schema: + type: string + enum: + - image/jpeg + - image/png + - image/apng + - image/gif + - image/webp + content: + image/jpeg: + schema: + # This is a workaround for us not being able to say the response is required. + description: "**Required.** The bytes for the thumbnail." + image/png: + schema: + x-changedInMatrixVersion: + "1.11": The PNG may be of the APNG variety if animation is supported and requested. + description: | + **Required.** The bytes for the thumbnail. The thumbnail MAY use an animated + format if `animated=true`. + image/apng: + schema: + x-addedInMatrixVersion: "1.11" + description: "**Required.** The bytes for the *animated* thumbnail." + image/gif: + schema: + x-addedInMatrixVersion: "1.11" + description: "**Required.** The bytes for the *animated* thumbnail." + image/webp: + schema: + x-addedInMatrixVersion: "1.11" + description: "**Required.** The bytes for the *animated* thumbnail." + "307": + $ref: '#/components/responses/thumbnailRedirect' + "308": + $ref: '#/components/responses/thumbnailRedirect' + "400": + description: |- + The request does not make sense to the server, or the server cannot thumbnail + the content. For example, the client requested non-integer dimensions or asked + for negatively-sized images. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_UNKNOWN", + "error": "Cannot generate thumbnails for the requested content" + } + "413": + description: The local content is too large for the server to thumbnail. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + "429": + $ref: '#/components/responses/rateLimited' + "502": + description: The remote content is too large for the server to thumbnail. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + "504": + $ref: '#/components/responses/notYetUploaded' + tags: + - Media + /media/v3/preview_url: + get: + deprecated: true + summary: Get information about a URL for a client + description: |- + Get information about a URL for the client. Typically this is called when a + client sees a URL in a message and wants to render a preview for the user. + + **Note:** + Clients should consider avoiding this endpoint for URLs posted in encrypted + rooms. Encrypted rooms often contain more sensitive information the users + do not want to share with the homeserver, and this can mean that the URLs + being shared should also not be shared with the homeserver. + operationId: getUrlPreview + security: + - accessTokenQuery: [] + - accessTokenBearer: [] + parameters: + - in: query + name: url + description: The URL to get a preview of. + required: true + example: https://matrix.org + schema: + type: string + format: uri + - in: query + name: ts + description: |- + The preferred point in time to return a preview for. The server may + return a newer version if it does not have the requested version + available. + example: 1510610716656 + schema: + type: integer + format: int64 + responses: + "200": + description: |- + The OpenGraph data for the URL, which may be empty. Some values are + replaced with matrix equivalents if they are provided in the response. + The differences from the OpenGraph protocol are described here. + content: + application/json: + schema: + type: object + properties: + matrix:image:size: + type: integer + format: int64 + description: The byte-size of the image. Omitted if there is no image attached. + og:image: + type: string + format: uri + description: An [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to + the image. Omitted if there is no image. + examples: + response: + value: { + "og:title": "Matrix Blog Post", + "og:description": "This is a really cool blog post from matrix.org", + "og:image": "mxc://example.com/ascERGshawAWawugaAcauga", + "og:image:type": "image/png", + "og:image:height": 48, + "og:image:width": 48, + "matrix:image:size": 102400 + } + "429": + $ref: '#/components/responses/rateLimited' + tags: + - Media + /media/v3/config: + get: + deprecated: true + summary: Get the configuration for the content repository. + description: |- + This endpoint allows clients to retrieve the configuration of the content + repository, such as upload limitations. + Clients SHOULD use this as a guide when using content repository endpoints. + All values are intentionally left optional. Clients SHOULD follow + the advice given in the field description when the field is not available. + + **NOTE:** Both clients and server administrators should be aware that proxies + between the client and the server may affect the apparent behaviour of content + repository APIs, for example, proxies may enforce a lower upload size limit + than is advertised by the server on this endpoint. + operationId: getConfig + security: + - accessTokenQuery: [] + - accessTokenBearer: [] + responses: + "200": + description: The public content repository configuration for the matrix server. + content: + application/json: + schema: + type: object + properties: + m.upload.size: + type: integer + format: int64 + description: |- + The maximum size an upload can be in bytes. + Clients SHOULD use this as a guide when uploading content. + If not listed or null, the size limit should be treated as unknown. + examples: + response: + value: { + "m.upload.size": 50000000 + } + "429": + $ref: '#/components/responses/rateLimited' + tags: + - Media +servers: + - url: "{protocol}://{hostname}{basePath}" + variables: + protocol: + enum: + - http + - https + default: https + hostname: + default: localhost:8008 + basePath: + default: /_matrix +components: + securitySchemes: + accessTokenQuery: + $ref: definitions/security.yaml#/accessTokenQuery + accessTokenBearer: + $ref: definitions/security.yaml#/accessTokenBearer + parameters: + contentType: + in: header + name: Content-Type + description: The content type of the file being uploaded + example: application/pdf + schema: + type: string + filename: + in: query + name: filename + description: The name of the file being uploaded + example: War and Peace.pdf + schema: + type: string + serverName: + in: path + name: serverName + required: true + description: | + The server name from the `mxc://` URI (the authority component). + example: matrix.org + schema: + type: string + format: mx-server-name + mediaId: + in: path + name: mediaId + required: true + description: | + The media ID from the `mxc://` URI (the path component). + example: ascERGshawAWawugaAcauga + schema: + type: string + allow_remote: + in: query + name: allow_remote + required: false + description: |- + Indicates to the server that it should not attempt to fetch the media if + it is deemed remote. This is to prevent routing loops where the server + contacts itself. + + Defaults to `true` if not provided. + example: false + schema: + type: boolean + default: true + timeout_ms: + in: query + name: timeout_ms + x-addedInMatrixVersion: "1.7" + description: | + The maximum number of milliseconds that the client is willing to wait to + start receiving data, in the case that the content has not yet been + uploaded. The default value is 20000 (20 seconds). The content + repository can and should impose a maximum value for this parameter. The + content repository may also choose to respond before the timeout. + example: 5000 + schema: + type: integer + format: int64 + default: 20000 + allow_redirect: + in: query + name: allow_redirect + x-addedInMatrixVersion: "1.7" + required: false + description: | + Indicates to the server that it may return a 307 or 308 redirect + response that points at the relevant media content. When not explicitly + set to `true` the server must return the media content itself. + example: false + schema: + type: boolean + default: false + requestBodies: + bytes: + content: + application/octet-stream: + example: + description: The content to be uploaded. + required: true + responses: + uploadTooLarge: + description: The uploaded content is too large for the server. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Cannot upload files larger than 100mb" + } + rateLimited: + description: This request was rate-limited. + content: + application/json: + schema: + $ref: definitions/errors/rate_limited.yaml + notYetUploaded: + description: |- + The content is not yet available. A [standard error response](/client-server-api/#standard-error-response) + will be returned with the `errcode` `M_NOT_YET_UPLOADED`. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_NOT_YET_UPLOADED", + "error": "Content has not yet been uploaded" + } + downloadRedirect: + description: A redirect to the requested content. + headers: + Location: + description: The URL of the content. + schema: + type: string + format: uri + downloadTooLarge: + description: The content is too large for the server to serve. + content: + application/json: + schema: + $ref: definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to serve" + } + thumbnailRedirect: + description: A redirect to the thumbnail of the requested content. + headers: + Location: + description: The URL of the thumbnail content. + schema: + type: string + format: uri + headers: + downloadContentType: + description: The content type of the file that was previously uploaded. + schema: + type: string + From c998b8a0183c6b4489bdfb35e734ca9b0f6d3e05 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:53:46 -0600 Subject: [PATCH 06/21] C2S: Drop `/upload` and `/create` because we aren't replacing them today --- .../client-server/authed-content-repo.yaml | 231 ------------------ 1 file changed, 231 deletions(-) diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml index e8691a4ab..fe0ae7f06 100644 --- a/data/api/client-server/authed-content-repo.yaml +++ b/data/api/client-server/authed-content-repo.yaml @@ -17,204 +17,6 @@ info: title: Matrix Client-Server Content Repository API version: 1.0.0 paths: - /media/v3/upload: - post: - summary: Upload some content to the content repository. - operationId: uploadContent - security: - - accessTokenQuery: [] - - accessTokenBearer: [] - parameters: - - $ref: '#/components/parameters/contentType' - - $ref: '#/components/parameters/filename' - requestBody: - $ref: '#/components/requestBodies/bytes' - responses: - "200": - description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for - the uploaded content. - content: - application/json: - schema: - type: object - required: - - content_uri - properties: - content_uri: - type: string - format: mx-mxc-uri - pattern: "^mxc:\\/\\/" - description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) to - the uploaded content. - examples: - response: - value: { - "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw" - } - "403": - description: |- - The user does not have permission to upload the content. Some reasons for this error include: - - - The server does not permit the file type. - - The user has reached a quota for uploaded content. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_FORBIDDEN", - "error": "Cannot upload this content" - } - "413": - $ref: '#/components/responses/uploadTooLarge' - "429": - $ref: '#/components/responses/rateLimited' - tags: - - Media - "/media/v3/upload/{serverName}/{mediaId}": - put: - summary: Upload content to an `mxc://` URI that was created earlier. - description: |- - This endpoint permits uploading content to an `mxc://` URI that was created - earlier via [POST /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create). - operationId: uploadContentToMXC - x-addedInMatrixVersion: "1.7" - parameters: - - $ref: '#/components/parameters/serverName' - description: | - The server name from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the authority component). - - $ref: '#/components/parameters/mediaId' - description: | - The media ID from the `mxc://` URI returned by `POST /_matrix/media/v1/create` (the path component). - - $ref: '#/components/parameters/contentType' - - $ref: '#/components/parameters/filename' - requestBody: - $ref: '#/components/requestBodies/bytes' - responses: - "200": - description: The upload was successful. - content: - application/json: - schema: - type: object - examples: - response: - value: {} - "403": - description: |- - The user does not have permission to upload the content. Some reasons for this error include: - - - The server does not permit the file type. - - The user has reached a quota for uploaded content. - - The request comes from a different user than the one that called - [POST /_matrix/media/v1/create](/client-server-api/#post_matrixmediav1create). - - A [standard error response](/client-server-api/#standard-error-response) - will be returned with the `errcode` `M_FORBIDDEN`. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_FORBIDDEN", - "error": "Cannot upload this content" - } - "409": - description: |- - The endpoint was called with a media ID that already has content. A - [standard error response](/client-server-api/#standard-error-response) - will be returned with the `errcode` `M_CANNOT_OVERWRITE_MEDIA`. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_CANNOT_OVERWRITE_MEDIA", - "error": "Media already uploaded" - } - "413": - $ref: '#/components/responses/uploadTooLarge' - "429": - $ref: '#/components/responses/rateLimited' - tags: - - Media - /media/v1/create: - post: - summary: Create a new `mxc://` URI without uploading the content. - description: |- - Creates a new `mxc://` URI, independently of the content being uploaded. The content must be provided later - via [`PUT /_matrix/media/v3/upload/{serverName}/{mediaId}`](/client-server-api/#put_matrixmediav3uploadservernamemediaid). - - The server may optionally enforce a maximum age for unused IDs, - and delete media IDs when the client doesn't start the upload in time, - or when the upload was interrupted and not resumed in time. The server - should include the maximum POSIX millisecond timestamp to complete the - upload in the `unused_expires_at` field in the response JSON. The - recommended default expiration is 24 hours which should be enough time - to accommodate users on poor connection who find a better connection to - complete the upload. - - As well as limiting the rate of requests to create `mxc://` URIs, the server - should limit the number of concurrent *pending media uploads* a given - user can have. A pending media upload is a created `mxc://` URI where (a) - the media has not yet been uploaded, and (b) has not yet expired (the - `unused_expires_at` timestamp has not yet passed). In both cases, the - server should respond with an HTTP 429 error with an errcode of - `M_LIMIT_EXCEEDED`. - operationId: createContent - x-addedInMatrixVersion: "1.7" - security: - - accessTokenQuery: [] - - accessTokenBearer: [] - # empty json object - responses: - "200": - description: The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) for - the uploaded content. - content: - application/json: - schema: - type: object - required: - - content_uri - properties: - content_uri: - type: string - format: mx-mxc-uri - pattern: "^mxc:\\/\\/" - description: |- - The [`mxc://` URI](/client-server-api/#matrix-content-mxc-uris) at - which the content will be available, once it is uploaded. - example: mxc://example.com/AQwafuaFswefuhsfAFAgsw - unused_expires_at: - type: integer - format: int64 - description: |- - The timestamp (in milliseconds since the unix epoch) when the - generated media id will expire, if media is not uploaded. - example: 1647257217083 - "403": - description: The user does not have permission to upload the content. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_FORBIDDEN", - "error": "Cannot upload this content" - } - "429": - $ref: '#/components/responses/rateLimited' - tags: - - Media "/media/v3/download/{serverName}/{mediaId}": get: deprecated: true @@ -589,20 +391,6 @@ components: accessTokenBearer: $ref: definitions/security.yaml#/accessTokenBearer parameters: - contentType: - in: header - name: Content-Type - description: The content type of the file being uploaded - example: application/pdf - schema: - type: string - filename: - in: query - name: filename - description: The name of the file being uploaded - example: War and Peace.pdf - schema: - type: string serverName: in: path name: serverName @@ -664,26 +452,7 @@ components: schema: type: boolean default: false - requestBodies: - bytes: - content: - application/octet-stream: - example: - description: The content to be uploaded. - required: true responses: - uploadTooLarge: - description: The uploaded content is too large for the server. - content: - application/json: - schema: - $ref: definitions/errors/error.yaml - examples: - response: - value: { - "errcode": "M_TOO_LARGE", - "error": "Cannot upload files larger than 100mb" - } rateLimited: description: This request was rate-limited. content: From a1e558b461f8b264a0ddc14477c1fea2acdc6b38 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:53:13 -0600 Subject: [PATCH 07/21] C2S: Fix notes while we're here --- data/api/client-server/authed-content-repo.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml index fe0ae7f06..6ea02a813 100644 --- a/data/api/client-server/authed-content-repo.yaml +++ b/data/api/client-server/authed-content-repo.yaml @@ -266,11 +266,12 @@ paths: Get information about a URL for the client. Typically this is called when a client sees a URL in a message and wants to render a preview for the user. - **Note:** + {{% boxes/note %}} Clients should consider avoiding this endpoint for URLs posted in encrypted rooms. Encrypted rooms often contain more sensitive information the users do not want to share with the homeserver, and this can mean that the URLs being shared should also not be shared with the homeserver. + {{% /boxes/note %}} operationId: getUrlPreview security: - accessTokenQuery: [] @@ -340,10 +341,12 @@ paths: All values are intentionally left optional. Clients SHOULD follow the advice given in the field description when the field is not available. - **NOTE:** Both clients and server administrators should be aware that proxies + {{% boxes/note %}} + Both clients and server administrators should be aware that proxies between the client and the server may affect the apparent behaviour of content repository APIs, for example, proxies may enforce a lower upload size limit than is advertised by the server on this endpoint. + {{% /boxes/note %}} operationId: getConfig security: - accessTokenQuery: [] From ce861df511530a2a1303eeac57f0bed148d2324c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 16:38:47 -0600 Subject: [PATCH 08/21] C2S: Update metadata for new endpoints --- .../client-server/authed-content-repo.yaml | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml index 6ea02a813..041218d82 100644 --- a/data/api/client-server/authed-content-repo.yaml +++ b/data/api/client-server/authed-content-repo.yaml @@ -1,5 +1,5 @@ # Copyright 2016 OpenMarket Ltd -# Copyright 2019 The Matrix.org Foundation C.I.C. +# Copyright 2019-2024 The Matrix.org Foundation C.I.C. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,14 +14,14 @@ # limitations under the License. openapi: 3.1.0 info: - title: Matrix Client-Server Content Repository API + title: Matrix Client-Server (Authenticated) Content Repository API version: 1.0.0 paths: - "/media/v3/download/{serverName}/{mediaId}": + "/media/download/{serverName}/{mediaId}": get: - deprecated: true + x-addedInMatrixVersion: "1.11" summary: Download content from the content repository. - operationId: getContent + operationId: getContentAuthed parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' @@ -55,15 +55,15 @@ paths: $ref: '#/components/responses/notYetUploaded' tags: - Media - "/media/v3/download/{serverName}/{mediaId}/{fileName}": + "/media/download/{serverName}/{mediaId}/{fileName}": get: - deprecated: true + x-addedInMatrixVersion: "1.11" summary: Download content from the content repository overriding the file name description: |- This will download content from the content repository (same as the previous endpoint) but replace the target file name with the one provided by the caller. - operationId: getContentOverrideName + operationId: getContentOverrideNameAuthed parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' @@ -106,14 +106,14 @@ paths: $ref: '#/components/responses/notYetUploaded' tags: - Media - "/media/v3/thumbnail/{serverName}/{mediaId}": + "/media/thumbnail/{serverName}/{mediaId}": get: - deprecated: true + x-addedInMatrixVersion: "1.11" summary: Download a thumbnail of content from the content repository description: |- Download a thumbnail of content from the content repository. See the [Thumbnails](/client-server-api/#thumbnails) section for more information. - operationId: getContentThumbnail + operationId: getContentThumbnailAuthed parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' @@ -258,9 +258,9 @@ paths: $ref: '#/components/responses/notYetUploaded' tags: - Media - /media/v3/preview_url: + /media/preview_url: get: - deprecated: true + x-addedInMatrixVersion: "1.11" summary: Get information about a URL for a client description: |- Get information about a URL for the client. Typically this is called when a @@ -272,7 +272,7 @@ paths: do not want to share with the homeserver, and this can mean that the URLs being shared should also not be shared with the homeserver. {{% /boxes/note %}} - operationId: getUrlPreview + operationId: getUrlPreviewAuthed security: - accessTokenQuery: [] - accessTokenBearer: [] @@ -330,9 +330,9 @@ paths: $ref: '#/components/responses/rateLimited' tags: - Media - /media/v3/config: + /media/config: get: - deprecated: true + x-addedInMatrixVersion: "1.11" summary: Get the configuration for the content repository. description: |- This endpoint allows clients to retrieve the configuration of the content @@ -347,7 +347,7 @@ paths: repository APIs, for example, proxies may enforce a lower upload size limit than is advertised by the server on this endpoint. {{% /boxes/note %}} - operationId: getConfig + operationId: getConfigAuthed security: - accessTokenQuery: [] - accessTokenBearer: [] @@ -386,7 +386,7 @@ servers: hostname: default: localhost:8008 basePath: - default: /_matrix + default: /_matrix/client/v1 components: securitySchemes: accessTokenQuery: From e7442b6bad9b241dc4dd0befb06e8ef4951e8a88 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:52:38 -0600 Subject: [PATCH 09/21] C2S: Add authentication to new endpoints --- .../client-server/authed-content-repo.yaml | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml index 041218d82..64361bbcf 100644 --- a/data/api/client-server/authed-content-repo.yaml +++ b/data/api/client-server/authed-content-repo.yaml @@ -21,7 +21,16 @@ paths: get: x-addedInMatrixVersion: "1.11" summary: Download content from the content repository. + description: |- + {{% boxes/note %}} + Clients SHOULD NOT generate or use URLs which supply the access token in + the query string. These URLs may be copied by users verbatim and provided + in a chat message to another user, disclosing the sender's access token. + {{% /boxes/note %}} operationId: getContentAuthed + security: + - accessTokenQuery: [] + - accessTokenBearer: [] parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' @@ -58,12 +67,21 @@ paths: "/media/download/{serverName}/{mediaId}/{fileName}": get: x-addedInMatrixVersion: "1.11" - summary: Download content from the content repository overriding the file name + summary: Download content from the content repository overriding the file name. description: |- This will download content from the content repository (same as - the previous endpoint) but replace the target file name with the one + the previous endpoint) but replaces the target file name with the one provided by the caller. + + {{% boxes/note %}} + Clients SHOULD NOT generate or use URLs which supply the access token in + the query string. These URLs may be copied by users verbatim and provided + in a chat message to another user, disclosing the sender's access token. + {{% /boxes/note %}} operationId: getContentOverrideNameAuthed + security: + - accessTokenQuery: [] + - accessTokenBearer: [] parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' @@ -113,7 +131,16 @@ paths: description: |- Download a thumbnail of content from the content repository. See the [Thumbnails](/client-server-api/#thumbnails) section for more information. + + {{% boxes/note %}} + Clients SHOULD NOT generate or use URLs which supply the access token in + the query string. These URLs may be copied by users verbatim and provided + in a chat message to another user, disclosing the sender's access token. + {{% /boxes/note %}} operationId: getContentThumbnailAuthed + security: + - accessTokenQuery: [] + - accessTokenBearer: [] parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' From 3e6ba8688920f9f7df528cafd4df071b4018ec11 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 15:53:03 -0600 Subject: [PATCH 10/21] C2S: Drop `allow_remote` and `allow_redirect` on new endpoints --- .../client-server/authed-content-repo.yaml | 45 +++++-------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/data/api/client-server/authed-content-repo.yaml b/data/api/client-server/authed-content-repo.yaml index 64361bbcf..9741d6183 100644 --- a/data/api/client-server/authed-content-repo.yaml +++ b/data/api/client-server/authed-content-repo.yaml @@ -27,6 +27,10 @@ paths: the query string. These URLs may be copied by users verbatim and provided in a chat message to another user, disclosing the sender's access token. {{% /boxes/note %}} + + Clients MAY be redirected using the 307/308 responses below to download + the request object. This is typical when the homeserver uses a Content + Delivery Network (CDN). operationId: getContentAuthed security: - accessTokenQuery: [] @@ -34,9 +38,7 @@ paths: parameters: - $ref: '#/components/parameters/serverName' - $ref: '#/components/parameters/mediaId' - - $ref: '#/components/parameters/allow_remote' - $ref: '#/components/parameters/timeout_ms' - - $ref: '#/components/parameters/allow_redirect' responses: "200": description: The content that was previously uploaded. @@ -78,6 +80,10 @@ paths: the query string. These URLs may be copied by users verbatim and provided in a chat message to another user, disclosing the sender's access token. {{% /boxes/note %}} + + Clients MAY be redirected using the 307/308 responses below to download + the request object. This is typical when the homeserver uses a Content + Delivery Network (CDN). operationId: getContentOverrideNameAuthed security: - accessTokenQuery: [] @@ -92,9 +98,7 @@ paths: example: filename.jpg schema: type: string - - $ref: '#/components/parameters/allow_remote' - $ref: '#/components/parameters/timeout_ms' - - $ref: '#/components/parameters/allow_redirect' responses: "200": description: The content that was previously uploaded. @@ -137,6 +141,10 @@ paths: the query string. These URLs may be copied by users verbatim and provided in a chat message to another user, disclosing the sender's access token. {{% /boxes/note %}} + + Clients MAY be redirected using the 307/308 responses below to download + the request object. This is typical when the homeserver uses a Content + Delivery Network (CDN). operationId: getContentThumbnailAuthed security: - accessTokenQuery: [] @@ -173,9 +181,7 @@ paths: enum: - crop - scale - - $ref: '#/components/parameters/allow_remote' - $ref: '#/components/parameters/timeout_ms' - - $ref: '#/components/parameters/allow_redirect' - in: query name: animated x-addedInMatrixVersion: "1.11" @@ -440,20 +446,6 @@ components: example: ascERGshawAWawugaAcauga schema: type: string - allow_remote: - in: query - name: allow_remote - required: false - description: |- - Indicates to the server that it should not attempt to fetch the media if - it is deemed remote. This is to prevent routing loops where the server - contacts itself. - - Defaults to `true` if not provided. - example: false - schema: - type: boolean - default: true timeout_ms: in: query name: timeout_ms @@ -469,19 +461,6 @@ components: type: integer format: int64 default: 20000 - allow_redirect: - in: query - name: allow_redirect - x-addedInMatrixVersion: "1.7" - required: false - description: | - Indicates to the server that it may return a 307 or 308 redirect - response that points at the relevant media content. When not explicitly - set to `true` the server must return the media content itself. - example: false - schema: - type: boolean - default: false responses: rateLimited: description: This request was rate-limited. From c33390f9f88203f9f523e5be25b4889097c80d7a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 16:26:31 -0600 Subject: [PATCH 11/21] C2S: Append backwards compatibility notes --- .../client-server-api/modules/content_repo.md | 29 ++++++++++++++++++- data/api/client-server/content-repo.yaml | 21 ++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 66ef86a1b..79e472d78 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -44,7 +44,7 @@ mxc:/// : An opaque ID which identifies the content. ``` -#### Client behaviour +#### Client behaviour {id="content-repo-client-behaviour"} Clients can access the content repository using the following endpoints. @@ -53,6 +53,33 @@ Clients can access the content repository using the following endpoints. described below. Instead, they SHOULD use the new endpoints which require authentication. {{% /boxes/added-in-paragraph %}} +{{% boxes/warning %}} +By Matrix 1.12, servers SHOULD "freeze" the deprecated, unauthenticated, endpoints +to prevent newly-uploaded media from being downloaded. This SHOULD mean that any +media uploaded *before* the freeze remains accessible via the deprecated endpoints, +and any media uploaded *after* (or *during*) the freeze SHOULD only be accessible +through the new, authenticated, endpoints. For remote media, "newly-uploaded" is +determined by the date the cache was populated. This may mean the media is older +than the freeze, but because the server had to re-download it, it is now considered +"new". + +Clients SHOULD update to support the authenticated endpoints before servers freeze +unauthenticated access. + +Servers SHOULD consider their local ecosystem impact before enacting a freeze. +This could mean ensuring their users' typical clients support the new endpoints +when available, or updating bridges to start using media proxies. + +An *example* timeline for a server may be: + +* Matrix 1.11 release: Clients begin supporting authenticated media. +* Matrix 1.12 release: Servers freeze unauthenticated media access. + * Media uploaded prior to this point still works with the deprecated endpoints. + * Newly uploaded (or cached) media *only* works on the authenticated endpoints. + +Matrix 1.12 is expected to be released in the July-September 2024 calendar quarter. +{{% /boxes/warning %}} + {{% http-api spec="client-server" api="authed-content-repo" %}} {{% http-api spec="client-server" api="content-repo" %}} diff --git a/data/api/client-server/content-repo.yaml b/data/api/client-server/content-repo.yaml index e8691a4ab..4b6ceff52 100644 --- a/data/api/client-server/content-repo.yaml +++ b/data/api/client-server/content-repo.yaml @@ -219,6 +219,13 @@ paths: get: deprecated: true summary: Download content from the content repository. + description: |- + {{% boxes/warning %}} + {{< changed-in v="1.11" >}} This endpoint MAY return `404 M_NOT_FOUND` + for media which exists, but is after the server froze unauthenticated + media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more + information. + {{% /boxes/warning %}} operationId: getContent parameters: - $ref: '#/components/parameters/serverName' @@ -261,6 +268,13 @@ paths: This will download content from the content repository (same as the previous endpoint) but replace the target file name with the one provided by the caller. + + {{% boxes/warning %}} + {{< changed-in v="1.11" >}} This endpoint MAY return `404 M_NOT_FOUND` + for media which exists, but is after the server froze unauthenticated + media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more + information. + {{% /boxes/warning %}} operationId: getContentOverrideName parameters: - $ref: '#/components/parameters/serverName' @@ -311,6 +325,13 @@ paths: description: |- Download a thumbnail of content from the content repository. See the [Thumbnails](/client-server-api/#thumbnails) section for more information. + + {{% boxes/warning %}} + {{< changed-in v="1.11" >}} This endpoint MAY return `404 M_NOT_FOUND` + for media which exists, but is after the server froze unauthenticated + media access. See [Client Behaviour](/client-server-api/#content-repo-client-behaviour) for more + information. + {{% /boxes/warning %}} operationId: getContentThumbnail parameters: - $ref: '#/components/parameters/serverName' From 3cef6f0479adf483d3b3da7aa1065404db67c103 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 16:35:10 -0600 Subject: [PATCH 12/21] C2S: Decorate old media endpoints with pointers to the new ones The server-server spec might have a harder time linking to these, but that can be fixed with verbiage. --- data/api/client-server/content-repo.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/data/api/client-server/content-repo.yaml b/data/api/client-server/content-repo.yaml index 4b6ceff52..1dac8b10d 100644 --- a/data/api/client-server/content-repo.yaml +++ b/data/api/client-server/content-repo.yaml @@ -220,6 +220,11 @@ paths: deprecated: true summary: Download content from the content repository. description: |- + {{% boxes/note %}} + Replaced by [`GET /_matrix/client/v1/media/download/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid) + (requires authentication). + {{% /boxes/note %}} + {{% boxes/warning %}} {{< changed-in v="1.11" >}} This endpoint MAY return `404 M_NOT_FOUND` for media which exists, but is after the server froze unauthenticated @@ -265,6 +270,11 @@ paths: deprecated: true summary: Download content from the content repository overriding the file name description: |- + {{% boxes/note %}} + Replaced by [`GET /_matrix/client/v1/media/download/{serverName}/{mediaId}/{fileName}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename) + (requires authentication). + {{% /boxes/note %}} + This will download content from the content repository (same as the previous endpoint) but replace the target file name with the one provided by the caller. @@ -323,6 +333,11 @@ paths: deprecated: true summary: Download a thumbnail of content from the content repository description: |- + {{% boxes/note %}} + Replaced by [`GET /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid) + (requires authentication). + {{% /boxes/note %}} + Download a thumbnail of content from the content repository. See the [Thumbnails](/client-server-api/#thumbnails) section for more information. @@ -482,6 +497,10 @@ paths: deprecated: true summary: Get information about a URL for a client description: |- + {{% boxes/note %}} + Replaced by [`GET /_matrix/client/v1/media/preview_url`](/client-server-api/#get_matrixclientv1mediapreview_url). + {{% /boxes/note %}} + Get information about a URL for the client. Typically this is called when a client sees a URL in a message and wants to render a preview for the user. @@ -553,6 +572,10 @@ paths: deprecated: true summary: Get the configuration for the content repository. description: |- + {{% boxes/note %}} + Replaced by [`GET /_matrix/client/v1/media/config`](/client-server-api/#get_matrixclientv1mediaconfig). + {{% /boxes/note %}} + This endpoint allows clients to retrieve the configuration of the content repository, such as upload limitations. Clients SHOULD use this as a guide when using content repository endpoints. From 0617aced7c4ea119e204983977fb5e8e061eac77 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 16:50:05 -0600 Subject: [PATCH 13/21] C2S: Annotate IdP icon spec with media auth implications --- .../client-server/definitions/sso_login_flow.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/data/api/client-server/definitions/sso_login_flow.yaml b/data/api/client-server/definitions/sso_login_flow.yaml index 3b95e6642..48f193bee 100644 --- a/data/api/client-server/definitions/sso_login_flow.yaml +++ b/data/api/client-server/definitions/sso_login_flow.yaml @@ -53,6 +53,18 @@ properties: description: |- Optional `mxc://` URI to provide an image/icon representing the IdP. Intended to be shown alongside the `name` if provided. + + {{% boxes/note %}} + Clients will need to use the deprecated [`/download`](/client-server-api/#get_matrixmediav3downloadservernamemediaid) + and [`/thumbnail`](/client-server-api/#get_matrixmediav3thumbnailservernamemediaid) + endpoints to retrieve this media item because clients will not have + an access token they can authenticate with yet. Servers SHOULD ensure + media used for IdP icons is excluded from the freeze described by the + [Content Repository module's Client Behaviour section](/client-server-api/#content-repo-client-behaviour). + + This may be addressed in the future with proposals like [MSC4148](https://github.com/matrix-org/matrix-spec-proposals/pull/4148), + or removed entirely through the transition to OIDC. + {{% /boxes/note %}} example: "mxc://example.org/abc123" brand: type: string From 1621eccd2f162bb501e5169da8158fab209bdeef Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 17:47:20 -0600 Subject: [PATCH 14/21] S2S: Modernize section text --- content/server-server-api.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/content/server-server-api.md b/content/server-server-api.md index e92d871c5..03a26e886 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -1189,15 +1189,26 @@ using the following EDU: Attachments to events (images, files, etc) are uploaded to a homeserver via the Content Repository described in the [Client-Server -API](/client-server-api). When a server wishes +API](/client-server-api/#content-repository). When a server wishes to serve content originating from a remote server, it needs to ask the remote server for the media. -Servers should use the server described in the Matrix Content URI, which -has the format `mxc://{ServerName}/{MediaID}`. Servers should use the -download endpoint described in the [Client-Server -API](/client-server-api), being sure to use -the `allow_remote` parameter (set to `false`). +Servers should use the server described in the [Matrix Content URI](/client-server-api/#matrix-content-mxc-uris). +Formatted as `mxc://{ServerName}/{MediaID}`, servers MUST download the media from +`ServerName` using the below endpoints. + +{{% boxes/added-in-paragraph %}} +{{< changed-in v="1.11" >}} Servers were previously advised to use the `/_matrix/media/*` +endpoints described by the [Content Repository module in the Client-Server API](/client-server-api/#content-repository), +however, those endpoints have been deprecated. New endpoints are introduced which +require authentication. Naturally, as a server is not a user, they cannot provide +the required access token to those endpoints. Instead, servers MUST try the endpoints +described below before falling back to the deprecated `/_matrix/media/*` endpoints +when they receive a `404 M_UNRECOGNIZED` error. When falling back, servers MUST +be sure to set `allow_remote` to `false`. +{{% /boxes/added-in-paragraph %}} + +{{% http-api spec="server-server" api="content_repository" %}} ## Server Access Control Lists (ACLs) From 72c09444e9b3a91656f0431d510a3b1a71f09183 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 17:49:12 -0600 Subject: [PATCH 15/21] S2S: Create content repository API This is largely a copy/paste of the new authed content repo API in the Client-Server API, though some keywords (like "client") have been changed. Paths and response formats have also been changed to support the federation-specific requirements. --- .../api/server-server/content_repository.yaml | 293 ++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 data/api/server-server/content_repository.yaml diff --git a/data/api/server-server/content_repository.yaml b/data/api/server-server/content_repository.yaml new file mode 100644 index 000000000..89b9d1382 --- /dev/null +++ b/data/api/server-server/content_repository.yaml @@ -0,0 +1,293 @@ +# Copyright 2024 The Matrix.org Foundation C.I.C. +# +# 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. +openapi: 3.1.0 +info: + title: Matrix Federation Content Repository API + version: 1.0.0 +paths: + "/media/download/{mediaId}": + get: + x-addedInMatrixVersion: "1.11" + summary: Download content from the content repository. + operationId: getContent + security: + - signedRequest: [] + parameters: + - $ref: '#/components/parameters/mediaId' + - $ref: '#/components/parameters/timeout_ms' + responses: + "200": + description: The content that was previously uploaded. + headers: + Content-Type: + $ref: '#/components/headers/downloadContentType' + content: + multipart/mixed: + schema: + # This is a workaround for us not being able to say the response is required. + description: |- + **Required.** MUST contain a `boundary` delineating exactly two + parts: + + The first part has a `Content-Type` header of `application/json` + and describes the media's metadata, if any. Currently, this will + always be an empty object. + + The second part is either: + + 1. the bytes of the media itself, using `Content-Type` and + `Content-Disposition` headers as appropriate; + 2. or a `Location` header to redirect the caller to where the media + can be retrieved. The URL at `Location` SHOULD have appropriate + `Content-Type` and `Content-Disposition` headers which describe + the media. + "429": + $ref: '#/components/responses/rateLimited' + "502": + description: The content is too large for the server to serve. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to serve" + } + "504": + $ref: '#/components/responses/notYetUploaded' + tags: + - Media + "/media/thumbnail/{mediaId}": + get: + x-addedInMatrixVersion: "1.11" + summary: Download a thumbnail of content from the content repository + description: |- + Download a thumbnail of content from the content repository. + See the [Client-Server API Thumbnails](/client-server-api/#thumbnails) + section for more information. + operationId: getContentThumbnail + security: + - signedRequest: [] + parameters: + - $ref: '#/components/parameters/mediaId' + - in: query + name: width + required: true + description: |- + The *desired* width of the thumbnail. The actual thumbnail may be + larger than the size specified. + example: 64 + schema: + type: integer + - in: query + name: height + required: true + description: |- + The *desired* height of the thumbnail. The actual thumbnail may be + larger than the size specified. + example: 64 + schema: + type: integer + - in: query + name: method + description: |- + The desired resizing method. See the [Client-Server API Thumbnails](/client-server-api/#thumbnails) + section for more information. + example: scale + schema: + type: string + enum: + - crop + - scale + - $ref: '#/components/parameters/timeout_ms' + - in: query + name: animated + x-addedInMatrixVersion: "1.11" + required: false + description: | + Indicates preference for an animated thumbnail from the server, if possible. Animated + thumbnails typically use the content types `image/gif`, `image/png` (with APNG format), + `image/apng`, and `image/webp` instead of the common static `image/png` or `image/jpeg` + content types. + + When `true`, the server SHOULD return an animated thumbnail if possible and supported. + When `false`, the server MUST NOT return an animated thumbnail. For example, returning a + static `image/png` or `image/jpeg` thumbnail. When not provided, the server SHOULD NOT + return an animated thumbnail. + + Servers SHOULD prefer to return `image/webp` thumbnails when supporting animation. + + When `true` and the media cannot be animated, such as in the case of a JPEG or PDF, the + server should behave as though `animated` is `false`. + example: false + schema: + type: boolean + responses: + "200": + description: A thumbnail of the requested content. + headers: + Content-Type: + description: Must be `multipart/mixed`. + schema: + type: string + content: + multipart/mixed: + schema: + # This is a workaround for us not being able to say the response is required. + description: |- + **Required.** MUST contain a `boundary` delineating exactly two + parts: + + The first part has a `Content-Type` header of `application/json` + and describes the media's metadata, if any. Currently, this will + always be an empty object. + + The second part is either: + + 1. the bytes of the media itself, using `Content-Type` and + `Content-Disposition` headers as appropriate; + 2. or a `Location` header to redirect the caller to where the media + can be retrieved. The URL at `Location` SHOULD have appropriate + `Content-Type` and `Content-Disposition` headers which describe + the media. + + {{% boxes/note %}} + The `Content-Type` for the second part SHOULD be one of: + * `image/png` (possibly of the APNG variety) + * `image/apng` + * `image/jpeg` + * `image/gif` + * `image/webp` + {{% /boxes/note %}} + "400": + description: |- + The request does not make sense to the server, or the server cannot thumbnail + the content. For example, the caller requested non-integer dimensions or asked + for negatively-sized images. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_UNKNOWN", + "error": "Cannot generate thumbnails for the requested content" + } + "413": + description: The local content is too large for the server to thumbnail. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + "429": + $ref: '#/components/responses/rateLimited' + "502": + description: The remote content is too large for the server to thumbnail. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_TOO_LARGE", + "error": "Content is too large to thumbnail" + } + "504": + $ref: '#/components/responses/notYetUploaded' + tags: + - Media +servers: + - url: "{protocol}://{hostname}{basePath}" + variables: + protocol: + enum: + - http + - https + default: https + hostname: + default: localhost:8448 + basePath: + default: /_matrix/federation/v1 +components: + securitySchemes: + signedRequest: + $ref: definitions/security.yaml#/signedRequest + parameters: + mediaId: + in: path + name: mediaId + required: true + description: | + The media ID from the `mxc://` URI (the path component). + example: ascERGshawAWawugaAcauga + schema: + type: string + timeout_ms: + in: query + name: timeout_ms + x-addedInMatrixVersion: "1.7" + description: | + The maximum number of milliseconds that the client is willing to wait to + start receiving data, in the case that the content has not yet been + uploaded. The default value is 20000 (20 seconds). The content + repository can and should impose a maximum value for this parameter. The + content repository may also choose to respond before the timeout. + example: 5000 + schema: + type: integer + format: int64 + default: 20000 + responses: + rateLimited: + description: This request was rate-limited. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/rate_limited.yaml + notYetUploaded: + description: |- + The content is not yet available. A [standard error response](/client-server-api/#standard-error-response) + will be returned with the `errcode` `M_NOT_YET_UPLOADED`. + content: + application/json: + schema: + # XXX: We should move error definitions into a more generic place. + $ref: ../client-server/definitions/errors/error.yaml + examples: + response: + value: { + "errcode": "M_NOT_YET_UPLOADED", + "error": "Content has not yet been uploaded" + } + headers: + downloadContentType: + description: |- + Must be `multipart/mixed`. + schema: + type: string From 70e70cbda9bbb3ed48748a8d3ef3751a17b7f334 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 10 Jun 2024 18:01:49 -0600 Subject: [PATCH 16/21] C2S & S2S: Add plethora of changelogs --- changelogs/client_server/newsfragments/1858.deprecation | 1 + changelogs/client_server/newsfragments/1858.feature.1 | 1 + changelogs/client_server/newsfragments/1858.feature.2 | 1 + changelogs/client_server/newsfragments/1858.new.1 | 1 + changelogs/client_server/newsfragments/1858.new.2 | 1 + changelogs/client_server/newsfragments/1858.new.3 | 1 + changelogs/client_server/newsfragments/1858.new.4 | 1 + changelogs/client_server/newsfragments/1858.new.5 | 1 + changelogs/server_server/newsfragments/1858.deprecation | 1 + changelogs/server_server/newsfragments/1858.feature | 1 + changelogs/server_server/newsfragments/1858.new.1 | 1 + changelogs/server_server/newsfragments/1858.new.2 | 1 + 12 files changed, 12 insertions(+) create mode 100644 changelogs/client_server/newsfragments/1858.deprecation create mode 100644 changelogs/client_server/newsfragments/1858.feature.1 create mode 100644 changelogs/client_server/newsfragments/1858.feature.2 create mode 100644 changelogs/client_server/newsfragments/1858.new.1 create mode 100644 changelogs/client_server/newsfragments/1858.new.2 create mode 100644 changelogs/client_server/newsfragments/1858.new.3 create mode 100644 changelogs/client_server/newsfragments/1858.new.4 create mode 100644 changelogs/client_server/newsfragments/1858.new.5 create mode 100644 changelogs/server_server/newsfragments/1858.deprecation create mode 100644 changelogs/server_server/newsfragments/1858.feature create mode 100644 changelogs/server_server/newsfragments/1858.new.1 create mode 100644 changelogs/server_server/newsfragments/1858.new.2 diff --git a/changelogs/client_server/newsfragments/1858.deprecation b/changelogs/client_server/newsfragments/1858.deprecation new file mode 100644 index 000000000..6e93dca58 --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.deprecation @@ -0,0 +1 @@ +Use of the `/_matrix/media/*` endpoints is now deprecated. New, authenticated, endpoints are available instead. \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.feature.1 b/changelogs/client_server/newsfragments/1858.feature.1 new file mode 100644 index 000000000..02b9b51ed --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.feature.1 @@ -0,0 +1 @@ +Media downloads and thumbnails are now authenticated, as per [MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.feature.2 b/changelogs/client_server/newsfragments/1858.feature.2 new file mode 100644 index 000000000..63dfbb787 --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.feature.2 @@ -0,0 +1 @@ +Some media endpoints are now consistently under `/_matrix/client/{version}/media/*` instead of `/_matrix/media/*`, as per [MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916). \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.new.1 b/changelogs/client_server/newsfragments/1858.new.1 new file mode 100644 index 000000000..9d02447f7 --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.new.1 @@ -0,0 +1 @@ +[`GET /_matrix/client/v1/media/config`](/client-server-api/#get_matrixclientv1mediaconfig) \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.new.2 b/changelogs/client_server/newsfragments/1858.new.2 new file mode 100644 index 000000000..07e7763ae --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.new.2 @@ -0,0 +1 @@ +[`GET /_matrix/client/v1/media/download/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid) \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.new.3 b/changelogs/client_server/newsfragments/1858.new.3 new file mode 100644 index 000000000..49b67f049 --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.new.3 @@ -0,0 +1 @@ +[`GET /_matrix/client/v1/media/download/{serverName}/{mediaId}/{fileName}`](/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename) \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.new.4 b/changelogs/client_server/newsfragments/1858.new.4 new file mode 100644 index 000000000..dda53b330 --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.new.4 @@ -0,0 +1 @@ +[`GET /_matrix/client/v1/media/preview_url`](/client-server-api/#get_matrixclientv1mediapreview_url) \ No newline at end of file diff --git a/changelogs/client_server/newsfragments/1858.new.5 b/changelogs/client_server/newsfragments/1858.new.5 new file mode 100644 index 000000000..021b4023d --- /dev/null +++ b/changelogs/client_server/newsfragments/1858.new.5 @@ -0,0 +1 @@ +[`GET /_matrix/client/v1/media/thumbnail/{serverName}/{mediaId}`](/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid) \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1858.deprecation b/changelogs/server_server/newsfragments/1858.deprecation new file mode 100644 index 000000000..fd3d25765 --- /dev/null +++ b/changelogs/server_server/newsfragments/1858.deprecation @@ -0,0 +1 @@ +Use of the Client-Server API `/_matrix/media/*` endpoints is now deprecated. New, authenticated, endpoints are available instead. \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1858.feature b/changelogs/server_server/newsfragments/1858.feature new file mode 100644 index 000000000..02b9b51ed --- /dev/null +++ b/changelogs/server_server/newsfragments/1858.feature @@ -0,0 +1 @@ +Media downloads and thumbnails are now authenticated, as per [MSC3916](https://github.com/matrix-org/matrix-spec-proposals/pull/3916). \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1858.new.1 b/changelogs/server_server/newsfragments/1858.new.1 new file mode 100644 index 000000000..e50d5fd18 --- /dev/null +++ b/changelogs/server_server/newsfragments/1858.new.1 @@ -0,0 +1 @@ +[`GET /_matrix/federation/v1/media/download/{mediaId}`](/server-server-api/#get_matrixfederationv1mediadownloadmediaid) \ No newline at end of file diff --git a/changelogs/server_server/newsfragments/1858.new.2 b/changelogs/server_server/newsfragments/1858.new.2 new file mode 100644 index 000000000..1da2a693f --- /dev/null +++ b/changelogs/server_server/newsfragments/1858.new.2 @@ -0,0 +1 @@ +[`GET /_matrix/federation/v1/media/thumbnail/{mediaId}`](/server-server-api/#get_matrixfederationv1mediathumbnailmediaid) \ No newline at end of file From c7522a61469aad277c0f5c54d35a995b6124d546 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2024 16:13:15 -0600 Subject: [PATCH 17/21] Reference RFC 1341 --- data/api/server-server/content_repository.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/api/server-server/content_repository.yaml b/data/api/server-server/content_repository.yaml index 89b9d1382..02b367dfe 100644 --- a/data/api/server-server/content_repository.yaml +++ b/data/api/server-server/content_repository.yaml @@ -37,8 +37,8 @@ paths: schema: # This is a workaround for us not being able to say the response is required. description: |- - **Required.** MUST contain a `boundary` delineating exactly two - parts: + **Required.** MUST contain a `boundary` (per [RFC 1341](https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html)) + delineating exactly two parts: The first part has a `Content-Type` header of `application/json` and describes the media's metadata, if any. Currently, this will @@ -149,8 +149,8 @@ paths: schema: # This is a workaround for us not being able to say the response is required. description: |- - **Required.** MUST contain a `boundary` delineating exactly two - parts: + **Required.** MUST contain a `boundary` (per [RFC 1341](https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html)) + delineating exactly two parts: The first part has a `Content-Type` header of `application/json` and describes the media's metadata, if any. Currently, this will From 290e6a28778d9a974e1cf687bcba108f5eb3caf6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2024 16:13:54 -0600 Subject: [PATCH 18/21] Upgrade keywords in changed text --- content/server-server-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/server-server-api.md b/content/server-server-api.md index 03a26e886..82c407344 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -1193,7 +1193,7 @@ API](/client-server-api/#content-repository). When a server wishes to serve content originating from a remote server, it needs to ask the remote server for the media. -Servers should use the server described in the [Matrix Content URI](/client-server-api/#matrix-content-mxc-uris). +Servers MUST use the server described in the [Matrix Content URI](/client-server-api/#matrix-content-mxc-uris). Formatted as `mxc://{ServerName}/{MediaID}`, servers MUST download the media from `ServerName` using the below endpoints. From bc93c9a93cb386010ced1ed6cb5c518c402f6bc3 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2024 16:15:58 -0600 Subject: [PATCH 19/21] Mention caching --- data/api/server-server/content_repository.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/data/api/server-server/content_repository.yaml b/data/api/server-server/content_repository.yaml index 02b367dfe..6c19d6ec9 100644 --- a/data/api/server-server/content_repository.yaml +++ b/data/api/server-server/content_repository.yaml @@ -52,6 +52,11 @@ paths: can be retrieved. The URL at `Location` SHOULD have appropriate `Content-Type` and `Content-Disposition` headers which describe the media. + + When `Location` is present, servers SHOULD NOT cache the URL. + The remote server may have applied time limits on its validity. + If the caller requires an up-to-date URL, it SHOULD re-request + the media download. "429": $ref: '#/components/responses/rateLimited' "502": @@ -165,6 +170,11 @@ paths: `Content-Type` and `Content-Disposition` headers which describe the media. + When `Location` is present, servers SHOULD NOT cache the URL. + The remote server may have applied time limits on its validity. + If the caller requires an up-to-date URL, it SHOULD re-request + the media download. + {{% boxes/note %}} The `Content-Type` for the second part SHOULD be one of: * `image/png` (possibly of the APNG variety) From aa54db138ac6ec4c0187e4d52281f60b2b2162bd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 11 Jun 2024 16:27:04 -0600 Subject: [PATCH 20/21] Cross-reference IdP icons --- content/client-server-api/modules/content_repo.md | 3 +++ data/api/client-server/definitions/sso_login_flow.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 79e472d78..2649b6884 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -70,6 +70,9 @@ Servers SHOULD consider their local ecosystem impact before enacting a freeze. This could mean ensuring their users' typical clients support the new endpoints when available, or updating bridges to start using media proxies. +In addition to the above, servers SHOULD exclude [IdP icons used in the `m.login.sso` flow](/client-server-api/#definition-mloginsso-flow-schema) +from the freeze. See the `m.login.sso` flow schema for details. + An *example* timeline for a server may be: * Matrix 1.11 release: Clients begin supporting authenticated media. diff --git a/data/api/client-server/definitions/sso_login_flow.yaml b/data/api/client-server/definitions/sso_login_flow.yaml index 48f193bee..0996511eb 100644 --- a/data/api/client-server/definitions/sso_login_flow.yaml +++ b/data/api/client-server/definitions/sso_login_flow.yaml @@ -55,7 +55,7 @@ properties: Intended to be shown alongside the `name` if provided. {{% boxes/note %}} - Clients will need to use the deprecated [`/download`](/client-server-api/#get_matrixmediav3downloadservernamemediaid) + Clients SHOULD use the deprecated [`/download`](/client-server-api/#get_matrixmediav3downloadservernamemediaid) and [`/thumbnail`](/client-server-api/#get_matrixmediav3thumbnailservernamemediaid) endpoints to retrieve this media item because clients will not have an access token they can authenticate with yet. Servers SHOULD ensure From b73ef14dc5c97d81376ba10edd59e7ea30ef5f14 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 13 Jun 2024 12:07:03 -0600 Subject: [PATCH 21/21] Update content/client-server-api/modules/content_repo.md --- content/client-server-api/modules/content_repo.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/content_repo.md b/content/client-server-api/modules/content_repo.md index 2649b6884..a01381561 100644 --- a/content/client-server-api/modules/content_repo.md +++ b/content/client-server-api/modules/content_repo.md @@ -25,8 +25,8 @@ interacting with the media repository. {{% boxes/added-in-paragraph %}} {{< changed-in v="1.11" >}} The unauthenticated download endpoints have been -deprecated in favour of newer, authenticated, ones. This change included updating -the pathing of all media endpoints from `/_matrix/media/*` to `/_matrix/client/{version}/media/*`, +deprecated in favour of newer, authenticated, ones. This change includes updating +the paths of all media endpoints from `/_matrix/media/*` to `/_matrix/client/{version}/media/*`, with the exception of the `/upload` and `/create` endpoints. The upload/create endpoints are expected to undergo a similar transition in a later version of the specification.