Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC2246: Asynchronous media uploads #2246

Merged
merged 30 commits into from
Apr 25, 2023
Merged
Changes from 5 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b439277
Proposal for asynchronous media uploads
tulir Aug 24, 2019
a83c79c
Add security consideration and mention possible /create request body
tulir Aug 24, 2019
9a395ed
Expand on security consideration
tulir Aug 25, 2019
29e3463
Change error code for existing media PUT
tulir Aug 26, 2019
7cf22be
Add spam prevention error, example response and auth requirements
tulir Aug 26, 2019
658aac8
Add query parameters to control downloading
tulir Aug 1, 2020
bbd7d08
Rename max_stall to max_stall_ms
tulir Aug 1, 2020
0bffcb7
Merge branch 'master' into asynchronous_uploads
tulir Aug 1, 2020
4d009a9
Specify /create request body content
tulir Aug 1, 2020
1cbc04e
Update links, versions and prefixes
tulir Mar 14, 2022
c65f2bf
Add recommended maximum delay for starting upload
tulir Mar 14, 2022
63cef50
Explicitly deny uploading to other users' media IDs
tulir Mar 14, 2022
8ccf85f
Prevent spam by ratelimiting instead of limiting number of IDs
tulir Mar 18, 2022
12e907b
Remove streaming requirement
tulir Mar 18, 2022
d582bb3
Add unstable prefixes for new error codes
tulir Mar 18, 2022
173edf3
Add missing words
tulir Mar 18, 2022
f438754
Change /create endpoint to use v1
sumnerevans Jul 8, 2022
725675c
Reorganize /upload spec and integrate feedback
sumnerevans Jul 8, 2022
d55f1f9
Rename max_stall_ms -> timeout_ms
sumnerevans Jul 8, 2022
955177b
Mention that maximum value for timeout_ms should be imposed by the se…
sumnerevans Jul 8, 2022
823fcca
Mention that the timeout_ms can be ignored if the media exists already
sumnerevans Jul 8, 2022
3b00026
Change M_NOT_YET_UPLOADED to use 504 status code
sumnerevans Jul 8, 2022
9627af2
Remove retry_after_ms optional field
sumnerevans Jul 8, 2022
045c21e
Make unused_expires_at the deadline for the upload to complete rather…
sumnerevans Mar 30, 2023
011031b
Add notes about suggested rate-limiting techniques
sumnerevans Mar 30, 2023
6cb7e31
Recommend 24 hours instead of 1 minute
sumnerevans Mar 30, 2023
fedc697
Merge pull request #3 from beeper/async-uploads-rate-limiting-improve…
tulir Mar 31, 2023
7652f59
Clarify that rate limiting can apply on /create and /upload
sumnerevans Apr 20, 2023
098dd90
Clarify that unused_expires_at is a POSIX millisecond timestamp
sumnerevans Apr 20, 2023
9559ab0
Merge pull request #4 from beeper/asynchronous_uploads
tulir Apr 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions proposals/2246-asynchronous-uploads.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Asynchronous media uploads
tulir marked this conversation as resolved.
Show resolved Hide resolved
Sending media to Matrix currently requires that clients first upload the media
to the content repository and then send the event. This is a problem for some
use cases, such as bridges that want to preserve message order, as reuploading
a large file would block all messages.

## Proposal
This proposal proposes a way to send the event containing media before actually
uploading the media, which would make the aformentioned bridge message order
preservation possible without blocking all other messages behind a long upload.

In the future, this new functionality could be used for streaming file
transfers, as requested in [#1885].

### Content repository behavior
The proposal adds two new endpoints to the content repository API and modifies
the behavior of the download endpoint.

#### `POST /_matrix/media/r0/create`
Create a new MXC URI without content. Like `/upload`, this endpoint requires
auth and returns the `content_uri` that can be used in events.
tulir marked this conversation as resolved.
Show resolved Hide resolved

This endpoint could have a JSON body that contains metadata, such as the mime
type of the media that's going to be uploaded. In the future, the body could
also contain access control settings (related: [MSC701]).

To prevent spam, servers should limit calls to this endpoint if the user has
created many media IDs without uploading any content to them. The error code
for such a spam limit is `M_TOO_MANY_IDS_ASSIGNED`. Servers should also provide
configuration options to let high-traffic clients like application services
bypass these limits. The `rate_limited` flag in the appservice registration is
one potential way to do this.

##### Example request
TODO: decide if body is needed already and if yes, spec body schema

##### Example response
```json
{
"content_uri": "mxc://example.com/AQwafuaFswefuhsfAFAgsw"
}
```

#### `PUT /_matrix/media/r0/upload/{serverName}/{mediaId}`
Upload content to a MXC URI that was created earlier. If the endpoint is called
with a media ID that already has content, the request should be rejected with
the error code `M_CANNOT_OVERWRITE_MEDIA`. This endpoint too requires auth.

If the upload is successful, an empty JSON object and status code 200 is
tulir marked this conversation as resolved.
Show resolved Hide resolved
returned. If the serverName/mediaId combination is not known or not local, an
`M_NOT_FOUND` error is returned. For other errors, such as file size, file type
or user quota errors, the normal `/upload` rules apply.

#### Behavior change in `/download`
When another client tries to download media that has not yet been uploaded, the
content repository should stall the request until it is uploaded. Optionally,
tulir marked this conversation as resolved.
Show resolved Hide resolved
content repository implementations may send the data that has already been
uploaded and stream data as it comes in from the sender.

TODO: this should have at least an option to not stall if there's no data yet

## Tradeoffs

## Potential issues
Other clients may time out the download if the sender takes too long to upload
media.

## Security considerations
turt2live marked this conversation as resolved.
Show resolved Hide resolved


[#1885]: https://github.com/matrix-org/matrix-doc/issues/1885
[MSC701]: https://github.com/matrix-org/matrix-doc/issues/701