Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit c932614

Browse files
authored
Refactor SimpleHttpClient to pull out reusable methods (#15427)
Pulls out some methods to `BaseHttpClient` to eventually be reused in other contexts.
1 parent 8a47d6e commit c932614

File tree

2 files changed

+77
-56
lines changed

2 files changed

+77
-56
lines changed

changelog.d/15427.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Refactor `SimpleHttpClient` to pull out a base class.

synapse/http/client.py

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -312,35 +312,27 @@ def request(
312312
)
313313

314314

315-
class SimpleHttpClient:
315+
class BaseHttpClient:
316316
"""
317317
A simple, no-frills HTTP client with methods that wrap up common ways of
318-
using HTTP in Matrix
318+
using HTTP in Matrix. Does not come with a default Agent, subclasses will need to
319+
define their own.
320+
321+
Args:
322+
hs: The HomeServer instance to pass in
323+
treq_args: Extra keyword arguments to be given to treq.request.
319324
"""
320325

326+
agent: IAgent
327+
321328
def __init__(
322329
self,
323330
hs: "HomeServer",
324331
treq_args: Optional[Dict[str, Any]] = None,
325-
ip_whitelist: Optional[IPSet] = None,
326-
ip_blacklist: Optional[IPSet] = None,
327-
use_proxy: bool = False,
328332
):
329-
"""
330-
Args:
331-
hs
332-
treq_args: Extra keyword arguments to be given to treq.request.
333-
ip_blacklist: The IP addresses that are blacklisted that
334-
we may not request.
335-
ip_whitelist: The whitelisted IP addresses, that we can
336-
request if it were otherwise caught in a blacklist.
337-
use_proxy: Whether proxy settings should be discovered and used
338-
from conventional environment variables.
339-
"""
340333
self.hs = hs
334+
self.reactor = hs.get_reactor()
341335

342-
self._ip_whitelist = ip_whitelist
343-
self._ip_blacklist = ip_blacklist
344336
self._extra_treq_args = treq_args or {}
345337
self.clock = hs.get_clock()
346338

@@ -356,44 +348,6 @@ def __init__(
356348
# reactor.
357349
self._cooperator = Cooperator(scheduler=_make_scheduler(hs.get_reactor()))
358350

359-
if self._ip_blacklist:
360-
# If we have an IP blacklist, we need to use a DNS resolver which
361-
# filters out blacklisted IP addresses, to prevent DNS rebinding.
362-
self.reactor: ISynapseReactor = BlacklistingReactorWrapper(
363-
hs.get_reactor(), self._ip_whitelist, self._ip_blacklist
364-
)
365-
else:
366-
self.reactor = hs.get_reactor()
367-
368-
# the pusher makes lots of concurrent SSL connections to sygnal, and
369-
# tends to do so in batches, so we need to allow the pool to keep
370-
# lots of idle connections around.
371-
pool = HTTPConnectionPool(self.reactor)
372-
# XXX: The justification for using the cache factor here is that larger instances
373-
# will need both more cache and more connections.
374-
# Still, this should probably be a separate dial
375-
pool.maxPersistentPerHost = max(int(100 * hs.config.caches.global_factor), 5)
376-
pool.cachedConnectionTimeout = 2 * 60
377-
378-
self.agent: IAgent = ProxyAgent(
379-
self.reactor,
380-
hs.get_reactor(),
381-
connectTimeout=15,
382-
contextFactory=self.hs.get_http_client_context_factory(),
383-
pool=pool,
384-
use_proxy=use_proxy,
385-
)
386-
387-
if self._ip_blacklist:
388-
# If we have an IP blacklist, we then install the blacklisting Agent
389-
# which prevents direct access to IP addresses, that are not caught
390-
# by the DNS resolution.
391-
self.agent = BlacklistingAgentWrapper(
392-
self.agent,
393-
ip_blacklist=self._ip_blacklist,
394-
ip_whitelist=self._ip_whitelist,
395-
)
396-
397351
async def request(
398352
self,
399353
method: str,
@@ -799,6 +753,72 @@ async def get_file(
799753
)
800754

801755

756+
class SimpleHttpClient(BaseHttpClient):
757+
"""
758+
An HTTP client capable of crossing a proxy and respecting a block/allow list.
759+
760+
This also configures a larger / longer lasting HTTP connection pool.
761+
762+
Args:
763+
hs: The HomeServer instance to pass in
764+
treq_args: Extra keyword arguments to be given to treq.request.
765+
ip_blacklist: The IP addresses that are blacklisted that
766+
we may not request.
767+
ip_whitelist: The whitelisted IP addresses, that we can
768+
request if it were otherwise caught in a blacklist.
769+
use_proxy: Whether proxy settings should be discovered and used
770+
from conventional environment variables.
771+
"""
772+
773+
def __init__(
774+
self,
775+
hs: "HomeServer",
776+
treq_args: Optional[Dict[str, Any]] = None,
777+
ip_whitelist: Optional[IPSet] = None,
778+
ip_blacklist: Optional[IPSet] = None,
779+
use_proxy: bool = False,
780+
):
781+
super().__init__(hs, treq_args=treq_args)
782+
self._ip_whitelist = ip_whitelist
783+
self._ip_blacklist = ip_blacklist
784+
785+
if self._ip_blacklist:
786+
# If we have an IP blacklist, we need to use a DNS resolver which
787+
# filters out blacklisted IP addresses, to prevent DNS rebinding.
788+
self.reactor: ISynapseReactor = BlacklistingReactorWrapper(
789+
self.reactor, self._ip_whitelist, self._ip_blacklist
790+
)
791+
792+
# the pusher makes lots of concurrent SSL connections to Sygnal, and tends to
793+
# do so in batches, so we need to allow the pool to keep lots of idle
794+
# connections around.
795+
pool = HTTPConnectionPool(self.reactor)
796+
# XXX: The justification for using the cache factor here is that larger
797+
# instances will need both more cache and more connections.
798+
# Still, this should probably be a separate dial
799+
pool.maxPersistentPerHost = max(int(100 * hs.config.caches.global_factor), 5)
800+
pool.cachedConnectionTimeout = 2 * 60
801+
802+
self.agent: IAgent = ProxyAgent(
803+
self.reactor,
804+
hs.get_reactor(),
805+
connectTimeout=15,
806+
contextFactory=self.hs.get_http_client_context_factory(),
807+
pool=pool,
808+
use_proxy=use_proxy,
809+
)
810+
811+
if self._ip_blacklist:
812+
# If we have an IP blacklist, we then install the blacklisting Agent
813+
# which prevents direct access to IP addresses, that are not caught
814+
# by the DNS resolution.
815+
self.agent = BlacklistingAgentWrapper(
816+
self.agent,
817+
ip_blacklist=self._ip_blacklist,
818+
ip_whitelist=self._ip_whitelist,
819+
)
820+
821+
802822
def _timeout_to_request_timed_out_error(f: Failure) -> Failure:
803823
if f.check(twisted_error.TimeoutError, twisted_error.ConnectingCancelledError):
804824
# The TCP connection has its own timeout (set by the 'connectTimeout' param

0 commit comments

Comments
 (0)