Ejemplo n.º 1
0
    def test_with_request_context(self):
        """
        Information from the logging context request should be added to the JSON response.
        """
        handler = logging.StreamHandler(self.output)
        handler.setFormatter(JsonFormatter())
        handler.addFilter(LoggingContextFilter())
        logger = self.get_logger(handler)

        # A full request isn't needed here.
        site = Mock(spec=["site_tag", "server_version_string", "getResourceFor"])
        site.site_tag = "test-site"
        site.server_version_string = "Server v1"
        site.reactor = Mock()
        request = SynapseRequest(FakeChannel(site, None), site)
        # Call requestReceived to finish instantiating the object.
        request.content = BytesIO()
        # Partially skip some of the internal processing of SynapseRequest.
        request._started_processing = Mock()
        request.request_metrics = Mock(spec=["name"])
        with patch.object(Request, "render"):
            request.requestReceived(b"POST", b"/_matrix/client/versions", b"1.1")

        # Also set the requester to ensure the processing works.
        request.requester = "@foo:test"

        with LoggingContext(
            request.get_request_id(), parent_context=request.logcontext
        ):
            logger.info("Hello there, %s!", "wally")

        log = self.get_log_line()

        # The terse logger includes additional request information, if possible.
        expected_log_keys = [
            "log",
            "level",
            "namespace",
            "request",
            "ip_address",
            "site_tag",
            "requester",
            "authenticated_entity",
            "method",
            "url",
            "protocol",
            "user_agent",
        ]
        self.assertCountEqual(log.keys(), expected_log_keys)
        self.assertEqual(log["log"], "Hello there, wally!")
        self.assertTrue(log["request"].startswith("POST-"))
        self.assertEqual(log["ip_address"], "127.0.0.1")
        self.assertEqual(log["site_tag"], "test-site")
        self.assertEqual(log["requester"], "@foo:test")
        self.assertEqual(log["authenticated_entity"], "@foo:test")
        self.assertEqual(log["method"], "POST")
        self.assertEqual(log["url"], "/_matrix/client/versions")
        self.assertEqual(log["protocol"], "1.1")
        self.assertEqual(log["user_agent"], "")
Ejemplo n.º 2
0
        async def post_json(destination, path, data):
            self.assertEqual(destination, self.hs.hostname)
            self.assertEqual(
                path, "/_matrix/key/v2/query",
            )

            channel = FakeChannel(self.site, self.reactor)
            req = SynapseRequest(channel)
            req.content = BytesIO(encode_canonical_json(data))

            req.requestReceived(
                b"POST", path.encode("utf-8"), b"1.1",
            )
            channel.await_result()
            self.assertEqual(channel.code, 200)
            resp = channel.json_body
            return resp
Ejemplo n.º 3
0
    def make_notary_request(self, server_name: str, key_id: str) -> dict:
        """Send a GET request to the test server requesting the given key.

        Checks that the response is a 200 and returns the decoded json body.
        """
        channel = FakeChannel(self.site, self.reactor)
        req = SynapseRequest(channel)
        req.content = BytesIO(b"")
        req.requestReceived(
            b"GET",
            b"/_matrix/key/v2/query/%s/%s" %
            (server_name.encode("utf-8"), key_id.encode("utf-8")),
            b"1.1",
        )
        channel.await_result()
        self.assertEqual(channel.code, 200)
        resp = channel.json_body
        return resp
Ejemplo n.º 4
0
        async def post_json(
                destination: str,
                path: str,
                data: Optional[JsonDict] = None) -> Union[JsonDict, list]:
            self.assertEqual(destination, self.hs.hostname)
            self.assertEqual(
                path,
                "/_matrix/key/v2/query",
            )

            channel = FakeChannel(self.site, self.reactor)
            # channel is a `FakeChannel` but `HTTPChannel` is expected
            req = SynapseRequest(channel, self.site)  # type: ignore[arg-type]
            req.content = BytesIO(encode_canonical_json(data))

            req.requestReceived(
                b"POST",
                path.encode("utf-8"),
                b"1.1",
            )
            channel.await_result()
            self.assertEqual(channel.code, 200)
            resp = channel.json_body
            return resp
Ejemplo n.º 5
0
    def _test_disconnect(
        self,
        reactor: ThreadedMemoryReactorClock,
        channel: FakeChannel,
        expect_cancellation: bool,
        expected_body: Union[bytes, JsonDict],
        expected_code: Optional[int] = None,
    ) -> None:
        """Disconnects an in-flight request and checks the response.

        Args:
            reactor: The twisted reactor running the request handler.
            channel: The `FakeChannel` for the request.
            expect_cancellation: `True` if request processing is expected to be
                cancelled, `False` if the request should run to completion.
            expected_body: The expected response for the request.
            expected_code: The expected status code for the request. Defaults to `200`
                or `499` depending on `expect_cancellation`.
        """
        # Determine the expected status code.
        if expected_code is None:
            if expect_cancellation:
                expected_code = HTTP_STATUS_REQUEST_CANCELLED
            else:
                expected_code = HTTPStatus.OK

        request = channel.request
        self.assertFalse(
            channel.is_finished(),
            "Request finished before we could disconnect - "
            "was `await_result=False` passed to `make_request`?",
        )

        # We're about to disconnect the request. This also disconnects the channel, so
        # we have to rely on mocks to extract the response.
        respond_method: Callable[..., Any]
        if isinstance(expected_body, bytes):
            respond_method = respond_with_html_bytes
        else:
            respond_method = respond_with_json

        with mock.patch(f"synapse.http.server.{respond_method.__name__}",
                        wraps=respond_method) as respond_mock:
            # Disconnect the request.
            request.connectionLost(reason=ConnectionDone())

            if expect_cancellation:
                # An immediate cancellation is expected.
                respond_mock.assert_called_once()
                args, _kwargs = respond_mock.call_args
                code, body = args[1], args[2]
                self.assertEqual(code, expected_code)
                self.assertEqual(request.code, expected_code)
                self.assertEqual(body, expected_body)
            else:
                respond_mock.assert_not_called()

                # The handler is expected to run to completion.
                reactor.pump([1.0])
                respond_mock.assert_called_once()
                args, _kwargs = respond_mock.call_args
                code, body = args[1], args[2]
                self.assertEqual(code, expected_code)
                self.assertEqual(request.code, expected_code)
                self.assertEqual(body, expected_body)