mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-28 15:08:49 +03:00
Include a user agent in federation requests. (#7677)
This commit is contained in:
parent
a3f11567d9
commit
ac51bd581a
5 changed files with 43 additions and 4 deletions
1
changelog.d/7677.bugfix
Normal file
1
changelog.d/7677.bugfix
Normal file
|
@ -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):
|
tls_client_options_factory (FederationPolicyForHTTPS|None):
|
||||||
factory to use for fetching client tls options, or none to disable TLS.
|
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):
|
_srv_resolver (SrvResolver|None):
|
||||||
SRVResolver impl to use for looking up SRV records. None to use a default
|
SRVResolver impl to use for looking up SRV records. None to use a default
|
||||||
implementation.
|
implementation.
|
||||||
|
@ -61,6 +64,7 @@ class MatrixFederationAgent(object):
|
||||||
self,
|
self,
|
||||||
reactor,
|
reactor,
|
||||||
tls_client_options_factory,
|
tls_client_options_factory,
|
||||||
|
user_agent,
|
||||||
_srv_resolver=None,
|
_srv_resolver=None,
|
||||||
_well_known_resolver=None,
|
_well_known_resolver=None,
|
||||||
):
|
):
|
||||||
|
@ -78,6 +82,7 @@ class MatrixFederationAgent(object):
|
||||||
),
|
),
|
||||||
pool=self._pool,
|
pool=self._pool,
|
||||||
)
|
)
|
||||||
|
self.user_agent = user_agent
|
||||||
|
|
||||||
if _well_known_resolver is None:
|
if _well_known_resolver is None:
|
||||||
_well_known_resolver = WellKnownResolver(
|
_well_known_resolver = WellKnownResolver(
|
||||||
|
@ -87,6 +92,7 @@ class MatrixFederationAgent(object):
|
||||||
pool=self._pool,
|
pool=self._pool,
|
||||||
contextFactory=tls_client_options_factory,
|
contextFactory=tls_client_options_factory,
|
||||||
),
|
),
|
||||||
|
user_agent=self.user_agent,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._well_known_resolver = _well_known_resolver
|
self._well_known_resolver = _well_known_resolver
|
||||||
|
@ -149,7 +155,7 @@ class MatrixFederationAgent(object):
|
||||||
parsed_uri = urllib.parse.urlparse(uri)
|
parsed_uri = urllib.parse.urlparse(uri)
|
||||||
|
|
||||||
# We need to make sure the host header is set to the netloc of the
|
# 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:
|
if headers is None:
|
||||||
headers = Headers()
|
headers = Headers()
|
||||||
else:
|
else:
|
||||||
|
@ -157,6 +163,8 @@ class MatrixFederationAgent(object):
|
||||||
|
|
||||||
if not headers.hasHeader(b"host"):
|
if not headers.hasHeader(b"host"):
|
||||||
headers.addRawHeader(b"host", parsed_uri.netloc)
|
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(
|
res = yield make_deferred_yieldable(
|
||||||
self._agent.request(method, uri, headers, bodyProducer)
|
self._agent.request(method, uri, headers, bodyProducer)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import attr
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer
|
||||||
from twisted.web.client import RedirectAgent, readBody
|
from twisted.web.client import RedirectAgent, readBody
|
||||||
from twisted.web.http import stringToDatetime
|
from twisted.web.http import stringToDatetime
|
||||||
|
from twisted.web.http_headers import Headers
|
||||||
|
|
||||||
from synapse.logging.context import make_deferred_yieldable
|
from synapse.logging.context import make_deferred_yieldable
|
||||||
from synapse.util import Clock
|
from synapse.util import Clock
|
||||||
|
@ -78,7 +79,12 @@ class WellKnownResolver(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
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._reactor = reactor
|
||||||
self._clock = Clock(reactor)
|
self._clock = Clock(reactor)
|
||||||
|
@ -92,6 +98,7 @@ class WellKnownResolver(object):
|
||||||
self._well_known_cache = well_known_cache
|
self._well_known_cache = well_known_cache
|
||||||
self._had_valid_well_known_cache = had_well_known_cache
|
self._had_valid_well_known_cache = had_well_known_cache
|
||||||
self._well_known_agent = RedirectAgent(agent)
|
self._well_known_agent = RedirectAgent(agent)
|
||||||
|
self.user_agent = user_agent
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def get_well_known(self, server_name):
|
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 = b"https://%s/.well-known/matrix/server" % (server_name,)
|
||||||
uri_str = uri.decode("ascii")
|
uri_str = uri.decode("ascii")
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
b"User-Agent": [self.user_agent],
|
||||||
|
}
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
i += 1
|
i += 1
|
||||||
|
@ -234,7 +245,9 @@ class WellKnownResolver(object):
|
||||||
logger.info("Fetching %s", uri_str)
|
logger.info("Fetching %s", uri_str)
|
||||||
try:
|
try:
|
||||||
response = yield make_deferred_yieldable(
|
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))
|
body = yield make_deferred_yieldable(readBody(response))
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,14 @@ class MatrixFederationHttpClient(object):
|
||||||
|
|
||||||
self.reactor = Reactor()
|
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
|
# Use a BlacklistingAgentWrapper to prevent circumventing the IP
|
||||||
# blacklist via IP literals in server names
|
# blacklist via IP literals in server names
|
||||||
|
|
|
@ -86,6 +86,7 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
||||||
self.well_known_resolver = WellKnownResolver(
|
self.well_known_resolver = WellKnownResolver(
|
||||||
self.reactor,
|
self.reactor,
|
||||||
Agent(self.reactor, contextFactory=self.tls_factory),
|
Agent(self.reactor, contextFactory=self.tls_factory),
|
||||||
|
b"test-agent",
|
||||||
well_known_cache=self.well_known_cache,
|
well_known_cache=self.well_known_cache,
|
||||||
had_well_known_cache=self.had_well_known_cache,
|
had_well_known_cache=self.had_well_known_cache,
|
||||||
)
|
)
|
||||||
|
@ -93,6 +94,7 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
||||||
self.agent = MatrixFederationAgent(
|
self.agent = MatrixFederationAgent(
|
||||||
reactor=self.reactor,
|
reactor=self.reactor,
|
||||||
tls_client_options_factory=self.tls_factory,
|
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,
|
_srv_resolver=self.mock_resolver,
|
||||||
_well_known_resolver=self.well_known_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
|
# check the .well-known request and send a response
|
||||||
self.assertEqual(len(well_known_server.requests), 1)
|
self.assertEqual(len(well_known_server.requests), 1)
|
||||||
request = well_known_server.requests[0]
|
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)
|
self._send_well_known_response(request, content, headers=response_headers)
|
||||||
return well_known_server
|
return well_known_server
|
||||||
|
|
||||||
|
@ -231,6 +236,9 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
request.requestHeaders.getRawHeaders(b"host"), [b"testserv:8448"]
|
request.requestHeaders.getRawHeaders(b"host"), [b"testserv:8448"]
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
request.requestHeaders.getRawHeaders(b"user-agent"), [b"test-agent"]
|
||||||
|
)
|
||||||
content = request.content.read()
|
content = request.content.read()
|
||||||
self.assertEqual(content, b"")
|
self.assertEqual(content, b"")
|
||||||
|
|
||||||
|
@ -719,10 +727,12 @@ class MatrixFederationAgentTests(unittest.TestCase):
|
||||||
agent = MatrixFederationAgent(
|
agent = MatrixFederationAgent(
|
||||||
reactor=self.reactor,
|
reactor=self.reactor,
|
||||||
tls_client_options_factory=tls_factory,
|
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,
|
_srv_resolver=self.mock_resolver,
|
||||||
_well_known_resolver=WellKnownResolver(
|
_well_known_resolver=WellKnownResolver(
|
||||||
self.reactor,
|
self.reactor,
|
||||||
Agent(self.reactor, contextFactory=tls_factory),
|
Agent(self.reactor, contextFactory=tls_factory),
|
||||||
|
b"test-agent",
|
||||||
well_known_cache=self.well_known_cache,
|
well_known_cache=self.well_known_cache,
|
||||||
had_well_known_cache=self.had_well_known_cache,
|
had_well_known_cache=self.had_well_known_cache,
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue