mirror of
https://git.anonymousland.org/anonymousland/synapse.git
synced 2025-09-19 01:34:34 -04:00
Implementation of HTTP 307 response for MSC3886 POST endpoint (#14018)
Co-authored-by: reivilibre <olivier@librepush.net> Co-authored-by: Andrew Morgan <andrewm@element.io>
This commit is contained in:
parent
844ce47b9b
commit
4eaf3eb840
16 changed files with 257 additions and 45 deletions
|
@ -153,6 +153,7 @@ class TerseJsonTestCase(LoggerCleanupMixin, TestCase):
|
|||
site.site_tag = "test-site"
|
||||
site.server_version_string = "Server v1"
|
||||
site.reactor = Mock()
|
||||
site.experimental_cors_msc3886 = False
|
||||
request = SynapseRequest(FakeChannel(site, None), site)
|
||||
# Call requestReceived to finish instantiating the object.
|
||||
request.content = BytesIO()
|
||||
|
|
45
tests/rest/client/test_rendezvous.py
Normal file
45
tests/rest/client/test_rendezvous.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from twisted.test.proto_helpers import MemoryReactor
|
||||
|
||||
from synapse.rest.client import rendezvous
|
||||
from synapse.server import HomeServer
|
||||
from synapse.util import Clock
|
||||
|
||||
from tests import unittest
|
||||
from tests.unittest import override_config
|
||||
|
||||
endpoint = "/_matrix/client/unstable/org.matrix.msc3886/rendezvous"
|
||||
|
||||
|
||||
class RendezvousServletTestCase(unittest.HomeserverTestCase):
|
||||
|
||||
servlets = [
|
||||
rendezvous.register_servlets,
|
||||
]
|
||||
|
||||
def make_homeserver(self, reactor: MemoryReactor, clock: Clock) -> HomeServer:
|
||||
self.hs = self.setup_test_homeserver()
|
||||
return self.hs
|
||||
|
||||
def test_disabled(self) -> None:
|
||||
channel = self.make_request("POST", endpoint, {}, access_token=None)
|
||||
self.assertEqual(channel.code, 400)
|
||||
|
||||
@override_config({"experimental_features": {"msc3886_endpoint": "/asd"}})
|
||||
def test_redirect(self) -> None:
|
||||
channel = self.make_request("POST", endpoint, {}, access_token=None)
|
||||
self.assertEqual(channel.code, 307)
|
||||
self.assertEqual(channel.headers.getRawHeaders("Location"), ["/asd"])
|
|
@ -266,7 +266,12 @@ class FakeSite:
|
|||
site_tag = "test"
|
||||
access_logger = logging.getLogger("synapse.access.http.fake")
|
||||
|
||||
def __init__(self, resource: IResource, reactor: IReactorTime):
|
||||
def __init__(
|
||||
self,
|
||||
resource: IResource,
|
||||
reactor: IReactorTime,
|
||||
experimental_cors_msc3886: bool = False,
|
||||
):
|
||||
"""
|
||||
|
||||
Args:
|
||||
|
@ -274,6 +279,7 @@ class FakeSite:
|
|||
"""
|
||||
self._resource = resource
|
||||
self.reactor = reactor
|
||||
self.experimental_cors_msc3886 = experimental_cors_msc3886
|
||||
|
||||
def getResourceFor(self, request):
|
||||
return self._resource
|
||||
|
|
|
@ -222,13 +222,22 @@ class OptionsResourceTests(unittest.TestCase):
|
|||
self.resource = OptionsResource()
|
||||
self.resource.putChild(b"res", DummyResource())
|
||||
|
||||
def _make_request(self, method: bytes, path: bytes) -> FakeChannel:
|
||||
def _make_request(
|
||||
self, method: bytes, path: bytes, experimental_cors_msc3886: bool = False
|
||||
) -> FakeChannel:
|
||||
"""Create a request from the method/path and return a channel with the response."""
|
||||
# Create a site and query for the resource.
|
||||
site = SynapseSite(
|
||||
"test",
|
||||
"site_tag",
|
||||
parse_listener_def(0, {"type": "http", "port": 0}),
|
||||
parse_listener_def(
|
||||
0,
|
||||
{
|
||||
"type": "http",
|
||||
"port": 0,
|
||||
"experimental_cors_msc3886": experimental_cors_msc3886,
|
||||
},
|
||||
),
|
||||
self.resource,
|
||||
"1.0",
|
||||
max_request_body_size=4096,
|
||||
|
@ -239,25 +248,58 @@ class OptionsResourceTests(unittest.TestCase):
|
|||
channel = make_request(self.reactor, site, method, path, shorthand=False)
|
||||
return channel
|
||||
|
||||
def _check_cors_standard_headers(self, channel: FakeChannel) -> None:
|
||||
# Ensure the correct CORS headers have been added
|
||||
# as per https://spec.matrix.org/v1.4/client-server-api/#web-browser-clients
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Origin"),
|
||||
[b"*"],
|
||||
"has correct CORS Origin header",
|
||||
)
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Methods"),
|
||||
[b"GET, HEAD, POST, PUT, DELETE, OPTIONS"], # HEAD isn't in the spec
|
||||
"has correct CORS Methods header",
|
||||
)
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Headers"),
|
||||
[b"X-Requested-With, Content-Type, Authorization, Date"],
|
||||
"has correct CORS Headers header",
|
||||
)
|
||||
|
||||
def _check_cors_msc3886_headers(self, channel: FakeChannel) -> None:
|
||||
# Ensure the correct CORS headers have been added
|
||||
# as per https://github.com/matrix-org/matrix-spec-proposals/blob/hughns/simple-rendezvous-capability/proposals/3886-simple-rendezvous-capability.md#cors
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Origin"),
|
||||
[b"*"],
|
||||
"has correct CORS Origin header",
|
||||
)
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Methods"),
|
||||
[b"GET, HEAD, POST, PUT, DELETE, OPTIONS"], # HEAD isn't in the spec
|
||||
"has correct CORS Methods header",
|
||||
)
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Allow-Headers"),
|
||||
[
|
||||
b"X-Requested-With, Content-Type, Authorization, Date, If-Match, If-None-Match"
|
||||
],
|
||||
"has correct CORS Headers header",
|
||||
)
|
||||
self.assertEqual(
|
||||
channel.headers.getRawHeaders(b"Access-Control-Expose-Headers"),
|
||||
[b"ETag, Location, X-Max-Bytes"],
|
||||
"has correct CORS Expose Headers header",
|
||||
)
|
||||
|
||||
def test_unknown_options_request(self) -> None:
|
||||
"""An OPTIONS requests to an unknown URL still returns 204 No Content."""
|
||||
channel = self._make_request(b"OPTIONS", b"/foo/")
|
||||
self.assertEqual(channel.code, 204)
|
||||
self.assertNotIn("body", channel.result)
|
||||
|
||||
# Ensure the correct CORS headers have been added
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Origin"),
|
||||
"has CORS Origin header",
|
||||
)
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Methods"),
|
||||
"has CORS Methods header",
|
||||
)
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Headers"),
|
||||
"has CORS Headers header",
|
||||
)
|
||||
self._check_cors_standard_headers(channel)
|
||||
|
||||
def test_known_options_request(self) -> None:
|
||||
"""An OPTIONS requests to an known URL still returns 204 No Content."""
|
||||
|
@ -265,19 +307,17 @@ class OptionsResourceTests(unittest.TestCase):
|
|||
self.assertEqual(channel.code, 204)
|
||||
self.assertNotIn("body", channel.result)
|
||||
|
||||
# Ensure the correct CORS headers have been added
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Origin"),
|
||||
"has CORS Origin header",
|
||||
)
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Methods"),
|
||||
"has CORS Methods header",
|
||||
)
|
||||
self.assertTrue(
|
||||
channel.headers.hasHeader(b"Access-Control-Allow-Headers"),
|
||||
"has CORS Headers header",
|
||||
self._check_cors_standard_headers(channel)
|
||||
|
||||
def test_known_options_request_msc3886(self) -> None:
|
||||
"""An OPTIONS requests to an known URL still returns 204 No Content."""
|
||||
channel = self._make_request(
|
||||
b"OPTIONS", b"/res/", experimental_cors_msc3886=True
|
||||
)
|
||||
self.assertEqual(channel.code, 204)
|
||||
self.assertNotIn("body", channel.result)
|
||||
|
||||
self._check_cors_msc3886_headers(channel)
|
||||
|
||||
def test_unknown_request(self) -> None:
|
||||
"""A non-OPTIONS request to an unknown URL should 404."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue