summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorAndrew Morgan <andrew@amorgan.xyz>2019-01-16 14:21:34 +0000
committerAndrew Morgan <andrew@amorgan.xyz>2019-01-16 17:17:50 +0000
commit6a83652deed30637d597ee45bfe1804ce67c2595 (patch)
treea351f7321ec271611694033fbd9b8eaba8ee420b /synapse
parentMerge Synapse v0.34.1.1 (diff)
downloadsynapse-6a83652deed30637d597ee45bfe1804ce67c2595.tar.xz
Allow for Synapse to run through a http proxy
Signed-off-by: Andrew Morgan <andrew@amorgan.xyz>
Diffstat (limited to 'synapse')
-rw-r--r--synapse/config/server.py14
-rw-r--r--synapse/http/matrixfederationclient.py26
2 files changed, 36 insertions, 4 deletions
diff --git a/synapse/config/server.py b/synapse/config/server.py
index fb57791098..33c173127c 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -107,12 +107,23 @@ class ServerConfig(Config):
         federation_domain_whitelist = config.get(
             "federation_domain_whitelist", None
         )
+
+        # Optional proxy address for federation traffic
+        self.proxy_federation_requests_address = config.get(
+            "proxy_federation_requests_address", None
+        )
+
         # turn the whitelist into a hash for speed of lookup
         if federation_domain_whitelist is not None:
             self.federation_domain_whitelist = {}
             for domain in federation_domain_whitelist:
                 self.federation_domain_whitelist[domain] = True
 
+        if self.proxy_federation_requests_address is not None:
+            # Ensure proxy address is correctly formatted
+            if len(self.proxy_federation_requests_address.split(':')) != 2:
+                self.proxy_federation_requests_address = None
+
         if self.public_baseurl is not None:
             if self.public_baseurl[-1] != '/':
                 self.public_baseurl += '/'
@@ -289,6 +300,9 @@ class ServerConfig(Config):
         #  - nyc.example.com
         #  - syd.example.com
 
+        # Proxy outbound federation requests through a seperate HTTP proxy.
+        # proxy_federation_requests_address: localhost:1234
+
         # List of ports that Synapse should listen on, their purpose and their
         # configuration.
         listeners:
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index be4076fc6a..abe9c0cbc5 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -56,7 +56,6 @@ outgoing_requests_counter = Counter("synapse_http_matrixfederationclient_request
 incoming_responses_counter = Counter("synapse_http_matrixfederationclient_responses",
                                      "", ["method", "code"])
 
-
 MAX_LONG_RETRIES = 10
 MAX_SHORT_RETRIES = 3
 
@@ -65,6 +64,17 @@ if PY3:
 else:
     MAXINT = sys.maxint
 
+class ProxyMatrixFederationEndpointFactory(object):
+    def __init__(self, hs):
+        self.reactor = hs.get_reactor()
+        self.tls_client_options_factory = hs.tls_client_options_factory
+
+    def endpointForURI(self, uri):
+        return matrix_federation_endpoint(
+            self.reactor, self.hs.proxy_federation_requests_address, timeout=10,
+            tls_client_options_factory=None
+        )
+
 
 class MatrixFederationEndpointFactory(object):
     def __init__(self, hs):
@@ -186,14 +196,22 @@ class MatrixFederationHttpClient(object):
         self.hs = hs
         self.signing_key = hs.config.signing_key[0]
         self.server_name = hs.hostname
+        self.proxy_addr = hs.config.proxy_federation_requests_address
         reactor = hs.get_reactor()
         pool = HTTPConnectionPool(reactor)
         pool.retryAutomatically = False
         pool.maxPersistentPerHost = 5
         pool.cachedConnectionTimeout = 2 * 60
-        self.agent = Agent.usingEndpointFactory(
-            reactor, MatrixFederationEndpointFactory(hs), pool=pool
-        )
+
+        if self.proxy_addr:
+            self.agent = Agent.usingEndpointFactory(
+                reactor, ProxyMatrixFederationEndpointFactory(hs), pool=pool
+            )
+        else:
+            self.agent = Agent.usingEndpointFactory(
+                reactor, MatrixFederationEndpointFactory(hs), pool=pool
+            )
+
         self.clock = hs.get_clock()
         self._store = hs.get_datastore()
         self.version_string_bytes = hs.version_string.encode('ascii')