Include a user agent in federation requests. (#7677)
parent
a3f11567d9
commit
ac51bd581a
|
@ -0,0 +1 @@
|
|||
Include a user-agent for federation and well-known requests.
|
|
@ -48,6 +48,9 @@ class MatrixFederationAgent(object):
|
|||
tls_client_options_factory (FederationPolicyForHTTPS|None):
|
||||
factory to use for fetching client tls options, or none to disable TLS.
|
||||
|
||||
user_agent (bytes):
|
||||
The user agent header to use for federation requests.
|
||||
|
||||
_srv_resolver (SrvResolver|None):
|
||||
SRVResolver impl to use for looking up SRV records. None to use a default
|
||||
implementation.
|
||||
|
@ -61,6 +64,7 @@ class MatrixFederationAgent(object):
|
|||
self,
|
||||
reactor,
|
||||
tls_client_options_factory,
|
||||
user_agent,
|
||||
_srv_resolver=None,
|
||||
_well_known_resolver=None,
|
||||
):
|
||||
|
@ -78,6 +82,7 @@ class MatrixFederationAgent(object):
|
|||
),
|
||||
pool=self._pool,
|
||||
)
|
||||
self.user_agent = user_agent
|
||||
|
||||
if _well_known_resolver is None:
|
||||
_well_known_resolver = WellKnownResolver(
|
||||
|
@ -87,6 +92,7 @@ class MatrixFederationAgent(object):
|
|||
pool=self._pool,
|
||||
contextFactory=tls_client_options_factory,
|
||||
),
|
||||
user_agent=self.user_agent,
|
||||
)
|
||||
|
||||
self._well_known_resolver = _well_known_resolver
|
||||
|
@ -149,7 +155,7 @@ class MatrixFederationAgent(object):
|
|||
parsed_uri = urllib.parse.urlparse(uri)
|
||||
|
||||
# We need to make sure the host header is set to the netloc of the
|
||||
# server.
|
||||
# server and that a user-agent is provided.
|
||||
if headers is None:
|
||||
headers = Headers()
|
||||
else:
|
||||
|
@ -157,6 +163,8 @@ class MatrixFederationAgent(object):
|
|||
|
||||
if not headers.hasHeader(b"host"):
|
||||
headers.addRawHeader(b"host", parsed_uri.netloc)
|
||||
if not headers.hasHeader(b"user-agent"):
|
||||
headers.addRawHeader(b"user-agent", self.user_agent)
|
||||
|
||||
res = yield make_deferred_yieldable(
|
||||
self._agent.request(method, uri, headers, bodyProducer)
|
||||
|
|
|
@ -23,6 +23,7 @@ import attr
|
|||
from twisted.internet import defer
|
||||
from twisted.web.client import RedirectAgent, readBody
|
||||
from twisted.web.http import stringToDatetime
|
||||
from twisted.web.http_headers import Headers
|
||||
|
||||
from synapse.logging.context import make_deferred_yieldable
|
||||
from synapse.util import Clock
|
||||
|
@ -78,7 +79,12 @@ class WellKnownResolver(object):
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self, reactor, agent, well_known_cache=None, had_well_known_cache=None
|
||||
self,
|
||||
reactor,
|
||||
agent,
|
||||
user_agent,
|
||||
well_known_cache=None,
|
||||
had_well_known_cache=None,
|
||||
):
|
||||
self._reactor = reactor
|
||||
self._clock = Clock(reactor)
|
||||
|
@ -92,6 +98,7 @@ class WellKnownResolver(object):
|
|||
self._well_known_cache = well_known_cache
|
||||
self._had_valid_well_known_cache = had_well_known_cache
|
||||
self._well_known_agent = RedirectAgent(agent)
|
||||
self.user_agent = user_agent
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def get_well_known(self, server_name):
|
||||
|
@ -227,6 +234,10 @@ class WellKnownResolver(object):
|
|||
uri = b"https://%s/.well-known/matrix/server" % (server_name,)
|
||||
uri_str = uri.decode("ascii")
|
||||
|
||||
headers = {
|
||||
b"User-Agent": [self.user_agent],
|
||||
}
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
i += 1
|
||||
|
@ -234,7 +245,9 @@ class WellKnownResolver(object):
|
|||
logger.info("Fetching %s", uri_str)
|
||||
try:
|
||||
response = yield make_deferred_yieldable(
|
||||
self._well_known_agent.request(b"GET", uri)
|
||||
self._well_known_agent.request(
|
||||
b"GET", uri, headers=Headers(headers)
|
||||
)
|
||||
)
|
||||
body = yield make_deferred_yieldable(readBody(response))
|
||||
|
||||
|
|
|
@ -197,7 +197,14 @@ class MatrixFederationHttpClient(object):
|
|||
|
||||
self.reactor = Reactor()
|
||||
|
||||
self.agent = MatrixFederationAgent(self.reactor, tls_client_options_factory)
|
||||
user_agent = hs.version_string
|
||||
if hs.config.user_agent_suffix:
|
||||
user_agent = "%s %s" % (user_agent, hs.config.user_agent_suffix)
|
||||
user_agent = user_agent.encode("ascii")
|
||||
|
||||
self.agent = MatrixFederationAgent(
|
||||
self.reactor, tls_client_options_factory, user_agent
|
||||
)
|
||||
|
||||
# Use a BlacklistingAgentWrapper to prevent circumventing the IP
|
||||
# blacklist via IP literals in server names
|
||||
|
|
|
@ -86,6 +86,7 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
|||
self.well_known_resolver = WellKnownResolver(
|
||||
self.reactor,
|
||||
Agent(self.reactor, contextFactory=self.tls_factory),
|
||||
b"test-agent",
|
||||
well_known_cache=self.well_known_cache,
|
||||
had_well_known_cache=self.had_well_known_cache,
|
||||
)
|
||||
|
@ -93,6 +94,7 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
|||
self.agent = MatrixFederationAgent(
|
||||
reactor=self.reactor,
|
||||
tls_client_options_factory=self.tls_factory,
|
||||
user_agent="test-agent", # Note that this is unused since _well_known_resolver is provided.
|
||||
_srv_resolver=self.mock_resolver,
|
||||
_well_known_resolver=self.well_known_resolver,
|
||||
)
|
||||
|
@ -186,6 +188,9 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
|||
# check the .well-known request and send a response
|
||||
self.assertEqual(len(well_known_server.requests), 1)
|
||||
request = well_known_server.requests[0]
|
||||
self.assertEqual(
|
||||
request.requestHeaders.getRawHeaders(b"user-agent"), [b"test-agent"]
|
||||
)
|
||||
self._send_well_known_response(request, content, headers=response_headers)
|
||||
return well_known_server
|
||||
|
||||
|
@ -231,6 +236,9 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
|||
self.assertEqual(
|
||||
request.requestHeaders.getRawHeaders(b"host"), [b"testserv:8448"]
|
||||
)
|
||||
self.assertEqual(
|
||||
request.requestHeaders.getRawHeaders(b"user-agent"), [b"test-agent"]
|
||||
)
|
||||
content = request.content.read()
|
||||
self.assertEqual(content, b"")
|
||||
|
||||
|
@ -719,10 +727,12 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
|||
agent = MatrixFederationAgent(
|
||||
reactor=self.reactor,
|
||||
tls_client_options_factory=tls_factory,
|
||||
user_agent=b"test-agent", # This is unused since _well_known_resolver is passed below.
|
||||
_srv_resolver=self.mock_resolver,
|
||||
_well_known_resolver=WellKnownResolver(
|
||||
self.reactor,
|
||||
Agent(self.reactor, contextFactory=tls_factory),
|
||||
b"test-agent",
|
||||
well_known_cache=self.well_known_cache,
|
||||
had_well_known_cache=self.had_well_known_cache,
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue