Support MSC2197 outbound with unstable prefix

Signed-off-by: Olivier Wilkinson (reivilibre) <olivier@librepush.net>
This commit is contained in:
Olivier Wilkinson (reivilibre) 2019-08-14 13:30:36 +01:00
parent f70d0a1dd9
commit 6fadb560fc
2 changed files with 56 additions and 13 deletions

View file

@ -327,21 +327,37 @@ class TransportLayerClient(object):
include_all_networks=False, include_all_networks=False,
third_party_instance_id=None, third_party_instance_id=None,
): ):
path = _create_v1_path("/publicRooms") if search_filter:
# TODO(MSC2197): Move to V1 prefix
path = _create_path(FEDERATION_UNSTABLE_PREFIX, "/publicRooms")
args = {"include_all_networks": "true" if include_all_networks else "false"} data = {"include_all_networks": "true" if include_all_networks else "false"}
if third_party_instance_id: if third_party_instance_id:
args["third_party_instance_id"] = (third_party_instance_id,) data["third_party_instance_id"] = third_party_instance_id
if limit: if limit:
args["limit"] = [str(limit)] data["limit"] = str(limit)
if since_token: if since_token:
args["since"] = [since_token] data["since"] = since_token
# TODO(erikj): Actually send the search_filter across federation. data["filter"] = search_filter
response = yield self.client.get_json( response = yield self.client.post_json(
destination=remote_server, path=path, args=args, ignore_backoff=True destination=remote_server, path=path, data=data, ignore_backoff=True
) )
else:
path = _create_v1_path("/publicRooms")
args = {"include_all_networks": "true" if include_all_networks else "false"}
if third_party_instance_id:
args["third_party_instance_id"] = (third_party_instance_id,)
if limit:
args["limit"] = [str(limit)]
if since_token:
args["since"] = [since_token]
response = yield self.client.get_json(
destination=remote_server, path=path, args=args, ignore_backoff=True
)
return response return response

View file

@ -25,6 +25,7 @@ from unpaddedbase64 import decode_base64, encode_base64
from twisted.internet import defer from twisted.internet import defer
from synapse.api.constants import EventTypes, JoinRules from synapse.api.constants import EventTypes, JoinRules
from synapse.api.errors import Codes, HttpResponseException
from synapse.types import ThirdPartyInstanceID from synapse.types import ThirdPartyInstanceID
from synapse.util.async_helpers import concurrently_execute from synapse.util.async_helpers import concurrently_execute
from synapse.util.caches.descriptors import cachedInlineCallbacks from synapse.util.caches.descriptors import cachedInlineCallbacks
@ -485,7 +486,33 @@ class RoomListHandler(BaseHandler):
return {"chunk": [], "total_room_count_estimate": 0} return {"chunk": [], "total_room_count_estimate": 0}
if search_filter: if search_filter:
# We currently don't support searching across federation, so we have # Searching across federation is defined in MSC2197.
# However, the remote homeserver may or may not actually support it.
# So we first try an MSC2197 remote-filtered search, then fall back
# to a locally-filtered search if we must.
try:
res = yield self._get_remote_list_cached(
server_name,
limit=limit,
since_token=since_token,
include_all_networks=include_all_networks,
third_party_instance_id=third_party_instance_id,
search_filter=search_filter,
)
return res
except HttpResponseException as hre:
syn_err = hre.to_synapse_error()
if hre.code in (404, 405) or syn_err.errcode in (
Codes.UNRECOGNIZED,
Codes.NOT_FOUND,
):
logger.debug("Falling back to locally-filtered /publicRooms")
else:
raise # Not an error that should trigger a fallback.
# if we reach this point, then we fall back to the situation where
# we currently don't support searching across federation, so we have
# to do it manually without pagination # to do it manually without pagination
limit = None limit = None
since_token = None since_token = None