From 358ac5e119f0bcc80abf869546505b341c666d60 Mon Sep 17 00:00:00 2001 From: Nick Barrett Date: Wed, 17 Aug 2022 10:41:09 +0100 Subject: [PATCH 1/7] Add empty draft --- proposals/xxx-media-async-upload-url.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 proposals/xxx-media-async-upload-url.md diff --git a/proposals/xxx-media-async-upload-url.md b/proposals/xxx-media-async-upload-url.md new file mode 100644 index 00000000000..7f76689935f --- /dev/null +++ b/proposals/xxx-media-async-upload-url.md @@ -0,0 +1,3 @@ +# MSCXXX: Media Async Upload URL + +Draft: extension on async uploads to return a URL to upload direct to in the create media response. Ex. an S3 presigned URL. From 78d87294ba468f75b79d31a4ada7ea0db7ad8419 Mon Sep 17 00:00:00 2001 From: Nick Barrett Date: Wed, 17 Aug 2022 13:14:23 +0100 Subject: [PATCH 2/7] Write up initial draft of MSC3870 --- proposals/3870-media-async-upload-url.md | 63 ++++++++++++++++++++++++ proposals/xxx-media-async-upload-url.md | 3 -- 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 proposals/3870-media-async-upload-url.md delete mode 100644 proposals/xxx-media-async-upload-url.md diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md new file mode 100644 index 00000000000..a668728bbac --- /dev/null +++ b/proposals/3870-media-async-upload-url.md @@ -0,0 +1,63 @@ +# MSC3870: Async media upload extension: upload to URL + +This MSC proposes an extension to [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246) +(async media uploads) that allows a media server to give clients a URL to use for uploading media +data after the MXID is created. + +The rationale behind this is to enable clients to upload direct to the backing datastore, for example +by using [S3 presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html) +and/or [S3 transfer acceleration](https://docs.aws.amazon.com/AmazonS3/latest/userguide/transfer-acceleration-getting-started.html) +(this is not limited to S3, just well documented by AWS). By enabling clients to upload to a different +URL server owners could improve upload performance significantly by using a CDN with closer Points +of Presence to their users than the homeserver itself. + +When combined with [MSC3860](https://github.com/matrix-org/matrix-spec-proposals/pull/3860) (media +download redirect URLs) this makes it possible to run a "lean" media server that orchestrates where +media is uploaded to and downloaded from but does not directly handle much media itself. Note this +doesn't include thubmnails or URL previews which would still go through the media server. + + +## Proposal + +The proposal modifies the MSC2246 create endpoint to optionally include a URL that a compatible +client may use to upload the content for the created MXID. This is considered optional and the +client may continue to upload via the new upload endpoint defined in MSC2246. + +`POST /_matrix/media/v3/create` + +**Example response** + +```json +{ + "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw", + "unused_expires_at": 1647257217083, + "upload_url": "https://cdn.example.com/media-repo/upload/XAPw4CtrzArk?signed=h4tGOHvCu" +} +``` + +If the client chooses to upload media via the `upload_url` field, the media server must implement +it's own methods of detecting when an upload is complete if desired (eg. thumbnailing or spam +detection). + +**Alternative**: a new endpoint that clients `POST` to after uploading media to the `upload_url` +used to notify the media server. However in the case of spam detection this makes it possible for +bad acting clients to bypass spam detection for media uploads. This means any server side only +detection is necessary anyway making the client endpoint redundant. + + +## Alternatives + +### Run the whole homeserver behind CDN + +Server owners could run their own Points of Presence to receive and handle media content and pass +through any non-media requests to a central homeserver (or run a distributed homeserver if/when +that exists). There is a significant cost (management time & infrastructure) associated with this. + + +## Security Considerations + +Security of presigned URL uploads is well documented but important to be aware of when implementing +support for this. + + +## Unstable Prefix diff --git a/proposals/xxx-media-async-upload-url.md b/proposals/xxx-media-async-upload-url.md deleted file mode 100644 index 7f76689935f..00000000000 --- a/proposals/xxx-media-async-upload-url.md +++ /dev/null @@ -1,3 +0,0 @@ -# MSCXXX: Media Async Upload URL - -Draft: extension on async uploads to return a URL to upload direct to in the create media response. Ex. an S3 presigned URL. From 0c4c9d6a2a1784d8d2de90bbe5a62da9429731c7 Mon Sep 17 00:00:00 2001 From: Nick Barrett Date: Wed, 31 Aug 2022 15:31:48 +0100 Subject: [PATCH 3/7] Add unstable prefix --- proposals/3870-media-async-upload-url.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md index a668728bbac..13369452bc5 100644 --- a/proposals/3870-media-async-upload-url.md +++ b/proposals/3870-media-async-upload-url.md @@ -61,3 +61,10 @@ support for this. ## Unstable Prefix + +While this MSC is not in a released version of the spec, implementations should use `com.beeper.msc3880` +as a prefix and as an unstable_features flag in the /versions endpoint. + +``` + POST /_matrix/media/unstable/com.beeper.msc3870/upload/{serverName}/{mediaId}/complete +``` From ba15fa9fc5f2d2e70258567e563714585006f057 Mon Sep 17 00:00:00 2001 From: Nick Barrett Date: Wed, 31 Aug 2022 15:32:27 +0100 Subject: [PATCH 4/7] Add upload complete endpoint and explicit define for how upload requests work --- proposals/3870-media-async-upload-url.md | 33 ++++++++++++++++++------ 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md index 13369452bc5..9caab840c50 100644 --- a/proposals/3870-media-async-upload-url.md +++ b/proposals/3870-media-async-upload-url.md @@ -35,14 +35,31 @@ client may continue to upload via the new upload endpoint defined in MSC2246. } ``` -If the client chooses to upload media via the `upload_url` field, the media server must implement -it's own methods of detecting when an upload is complete if desired (eg. thumbnailing or spam -detection). - -**Alternative**: a new endpoint that clients `POST` to after uploading media to the `upload_url` -used to notify the media server. However in the case of spam detection this makes it possible for -bad acting clients to bypass spam detection for media uploads. This means any server side only -detection is necessary anyway making the client endpoint redundant. +If the client chooses to upload media via the `upload_url` field it must use a `PUT` request, in this +case: + +`PUT https://cdn.example.com/media-repo/upload/XAPw4CtrzArk?signed=h4tGOHvCu` + +The response to the upload is implementation specific depending on the target server, the client +should interpret standard HTTP responses, a 200 or 201 indicating successful upload. Once the upload +is complete, the client must notify the media server via a new endpoint: + +`POST /_matrix/media/v3/upload/{serverName}/{mediaId}/complete` + +**Example response** + +```json +{ + "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw" +} +``` + +This allows the media server to perform any post-upload actions before either allowing the media +to be downloaded (and returning the URI to the client as above) or rejecting the upload. + +This means that there is potential for a client to send an event referencing an MXC that is then +uploaded and rejected. Note that this is also a problem MSC2246 faces, whatever solution applies +there can be applied here. ## Alternatives From af3d0fcb8dbbd9e2faf179f6e157a00d1c797d41 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Sat, 10 Aug 2024 13:53:24 +0100 Subject: [PATCH 5/7] Use correct API versions --- proposals/3870-media-async-upload-url.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md index 9caab840c50..4ff45a33f7a 100644 --- a/proposals/3870-media-async-upload-url.md +++ b/proposals/3870-media-async-upload-url.md @@ -23,7 +23,7 @@ The proposal modifies the MSC2246 create endpoint to optionally include a URL th client may use to upload the content for the created MXID. This is considered optional and the client may continue to upload via the new upload endpoint defined in MSC2246. -`POST /_matrix/media/v3/create` +`POST /_matrix/media/v1/create` **Example response** @@ -44,7 +44,7 @@ The response to the upload is implementation specific depending on the target se should interpret standard HTTP responses, a 200 or 201 indicating successful upload. Once the upload is complete, the client must notify the media server via a new endpoint: -`POST /_matrix/media/v3/upload/{serverName}/{mediaId}/complete` +`POST /_matrix/media/v1/upload/{serverName}/{mediaId}/complete` **Example response** From 3c9e240a949b4f9228639983a38b356e88c37767 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Sat, 10 Aug 2024 13:53:41 +0100 Subject: [PATCH 6/7] Add `upload_method` field, document expiry of external URL --- proposals/3870-media-async-upload-url.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md index 4ff45a33f7a..e00249a71fb 100644 --- a/proposals/3870-media-async-upload-url.md +++ b/proposals/3870-media-async-upload-url.md @@ -31,12 +31,14 @@ client may continue to upload via the new upload endpoint defined in MSC2246. { "content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw", "unused_expires_at": 1647257217083, + "upload_method": "PUT", "upload_url": "https://cdn.example.com/media-repo/upload/XAPw4CtrzArk?signed=h4tGOHvCu" } ``` -If the client chooses to upload media via the `upload_url` field it must use a `PUT` request, in this -case: +If the client chooses to upload media via the `upload_url` field it must use the method specified +by the `upload_method` field. Clients should expect the upload URL to work until `unused_expires_at` +time, afterwhich a new media would need to be created. Upload request based on the above response: `PUT https://cdn.example.com/media-repo/upload/XAPw4CtrzArk?signed=h4tGOHvCu` From 30cf12c911cd7c6fe4507b060153930f6582a3a0 Mon Sep 17 00:00:00 2001 From: Nick Mills-Barrett Date: Sat, 10 Aug 2024 13:57:53 +0100 Subject: [PATCH 7/7] Spelling --- proposals/3870-media-async-upload-url.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3870-media-async-upload-url.md b/proposals/3870-media-async-upload-url.md index e00249a71fb..edca0115574 100644 --- a/proposals/3870-media-async-upload-url.md +++ b/proposals/3870-media-async-upload-url.md @@ -14,7 +14,7 @@ of Presence to their users than the homeserver itself. When combined with [MSC3860](https://github.com/matrix-org/matrix-spec-proposals/pull/3860) (media download redirect URLs) this makes it possible to run a "lean" media server that orchestrates where media is uploaded to and downloaded from but does not directly handle much media itself. Note this -doesn't include thubmnails or URL previews which would still go through the media server. +doesn't include thumbnails or URL previews which would still go through the media server. ## Proposal