diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py
index 79c7a8558d..4228bac673 100755
--- a/synapse/app/homeserver.py
+++ b/synapse/app/homeserver.py
@@ -87,16 +87,10 @@ class SynapseHomeServer(HomeServer):
return MatrixFederationHttpClient(self)
def build_resource_for_client(self):
- res = ClientV1RestResource(self)
- if self.config.gzip_responses:
- res = gz_wrap(res)
- return res
+ return ClientV1RestResource(self)
def build_resource_for_client_v2_alpha(self):
- res = ClientV2AlphaRestResource(self)
- if self.config.gzip_responses:
- res = gz_wrap(res)
- return res
+ return ClientV2AlphaRestResource(self)
def build_resource_for_federation(self):
return JsonResource(self)
@@ -145,49 +139,102 @@ class SynapseHomeServer(HomeServer):
**self.db_config.get("args", {})
)
- def start_listening(self):
- config = self.get_config()
+ def _listener_http(self, config, listener_config):
+ port = listener_config["port"]
+ bind_address = listener_config.get("bind_address", "")
+ tls = listener_config.get("tls", False)
+
+ if tls and config.no_tls:
+ return
- if not config.no_tls and config.bind_port is not None:
+ metrics_resource = self.get_resource_for_metrics()
+
+ resources = {}
+ for res in listener_config["resources"]:
+ for name in res["names"]:
+ if name == "client":
+ if res["compress"]:
+ client_v1 = gz_wrap(self.get_resource_for_client())
+ client_v2 = gz_wrap(self.get_resource_for_client_v2_alpha())
+ else:
+ client_v1 = self.get_resource_for_client()
+ client_v2 = self.get_resource_for_client_v2_alpha()
+
+ resources.update({
+ CLIENT_PREFIX: client_v1,
+ CLIENT_V2_ALPHA_PREFIX: client_v2,
+ })
+
+ if name == "federation":
+ resources.update({
+ FEDERATION_PREFIX: self.get_resource_for_federation(),
+ })
+
+ if name in ["static", "client"]:
+ resources.update({
+ STATIC_PREFIX: self.get_resource_for_static_content(),
+ })
+
+ if name in ["media", "federation", "client"]:
+ resources.update({
+ MEDIA_PREFIX: self.get_resource_for_media_repository(),
+ CONTENT_REPO_PREFIX: self.get_resource_for_content_repo(),
+ })
+
+ if name in ["keys", "federation"]:
+ resources.update({
+ SERVER_KEY_PREFIX: self.get_resource_for_server_key(),
+ SERVER_KEY_V2_PREFIX: self.get_resource_for_server_key_v2(),
+ })
+
+ if name == "webclient":
+ resources[WEB_CLIENT_PREFIX] = self.get_resource_for_web_client()
+
+ if name == "metrics" and metrics_resource:
+ resources[METRICS_PREFIX] = metrics_resource
+
+ root_resource = create_resource_tree(resources)
+ if tls:
reactor.listenSSL(
- config.bind_port,
+ port,
SynapseSite(
"synapse.access.https",
config,
- self.root_resource,
+ root_resource,
),
self.tls_context_factory,
- interface=config.bind_host
+ interface=bind_address
)
- logger.info("Synapse now listening on port %d", config.bind_port)
-
- if config.unsecure_port is not None:
+ else:
reactor.listenTCP(
- config.unsecure_port,
+ port,
SynapseSite(
- "synapse.access.http",
+ "synapse.access.https",
config,
- self.root_resource,
+ root_resource,
),
- interface=config.bind_host
+ interface=bind_address
)
- logger.info("Synapse now listening on port %d", config.unsecure_port)
+ logger.info("Synapse now listening on port %d", port)
- metrics_resource = self.get_resource_for_metrics()
- if metrics_resource and config.metrics_port is not None:
- reactor.listenTCP(
- config.metrics_port,
- SynapseSite(
- "synapse.access.metrics",
- config,
- metrics_resource,
- ),
- interface=config.metrics_bind_host,
- )
- logger.info(
- "Metrics now running on %s port %d",
- config.metrics_bind_host, config.metrics_port,
- )
+ def start_listening(self):
+ config = self.get_config()
+
+ for listener in config.listeners:
+ if listener["type"] == "http":
+ self._listener_http(config, listener)
+ elif listener["type"] == "manhole":
+ f = twisted.manhole.telnet.ShellFactory()
+ f.username = "matrix"
+ f.password = "rabbithole"
+ f.namespace['hs'] = self
+ reactor.listenTCP(
+ listener["port"],
+ f,
+ interface=listener.get("bind_address", '127.0.0.1')
+ )
+ else:
+ logger.warn("Unrecognized listener type: %s", listener["type"])
def run_startup_checks(self, db_conn, database_engine):
all_users_native = are_all_users_on_domain(
@@ -322,11 +369,6 @@ def setup(config_options):
events.USE_FROZEN_DICTS = config.use_frozen_dicts
- if re.search(":[0-9]+$", config.server_name):
- domain_with_port = config.server_name
- else:
- domain_with_port = "%s:%s" % (config.server_name, config.bind_port)
-
tls_context_factory = context_factory.ServerContextFactory(config)
database_engine = create_engine(config.database_config["name"])
@@ -334,7 +376,6 @@ def setup(config_options):
hs = SynapseHomeServer(
config.server_name,
- domain_with_port=domain_with_port,
upload_dir=os.path.abspath("uploads"),
db_config=config.database_config,
tls_context_factory=tls_context_factory,
@@ -344,29 +385,6 @@ def setup(config_options):
database_engine=database_engine,
)
- resources = {
- CLIENT_PREFIX: hs.get_resource_for_client(),
- CLIENT_V2_ALPHA_PREFIX: hs.get_resource_for_client_v2_alpha(),
- FEDERATION_PREFIX: hs.get_resource_for_federation(),
- CONTENT_REPO_PREFIX: hs.get_resource_for_content_repo(),
- SERVER_KEY_PREFIX: hs.get_resource_for_server_key(),
- SERVER_KEY_V2_PREFIX: hs.get_resource_for_server_key_v2(),
- MEDIA_PREFIX: hs.get_resource_for_media_repository(),
- STATIC_PREFIX: hs.get_resource_for_static_content(),
- }
-
- if config.web_client:
- resources[WEB_CLIENT_PREFIX] = hs.get_resource_for_web_client()
-
- metrics_resource = hs.get_resource_for_metrics()
- if config.metrics_port is None and metrics_resource is not None:
- resources[METRICS_PREFIX] = metrics_resource
-
- hs.root_resource = create_resource_tree(
- resources,
- redirect_root_to_web_client=True,
- )
-
logger.info("Preparing database: %r...", config.database_config)
try:
diff --git a/synapse/config/server.py b/synapse/config/server.py
index 022ebcea94..26017c7efa 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -20,26 +20,73 @@ class ServerConfig(Config):
def read_config(self, config):
self.server_name = config["server_name"]
- self.bind_port = config["bind_port"]
- self.bind_host = config["bind_host"]
- self.unsecure_port = config["unsecure_port"]
self.manhole = config.get("manhole")
self.pid_file = self.abspath(config.get("pid_file"))
self.web_client = config["web_client"]
self.soft_file_limit = config["soft_file_limit"]
self.daemonize = config.get("daemonize")
self.use_frozen_dicts = config.get("use_frozen_dicts", True)
- self.gzip_responses = config["gzip_responses"]
+
+ self.listeners = config.get("listeners", [])
+
+ bind_port = config.get("bind_port")
+ if bind_port:
+ self.listeners = []
+ bind_host = config.get("bind_host", "")
+ gzip_responses = config.get("gzip_responses", True)
+
+ self.listeners.append({
+ "port": bind_port,
+ "bind_address": bind_host,
+ "tls": True,
+ "type": "http",
+ "resources": [
+ {
+ "names": ["client", "webclient"],
+ "compress": gzip_responses,
+ },
+ {
+ "names": ["federation"],
+ "compress": False,
+ }
+ ]
+ })
+
+ unsecure_port = config.get("unsecure_port", bind_port - 400)
+ if unsecure_port:
+ self.listeners.append({
+ "port": unsecure_port,
+ "bind_address": bind_host,
+ "tls": False,
+ "type": "http",
+ "resources": [
+ {
+ "names": ["client", "webclient"],
+ "compress": gzip_responses,
+ },
+ {
+ "names": ["federation"],
+ "compress": False,
+ }
+ ]
+ })
# Attempt to guess the content_addr for the v0 content repostitory
content_addr = config.get("content_addr")
if not content_addr:
+ for listener in self.listeners:
+ if listener["type"] == "http" and not listener.get("tls", False):
+ unsecure_port = listener["port"]
+ break
+ else:
+ raise RuntimeError("Could not determine 'content_addr'")
+
host = self.server_name
if ':' not in host:
- host = "%s:%d" % (host, self.unsecure_port)
+ host = "%s:%d" % (host, unsecure_port)
else:
host = host.split(':')[0]
- host = "%s:%d" % (host, self.unsecure_port)
+ host = "%s:%d" % (host, unsecure_port)
content_addr = "http://%s" % (host,)
self.content_addr = content_addr
@@ -61,9 +108,17 @@ class ServerConfig(Config):
# e.g. matrix.org, localhost:8080, etc.
server_name: "%(server_name)s"
+ # The port to listen for HTTPS requests on.
+ # For when matrix traffic is sent directly to synapse.
+ # bind_port: %(bind_port)s
+
+ # The port to listen for HTTP requests on.
+ # For when matrix traffic passes through loadbalancer that unwraps TLS.
+ # unsecure_port: %(unsecure_port)s
+
# Local interface to listen on.
# The empty string will cause synapse to listen on all interfaces.
- bind_host: ""
+ # bind_host: ""
# When running as a daemon, the file to store the pid in
pid_file: %(pid_file)s
@@ -83,31 +138,30 @@ class ServerConfig(Config):
# Should synapse compress HTTP responses to clients that support it?
# This should be disabled if running synapse behind a load balancer
# that can do automatic compression.
- gzip_responses: True
+ # gzip_responses: True
listeners:
- # For when matrix traffic is sent directly to synapse.
- secure:
- # The type of
- type: http_resource
-
- # The port to listen for HTTPS requests on.
- port: %(bind_port)s
-
- # Is this a TLS socket?
- tls: true
-
- # Local interface to listen on.
- # The empty string will cause synapse to listen on all interfaces.
- bind_address: ""
-
- # For when matrix traffic passes through loadbalancer that unwraps TLS.
- unsecure:
- port: %(unsecure_port)s
- tls: false
- bind_address: ""
-
-
+ - port: %(unsecure_port)s
+ tls: false
+ bind_address: ''
+ type: http
+
+ resources:
+ - names: [client, webclient]
+ compress: true
+ - names: [federation]
+ compress: false
+
+ - port: %(bind_port)s
+ tls: true
+ bind_address: ''
+ type: http
+
+ resources:
+ - names: [client, webclient]
+ compress: true
+ - names: [federation]
+ compress: false
""" % locals()
def read_arguments(self, args):
|