diff --git a/synapse/server.py b/synapse/server.py
index fec0024c89..2c27d2a7e8 100644
--- a/synapse/server.py
+++ b/synapse/server.py
@@ -1,6 +1,4 @@
-# Copyright 2014-2016 OpenMarket Ltd
-# Copyright 2017-2018 New Vector Ltd
-# Copyright 2019 The Matrix.org Foundation C.I.C.
+# Copyright 2021 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.
@@ -39,6 +37,7 @@ import twisted.internet.tcp
from twisted.internet import defer
from twisted.mail.smtp import sendmail
from twisted.web.iweb import IPolicyForHTTPS
+from twisted.web.resource import IResource
from synapse.api.auth import Auth
from synapse.api.filtering import Filtering
@@ -66,7 +65,6 @@ from synapse.groups.attestations import GroupAttestationSigning, GroupAttestionR
from synapse.groups.groups_server import GroupsServerHandler, GroupsServerWorkerHandler
from synapse.handlers.account_data import AccountDataHandler
from synapse.handlers.account_validity import AccountValidityHandler
-from synapse.handlers.acme import AcmeHandler
from synapse.handlers.admin import AdminHandler
from synapse.handlers.appservice import ApplicationServicesHandler
from synapse.handlers.auth import AuthHandler, MacaroonGenerator
@@ -259,6 +257,38 @@ class HomeServer(metaclass=abc.ABCMeta):
self.datastores = None # type: Optional[Databases]
+ self._module_web_resources: Dict[str, IResource] = {}
+ self._module_web_resources_consumed = False
+
+ def register_module_web_resource(self, path: str, resource: IResource):
+ """Allows a module to register a web resource to be served at the given path.
+
+ If multiple modules register a resource for the same path, the module that
+ appears the highest in the configuration file takes priority.
+
+ Args:
+ path: The path to register the resource for.
+ resource: The resource to attach to this path.
+
+ Raises:
+ SynapseError(500): A module tried to register a web resource after the HTTP
+ listeners have been started.
+ """
+ if self._module_web_resources_consumed:
+ raise RuntimeError(
+ "Tried to register a web resource from a module after startup",
+ )
+
+ # Don't register a resource that's already been registered.
+ if path not in self._module_web_resources.keys():
+ self._module_web_resources[path] = resource
+ else:
+ logger.warning(
+ "Module tried to register a web resource for path %s but another module"
+ " has already registered a resource for this path.",
+ path,
+ )
+
def get_instance_id(self) -> str:
"""A unique ID for this synapse process instance.
@@ -495,10 +525,6 @@ class HomeServer(metaclass=abc.ABCMeta):
return E2eRoomKeysHandler(self)
@cache_in_self
- def get_acme_handler(self) -> AcmeHandler:
- return AcmeHandler(self)
-
- @cache_in_self
def get_admin_handler(self) -> AdminHandler:
return AdminHandler(self)
@@ -651,7 +677,7 @@ class HomeServer(metaclass=abc.ABCMeta):
@cache_in_self
def get_spam_checker(self) -> SpamChecker:
- return SpamChecker(self)
+ return SpamChecker()
@cache_in_self
def get_third_party_event_rules(self) -> ThirdPartyEventRules:
|