Use config.listeners

This commit is contained in:
Erik Johnston 2015-06-12 15:33:07 +01:00
parent c42ed47660
commit fd2c07bfed
2 changed files with 165 additions and 93 deletions

View File

@ -87,16 +87,10 @@ class SynapseHomeServer(HomeServer):
return MatrixFederationHttpClient(self) return MatrixFederationHttpClient(self)
def build_resource_for_client(self): def build_resource_for_client(self):
res = ClientV1RestResource(self) return ClientV1RestResource(self)
if self.config.gzip_responses:
res = gz_wrap(res)
return res
def build_resource_for_client_v2_alpha(self): def build_resource_for_client_v2_alpha(self):
res = ClientV2AlphaRestResource(self) return ClientV2AlphaRestResource(self)
if self.config.gzip_responses:
res = gz_wrap(res)
return res
def build_resource_for_federation(self): def build_resource_for_federation(self):
return JsonResource(self) return JsonResource(self)
@ -145,49 +139,102 @@ class SynapseHomeServer(HomeServer):
**self.db_config.get("args", {}) **self.db_config.get("args", {})
) )
def start_listening(self): def _listener_http(self, config, listener_config):
config = self.get_config() port = listener_config["port"]
bind_address = listener_config.get("bind_address", "")
tls = listener_config.get("tls", False)
if not config.no_tls and config.bind_port is not None: if tls and config.no_tls:
return
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( reactor.listenSSL(
config.bind_port, port,
SynapseSite( SynapseSite(
"synapse.access.https", "synapse.access.https",
config, config,
self.root_resource, root_resource,
), ),
self.tls_context_factory, self.tls_context_factory,
interface=config.bind_host interface=bind_address
) )
logger.info("Synapse now listening on port %d", config.bind_port) else:
if config.unsecure_port is not None:
reactor.listenTCP( reactor.listenTCP(
config.unsecure_port, port,
SynapseSite( SynapseSite(
"synapse.access.http", "synapse.access.https",
config, 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() def start_listening(self):
if metrics_resource and config.metrics_port is not None: config = self.get_config()
reactor.listenTCP(
config.metrics_port, for listener in config.listeners:
SynapseSite( if listener["type"] == "http":
"synapse.access.metrics", self._listener_http(config, listener)
config, elif listener["type"] == "manhole":
metrics_resource, f = twisted.manhole.telnet.ShellFactory()
), f.username = "matrix"
interface=config.metrics_bind_host, f.password = "rabbithole"
) f.namespace['hs'] = self
logger.info( reactor.listenTCP(
"Metrics now running on %s port %d", listener["port"],
config.metrics_bind_host, config.metrics_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): def run_startup_checks(self, db_conn, database_engine):
all_users_native = are_all_users_on_domain( all_users_native = are_all_users_on_domain(
@ -322,11 +369,6 @@ def setup(config_options):
events.USE_FROZEN_DICTS = config.use_frozen_dicts 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) tls_context_factory = context_factory.ServerContextFactory(config)
database_engine = create_engine(config.database_config["name"]) database_engine = create_engine(config.database_config["name"])
@ -334,7 +376,6 @@ def setup(config_options):
hs = SynapseHomeServer( hs = SynapseHomeServer(
config.server_name, config.server_name,
domain_with_port=domain_with_port,
upload_dir=os.path.abspath("uploads"), upload_dir=os.path.abspath("uploads"),
db_config=config.database_config, db_config=config.database_config,
tls_context_factory=tls_context_factory, tls_context_factory=tls_context_factory,
@ -344,29 +385,6 @@ def setup(config_options):
database_engine=database_engine, 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) logger.info("Preparing database: %r...", config.database_config)
try: try:

View File

@ -20,26 +20,73 @@ class ServerConfig(Config):
def read_config(self, config): def read_config(self, config):
self.server_name = config["server_name"] 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.manhole = config.get("manhole")
self.pid_file = self.abspath(config.get("pid_file")) self.pid_file = self.abspath(config.get("pid_file"))
self.web_client = config["web_client"] self.web_client = config["web_client"]
self.soft_file_limit = config["soft_file_limit"] self.soft_file_limit = config["soft_file_limit"]
self.daemonize = config.get("daemonize") self.daemonize = config.get("daemonize")
self.use_frozen_dicts = config.get("use_frozen_dicts", True) 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 # Attempt to guess the content_addr for the v0 content repostitory
content_addr = config.get("content_addr") content_addr = config.get("content_addr")
if not 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 host = self.server_name
if ':' not in host: if ':' not in host:
host = "%s:%d" % (host, self.unsecure_port) host = "%s:%d" % (host, unsecure_port)
else: else:
host = host.split(':')[0] host = host.split(':')[0]
host = "%s:%d" % (host, self.unsecure_port) host = "%s:%d" % (host, unsecure_port)
content_addr = "http://%s" % (host,) content_addr = "http://%s" % (host,)
self.content_addr = content_addr self.content_addr = content_addr
@ -61,9 +108,17 @@ class ServerConfig(Config):
# e.g. matrix.org, localhost:8080, etc. # e.g. matrix.org, localhost:8080, etc.
server_name: "%(server_name)s" 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. # Local interface to listen on.
# The empty string will cause synapse to listen on all interfaces. # 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 # When running as a daemon, the file to store the pid in
pid_file: %(pid_file)s pid_file: %(pid_file)s
@ -83,31 +138,30 @@ class ServerConfig(Config):
# Should synapse compress HTTP responses to clients that support it? # Should synapse compress HTTP responses to clients that support it?
# This should be disabled if running synapse behind a load balancer # This should be disabled if running synapse behind a load balancer
# that can do automatic compression. # that can do automatic compression.
gzip_responses: True # gzip_responses: True
listeners: listeners:
# For when matrix traffic is sent directly to synapse. - port: %(unsecure_port)s
secure: tls: false
# The type of bind_address: ''
type: http_resource type: http
# The port to listen for HTTPS requests on. resources:
port: %(bind_port)s - names: [client, webclient]
compress: true
# Is this a TLS socket? - names: [federation]
tls: true compress: false
# 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: %(bind_port)s
tls: true
bind_address: ''
type: http
resources:
- names: [client, webclient]
compress: true
- names: [federation]
compress: false
""" % locals() """ % locals()
def read_arguments(self, args): def read_arguments(self, args):