Repository: matrix-org/synapse

Issue:
Synapse uses unspecced URL to fetch remote media
### Description

Synapse tries to fetch remote media using a non-specced `v1` URL `/_matrix/media/v1/download/`, instead of `/_matrix/media/r0/download/`.

### Steps to reproduce

Try to fetch remote media, e.g. `https://synapse.neilalexander.dev/_matrix/media/r0/download/dendrite.neilalexander.dev/_3aD3qpR-RhMj0D_IjYzIETXYQ3Ie4QgRbh557zGRXE`

`synapse.http.matrixfederationclient - 408 - INFO - GET-126607 - {GET-O-250358} [dendrite.neilalexander.dev] Sending request: GET matrix://dendrite.neilalexander.dev/_matrix/media/v1/download/dendrite.neilalexander.dev/_3aD3qpR-RhMj0D_IjYzIETXYQ3Ie4QgRbh557zGRXE?allow_remote=false; timeout 60.000000s`

### Version information

- **Homeserver**: Synapse

If not matrix.org:

<!--
 What version of Synapse is running?

You can find the Synapse version with this command:

$ curl http://localhost:8008/_synapse/admin/v1/server_version

(You may need to replace `localhost:8008` if Synapse is not configured to
listen on that port.)
-->
- **Version**: 1.11.0, from docker image `matrixdotorg/synapse latest d64d49dfd131`

- **Install method**: Docker

- **Platform**: VMware Photon OS `Linux photon-machine 4.19.15-1.ph3-esx`



Discussion:
Note that it seems Synapse does server both the r0 and v1 versions, so that's good:

https://github.com/matrix-org/synapse/blob/bd6dc17221741d4ceae05ae769a70696ae939336/synapse/app/homeserver.py#L238-L240

(And this is since 737c4223ef25fd2856d0ff6cc111d14b19f1adec, so for a very long time.)

I suspect we can just update Synapse to use the proper r0 version.

Resolving patch:
diff --git a/synapse/rest/media/v1/media_repository.py b/synapse/rest/media/v1/media_repository.py
--- a/synapse/rest/media/v1/media_repository.py
+++ b/synapse/rest/media/v1/media_repository.py
@@ -338,7 +338,7 @@ async def _download_remote_file(self, server_name, media_id, file_id):
 
         with self.media_storage.store_into_file(file_info) as (f, fname, finish):
             request_path = "/".join(
-                ("/_matrix/media/v1/download", server_name, media_id)
+                ("/_matrix/media/r0/download", server_name, media_id)
             )
             try:
                 length, headers = await self.client.get_file(
@@ -703,7 +703,7 @@ class MediaRepositoryResource(Resource):
     Uploads are POSTed to a resource which returns a token which is used to GET
     the download::
 
-        => POST /_matrix/media/v1/upload HTTP/1.1
+        => POST /_matrix/media/r0/upload HTTP/1.1
            Content-Type: <media-type>
            Content-Length: <content-length>
 
@@ -714,7 +714,7 @@ class MediaRepositoryResource(Resource):
 
            { "content_uri": "mxc://<server-name>/<media-id>" }
 
-        => GET /_matrix/media/v1/download/<server-name>/<media-id> HTTP/1.1
+        => GET /_matrix/media/r0/download/<server-name>/<media-id> HTTP/1.1
 
         <= HTTP/1.1 200 OK
            Content-Type: <media-type>
@@ -725,7 +725,7 @@ class MediaRepositoryResource(Resource):
     Clients can get thumbnails by supplying a desired width and height and
     thumbnailing method::
 
-        => GET /_matrix/media/v1/thumbnail/<server_name>
+        => GET /_matrix/media/r0/thumbnail/<server_name>
                 /<media-id>?width=<w>&height=<h>&method=<m> HTTP/1.1
 
         <= HTTP/1.1 200 OK


Test patch:
diff --git a/tests/rest/media/v1/test_media_storage.py b/tests/rest/media/v1/test_media_storage.py
--- a/tests/rest/media/v1/test_media_storage.py
+++ b/tests/rest/media/v1/test_media_storage.py
@@ -232,7 +232,7 @@ def _req(self, content_disposition):
         self.assertEqual(len(self.fetches), 1)
         self.assertEqual(self.fetches[0][1], "example.com")
         self.assertEqual(
-            self.fetches[0][2], "/_matrix/media/v1/download/" + self.media_id
+            self.fetches[0][2], "/_matrix/media/r0/download/" + self.media_id
         )
         self.assertEqual(self.fetches[0][3], {"allow_remote": "false"})