@@ -16,7 +16,7 @@ transfers, as requested in [matrix-spec#432].
16
16
The proposal adds two new endpoints to the content repository API and modifies
17
17
the download and thumbnail endpoints.
18
18
19
- #### ` POST /_matrix/media/v3 /create `
19
+ #### ` POST /_matrix/media/v1 /create `
20
20
Create a new MXC URI without content. Like ` /upload ` , this endpoint requires
21
21
auth and returns the ` content_uri ` that can be used in events.
22
22
@@ -27,12 +27,23 @@ settings (related: [MSC701]).
27
27
The server may optionally enforce a maximum age for unused media IDs to delete
28
28
media IDs when the client doesn't start the upload in time, or when the upload
29
29
was interrupted and not resumed in time. The server should include the maximum
30
- timestamp to start the upload in the ` unused_expires_at ` field in the response
31
- JSON. The recommended default expiration for starting the upload is 1 minute.
30
+ timestamp to complete the upload in the ` unused_expires_at ` field in the
31
+ response JSON. The recommended default expiration is 24 hours which should be
32
+ enough time to accommodate users on poor connection who find a better connection
33
+ to complete the upload.
32
34
33
- The server should also rate limit requests to create media. When combined with
34
- the maximum age for created media IDs, it effectively prevents spam by creating
35
- lots of unused ids.
35
+ ##### Rate Limiting
36
+
37
+ The server should rate limit requests to create media.
38
+
39
+ The server should limit the number of concurrent * pending media uploads* a given
40
+ user can have. A pending media upload is a created MXC URI that (a) is not
41
+ expired (the ` unused_expires_at ` timestamp has not passed) and (b) the media has
42
+ not yet been uploaded for.
43
+
44
+ In both cases, the server should respond with ` M_LIMIT_EXCEEDED ` optionally
45
+ providing details in the ` error ` field, but servers may wish to obscure the
46
+ exact limits that are used and not provide such details.
36
47
37
48
##### Example response
38
49
``` json
@@ -43,31 +54,43 @@ lots of unused ids.
43
54
```
44
55
45
56
#### ` PUT /_matrix/media/v3/upload/{serverName}/{mediaId} `
46
- Upload content to a MXC URI that was created earlier. If the endpoint is called
47
- with a media ID that already has content, the request should be rejected with
48
- the error code ` M_CANNOT_OVERWRITE_MEDIA ` and HTTP status code 409. The endpoint
49
- should also reject upload requests from users other than the user who created
50
- the media ID. This endpoint requires auth.
57
+ Upload content to a MXC URI that was created earlier. This endpoint requires
58
+ auth. If the upload is successful, an empty JSON object and status code 200 is
59
+ returned.
60
+
61
+ If the endpoint is called with a media ID that already has content, the request
62
+ should be rejected with the error code ` M_CANNOT_OVERWRITE_MEDIA ` and HTTP
63
+ status code 409.
51
64
52
- If the upload is successful, an empty JSON object and status code 200 is
53
- returned. If the serverName/mediaId combination is not known or not local, an
54
- ` M_NOT_FOUND ` error is returned. For other errors, such as file size, file type
55
- or user quota errors, the normal ` /upload ` rules apply.
65
+ If the upload request comes from a user other than the one who created the media
66
+ ID, the request should be rejected with an ` M_FORBIDDEN ` error.
56
67
57
- The client should include a ` Content-Length ` header to ensure the server knows
58
- if the file was uploaded entirely. If the server receives a different amount of
59
- data than specified in the header, the upload must fail.
68
+ If the serverName/mediaId combination is not known, not local, or expired, an
69
+ ` M_NOT_FOUND ` error is returned.
70
+
71
+ If the MXC's ` unused_expires_at ` is reached before the upload completes, the
72
+ server may either respond immediately with ` M_NOT_FOUND ` or allow the upload to
73
+ continue.
74
+
75
+ For other errors, such as file size, file type or user quota errors, the normal
76
+ ` /upload ` rules apply.
60
77
61
78
#### Changes to the ` /download ` and ` /thumbnail ` endpoints
62
- A new query parameter, ` max_stall_ms ` is added to the endpoints that can
79
+ A new query parameter, ` timeout_ms ` is added to the endpoints that can
63
80
download media. It's an integer that specifies the maximum number of
64
81
milliseconds that the client is willing to wait to start receiving data.
65
- The default value is 20000 (20 seconds).
82
+ The default value is 20000 (20 seconds). The content repository can and should
83
+ impose a maximum value for this parameter. The content repository can also
84
+ choose to respond before the timeout if it desires.
85
+
86
+ If the media is available immediately (for example in the case of a
87
+ non-asynchronous upload), the content repository should ignore this parameter.
88
+
89
+ If the MXC has expired, the content repository should respond with ` M_NOT_FOUND `
90
+ and a HTTP 404 status code.
66
91
67
- If the data is not available before the specified time is up, the content
68
- repository returns a ` M_NOT_YET_UPLOADED ` error with a HTTP 404 status code.
69
- The error may include an additional ` retry_after_ms ` field to suggest when the
70
- client should try again.
92
+ If the data is not available when the server chooses to respond, the content
93
+ repository returns a ` M_NOT_YET_UPLOADED ` error with a HTTP 504 status code.
71
94
72
95
For the ` /download ` endpoint, the server could also stream data directly as it
73
96
is being uploaded. However, streaming creates several implementation and spec
@@ -83,14 +106,44 @@ media.
83
106
84
107
## Security considerations
85
108
109
+ The primary attack vector that must be prevented is a malicious user creating a
110
+ large number of MXC URIs and sending them to a room without uploading the
111
+ corresponding media. Clients in that room would then attempt to download the
112
+ media, holding open connections to the server and potentially exhausting the
113
+ number of available connections.
114
+
115
+ This attack vector is stopped in multiple ways:
116
+
117
+ 1 . Limits on ` /create ` prevent users from creating MXC URIs too quickly and also
118
+ require them to finish uploading files (or let some of their MXCs expire)
119
+ before creating new MXC URIs.
120
+
121
+ 2 . Servers are free to respond to ` /download ` and ` /thumbnail ` requests before
122
+ the ` timeout_ms ` has been reached and respond with ` M_NOT_YET_UPLOADED ` . For
123
+ example, if the server is under connection count pressure, it can choose to
124
+ respond to waiting download connections with ` M_NOT_YET_UPLOADED ` to free
125
+ connections in the pool.
126
+
127
+ 3 . Once the media is expired, servers can respond immediately to ` /download ` and
128
+ ` /thumbnail ` requests with ` M_NOT_FOUND ` .
129
+
130
+ ## Future work
131
+
132
+ Future MSCs might wish to address large file uploads. One approach would be to
133
+ add metadata to the ` /create ` call via a query parameter (for example
134
+ ` ?large_file_upload=true ` . Servers would have the ability to impose restrictions
135
+ on how many such "large file" uploads a user can have concurrently. For such a
136
+ situation, the server would likely send a more generous ` unused_expires_at `
137
+ timestamp to allow for a long-running upload.
138
+
86
139
## Unstable prefix
87
140
While this MSC is not in a released version of the spec, implementations should
88
141
use ` fi.mau.msc2246 ` as a prefix and as an ` unstable_features ` flag in the
89
142
` /versions ` endpoint.
90
143
91
144
* ` POST /_matrix/media/unstable/fi.mau.msc2246/create `
92
145
* ` PUT /_matrix/media/unstable/fi.mau.msc2246/upload/{serverName}/{mediaId} `
93
- * ` ?fi.mau.msc2246.max_stall_ms `
146
+ * ` ?fi.mau.msc2246.timeout_ms `
94
147
* ` FI.MAU.MSC2246_NOT_YET_UPLOADED `
95
148
* ` FI.MAU.MSC2246_CANNOT_OVERWRITE_MEDIA `
96
149
0 commit comments