@@ -45,7 +45,20 @@ func TestMediaFilenames(t *testing.T) {
4545
4646 mxcUri := alice .UploadContent (t , data .MatrixPng , filename , "image/png" )
4747
48- name , _ := downloadForFilename (t , alice , mxcUri , "" )
48+ name , _ := downloadForFilename (t , alice , mxcUri , "" , false )
49+
50+ // filename is not required, but if it's an attachment then check it matches
51+ if name != filename {
52+ t .Fatalf ("Incorrect filename '%s', expected '%s'" , name , filename )
53+ }
54+ })
55+
56+ t .Run (fmt .Sprintf ("Can download file '%s' over /_matrix/client/v1/media/download" , filename ), func (t * testing.T ) {
57+ t .Parallel ()
58+
59+ mxcUri := alice .UploadContent (t , data .MatrixPng , filename , "image/png" )
60+
61+ name , _ := downloadForFilename (t , alice , mxcUri , "" , true )
4962
5063 // filename is not required, but if it's an attachment then check it matches
5164 if name != filename {
@@ -61,12 +74,25 @@ func TestMediaFilenames(t *testing.T) {
6174 mxcUri := alice .UploadContent (t , data .MatrixPng , asciiFileName , "image/png" )
6275
6376 const altName = "file.png"
64- filename , _ := downloadForFilename (t , alice , mxcUri , altName )
77+ filename , _ := downloadForFilename (t , alice , mxcUri , altName , false )
6578
6679 if filename != altName {
6780 t .Fatalf ("filename did not match, expected '%s', got '%s'" , altName , filename )
6881 }
6982 })
83+ t .Run ("Can download specifying a different ASCII file name over _matrix/client/v1/media/download" , func (t * testing.T ) {
84+ t .Parallel ()
85+
86+ mxcUri := alice .UploadContent (t , data .MatrixPng , asciiFileName , "image/png" )
87+
88+ const altName = "file.png"
89+ filename , _ := downloadForFilename (t , alice , mxcUri , altName , true )
90+
91+ if filename != altName {
92+ t .Fatalf ("filename did not match, expected '%s', got '%s'" , altName , filename )
93+ }
94+ })
95+
7096 })
7197
7298 t .Run ("Unicode" , func (t * testing.T ) {
@@ -87,7 +113,21 @@ func TestMediaFilenames(t *testing.T) {
87113
88114 const diffUnicodeFilename = "\u2615 " // coffee emoji
89115
90- filename , _ := downloadForFilename (t , alice , mxcUri , diffUnicodeFilename )
116+ filename , _ := downloadForFilename (t , alice , mxcUri , diffUnicodeFilename , false )
117+
118+ if filename != diffUnicodeFilename {
119+ t .Fatalf ("filename did not match, expected '%s', got '%s'" , diffUnicodeFilename , filename )
120+ }
121+ })
122+
123+ t .Run ("Can download specifying a different Unicode file name over _matrix/client/v1/media/download" , func (t * testing.T ) {
124+ t .Parallel ()
125+
126+ mxcUri := alice .UploadContent (t , data .MatrixPng , unicodeFileName , "image/png" )
127+
128+ const diffUnicodeFilename = "\u2615 " // coffee emoji
129+
130+ filename , _ := downloadForFilename (t , alice , mxcUri , diffUnicodeFilename , true )
91131
92132 if filename != diffUnicodeFilename {
93133 t .Fatalf ("filename did not match, expected '%s', got '%s'" , diffUnicodeFilename , filename )
@@ -100,7 +140,19 @@ func TestMediaFilenames(t *testing.T) {
100140
101141 mxcUri := alice .UploadContent (t , data .MatrixPng , unicodeFileName , "image/png" )
102142
103- filename , _ := downloadForFilename (t , alice , mxcUri , "" )
143+ filename , _ := downloadForFilename (t , alice , mxcUri , "" , false )
144+
145+ if filename != unicodeFileName {
146+ t .Fatalf ("filename did not match, expected '%s', got '%s'" , unicodeFileName , filename )
147+ }
148+ })
149+
150+ t .Run ("Can download with Unicode file name locally over _matrix/client/v1/media/download" , func (t * testing.T ) {
151+ t .Parallel ()
152+
153+ mxcUri := alice .UploadContent (t , data .MatrixPng , unicodeFileName , "image/png" )
154+
155+ filename , _ := downloadForFilename (t , alice , mxcUri , "" , true )
104156
105157 if filename != unicodeFileName {
106158 t .Fatalf ("filename did not match, expected '%s', got '%s'" , unicodeFileName , filename )
@@ -113,7 +165,19 @@ func TestMediaFilenames(t *testing.T) {
113165
114166 mxcUri := alice .UploadContent (t , data .MatrixPng , unicodeFileName , "image/png" )
115167
116- filename , _ := downloadForFilename (t , bob , mxcUri , "" )
168+ filename , _ := downloadForFilename (t , bob , mxcUri , "" , false )
169+
170+ if filename != unicodeFileName {
171+ t .Fatalf ("filename did not match, expected '%s', got '%s'" , unicodeFileName , filename )
172+ }
173+ })
174+
175+ t .Run ("Can download with Unicode file name over federation via _matrix/client/v1/media/download" , func (t * testing.T ) {
176+ t .Parallel ()
177+
178+ mxcUri := alice .UploadContent (t , data .MatrixPng , unicodeFileName , "image/png" )
179+
180+ filename , _ := downloadForFilename (t , bob , mxcUri , "" , true )
117181
118182 if filename != unicodeFileName {
119183 t .Fatalf ("filename did not match, expected '%s', got '%s'" , unicodeFileName , filename )
@@ -131,7 +195,25 @@ func TestMediaFilenames(t *testing.T) {
131195
132196 mxcUri := alice .UploadContent (t , data .MatrixPng , "" , "image/png" )
133197
134- _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" )
198+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , false )
199+
200+ if isAttachment {
201+ t .Fatal ("Expected file to be served as inline" )
202+ }
203+ })
204+
205+ t .Run ("Will serve safe media types as inline via _matrix/client/v1/media/download" , func (t * testing.T ) {
206+ if runtime .Homeserver != runtime .Synapse && runtime .Homeserver != runtime .Conduwuit {
207+ // We need to check that this security behaviour is being correctly run in
208+ // Synapse or conduwuit, but since this is not part of the Matrix spec we do not assume
209+ // other homeservers are doing so.
210+ t .Skip ("Skipping test of Content-Disposition header requirements on non-Synapse and non-conduwuit homeserver" )
211+ }
212+ t .Parallel ()
213+
214+ mxcUri := alice .UploadContent (t , data .MatrixPng , "" , "image/png" )
215+
216+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , true )
135217
136218 if isAttachment {
137219 t .Fatal ("Expected file to be served as inline" )
@@ -150,7 +232,26 @@ func TestMediaFilenames(t *testing.T) {
150232 // Add parameters and upper-case, which should be parsed as text/plain.
151233 mxcUri := alice .UploadContent (t , data .MatrixPng , "" , "Text/Plain; charset=utf-8" )
152234
153- _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" )
235+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , false )
236+
237+ if isAttachment {
238+ t .Fatal ("Expected file to be served as inline" )
239+ }
240+ })
241+
242+ t .Run ("Will serve safe media types with parameters as inline via _matrix/client/v1/media/download" , func (t * testing.T ) {
243+ if runtime .Homeserver != runtime .Synapse && runtime .Homeserver != runtime .Conduwuit {
244+ // We need to check that this security behaviour is being correctly run in
245+ // Synapse or conduwuit, but since this is not part of the Matrix spec we do not assume
246+ // other homeservers are doing so.
247+ t .Skip ("Skipping test of Content-Disposition header requirements on non-Synapse and non-conduwuit homeserver" )
248+ }
249+ t .Parallel ()
250+
251+ // Add parameters and upper-case, which should be parsed as text/plain.
252+ mxcUri := alice .UploadContent (t , data .MatrixPng , "" , "Text/Plain; charset=utf-8" )
253+
254+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , true )
154255
155256 if isAttachment {
156257 t .Fatal ("Expected file to be served as inline" )
@@ -168,7 +269,25 @@ func TestMediaFilenames(t *testing.T) {
168269
169270 mxcUri := alice .UploadContent (t , data .MatrixSvg , "" , "image/svg" )
170271
171- _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" )
272+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , false )
273+
274+ if ! isAttachment {
275+ t .Fatal ("Expected file to be served as an attachment" )
276+ }
277+ })
278+
279+ t .Run ("Will serve unsafe media types as attachments via _matrix/client/v1/media/download" , func (t * testing.T ) {
280+ if runtime .Homeserver != runtime .Synapse && runtime .Homeserver != runtime .Conduwuit {
281+ // We need to check that this security behaviour is being correctly run in
282+ // Synapse or conduwuit, but since this is not part of the Matrix spec we do not assume
283+ // other homeservers are doing so.
284+ t .Skip ("Skipping test of Content-Disposition header requirements on non-Synapse and non-conduwuit homeserver" )
285+ }
286+ t .Parallel ()
287+
288+ mxcUri := alice .UploadContent (t , data .MatrixSvg , "" , "image/svg" )
289+
290+ _ , isAttachment := downloadForFilename (t , bob , mxcUri , "" , true )
172291
173292 if ! isAttachment {
174293 t .Fatal ("Expected file to be served as an attachment" )
@@ -179,7 +298,7 @@ func TestMediaFilenames(t *testing.T) {
179298}
180299
181300// Returns content disposition information like (filename, isAttachment)
182- func downloadForFilename (t * testing.T , c * client.CSAPI , mxcUri string , diffName string ) (filename string , isAttachment bool ) {
301+ func downloadForFilename (t * testing.T , c * client.CSAPI , mxcUri string , diffName string , authenticatedEndpoint bool ) (filename string , isAttachment bool ) {
183302 t .Helper ()
184303
185304 origin , mediaId := client .SplitMxc (mxcUri )
@@ -188,8 +307,16 @@ func downloadForFilename(t *testing.T, c *client.CSAPI, mxcUri string, diffName
188307
189308 if diffName != "" {
190309 path = []string {"_matrix" , "media" , "v3" , "download" , origin , mediaId , diffName }
310+
311+ if authenticatedEndpoint {
312+ path = []string {"_matrix" , "client" , "v1" , "media" , "download" , origin , mediaId , diffName }
313+ }
191314 } else {
192315 path = []string {"_matrix" , "media" , "v3" , "download" , origin , mediaId }
316+
317+ if authenticatedEndpoint {
318+ path = []string {"_matrix" , "client" , "v1" , "media" , "download" , origin , mediaId }
319+ }
193320 }
194321
195322 res := c .MustDo (t , "GET" , path )
0 commit comments