diff --git a/synapse/federation/federation_client.py b/synapse/federation/federation_client.py
index 137cfb3346..15a9a88302 100644
--- a/synapse/federation/federation_client.py
+++ b/synapse/federation/federation_client.py
@@ -1014,7 +1014,11 @@ class FederationClient(FederationBase):
)
async def send_join(
- self, destinations: Iterable[str], pdu: EventBase, room_version: RoomVersion
+ self,
+ destinations: Iterable[str],
+ pdu: EventBase,
+ room_version: RoomVersion,
+ partial_state: bool = True,
) -> SendJoinResult:
"""Sends a join event to one of a list of homeservers.
@@ -1027,6 +1031,10 @@ class FederationClient(FederationBase):
pdu: event to be sent
room_version: the version of the room (according to the server that
did the make_join)
+ partial_state: whether to ask the remote server to omit membership state
+ events from the response. If the remote server complies,
+ `partial_state` in the send join result will be set. Defaults to
+ `True`.
Returns:
The result of the send join request.
@@ -1037,7 +1045,9 @@ class FederationClient(FederationBase):
"""
async def send_request(destination: str) -> SendJoinResult:
- response = await self._do_send_join(room_version, destination, pdu)
+ response = await self._do_send_join(
+ room_version, destination, pdu, omit_members=partial_state
+ )
# If an event was returned (and expected to be returned):
#
@@ -1142,9 +1152,9 @@ class FederationClient(FederationBase):
% (auth_chain_create_events,)
)
- if response.partial_state and not response.servers_in_room:
+ if response.members_omitted and not response.servers_in_room:
raise InvalidResponseError(
- "partial_state was set, but no servers were listed in the room"
+ "members_omitted was set, but no servers were listed in the room"
)
return SendJoinResult(
@@ -1152,7 +1162,7 @@ class FederationClient(FederationBase):
state=signed_state,
auth_chain=signed_auth,
origin=destination,
- partial_state=response.partial_state,
+ partial_state=response.members_omitted,
servers_in_room=response.servers_in_room or [],
)
@@ -1177,7 +1187,11 @@ class FederationClient(FederationBase):
)
async def _do_send_join(
- self, room_version: RoomVersion, destination: str, pdu: EventBase
+ self,
+ room_version: RoomVersion,
+ destination: str,
+ pdu: EventBase,
+ omit_members: bool,
) -> SendJoinResponse:
time_now = self._clock.time_msec()
@@ -1188,6 +1202,7 @@ class FederationClient(FederationBase):
room_id=pdu.room_id,
event_id=pdu.event_id,
content=pdu.get_pdu_json(time_now),
+ omit_members=omit_members,
)
except HttpResponseException as e:
# If an error is received that is due to an unrecognised endpoint,
diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py
index bb20af6e91..3197939a36 100644
--- a/synapse/federation/federation_server.py
+++ b/synapse/federation/federation_server.py
@@ -725,10 +725,12 @@ class FederationServer(FederationBase):
"state": [p.get_pdu_json(time_now) for p in state_events],
"auth_chain": [p.get_pdu_json(time_now) for p in auth_chain_events],
"org.matrix.msc3706.partial_state": caller_supports_partial_state,
+ "members_omitted": caller_supports_partial_state,
}
if servers_in_room is not None:
resp["org.matrix.msc3706.servers_in_room"] = list(servers_in_room)
+ resp["servers_in_room"] = list(servers_in_room)
return resp
@@ -1500,7 +1502,7 @@ def _get_event_ids_for_partial_state_join(
prev_state_ids: StateMap[str],
summary: Dict[str, MemberSummary],
) -> Collection[str]:
- """Calculate state to be retuned in a partial_state send_join
+ """Calculate state to be returned in a partial_state send_join
Args:
join_event: the join event being send_joined
diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py
index 77f1f39cac..556883f079 100644
--- a/synapse/federation/transport/client.py
+++ b/synapse/federation/transport/client.py
@@ -351,12 +351,16 @@ class TransportLayerClient:
room_id: str,
event_id: str,
content: JsonDict,
+ omit_members: bool,
) -> "SendJoinResponse":
path = _create_v2_path("/send_join/%s/%s", room_id, event_id)
query_params: Dict[str, str] = {}
if self._faster_joins_enabled:
# lazy-load state on join
- query_params["org.matrix.msc3706.partial_state"] = "true"
+ query_params["org.matrix.msc3706.partial_state"] = (
+ "true" if omit_members else "false"
+ )
+ query_params["omit_members"] = "true" if omit_members else "false"
return await self.client.put_json(
destination=destination,
@@ -794,7 +798,7 @@ class SendJoinResponse:
event: Optional[EventBase] = None
# The room state is incomplete
- partial_state: bool = False
+ members_omitted: bool = False
# List of servers in the room
servers_in_room: Optional[List[str]] = None
@@ -834,16 +838,18 @@ def _event_list_parser(
@ijson.coroutine
-def _partial_state_parser(response: SendJoinResponse) -> Generator[None, Any, None]:
+def _members_omitted_parser(response: SendJoinResponse) -> Generator[None, Any, None]:
"""Helper function for use with `ijson.items_coro`
- Parses the partial_state field in send_join responses
+ Parses the members_omitted field in send_join responses
"""
while True:
val = yield
if not isinstance(val, bool):
- raise TypeError("partial_state must be a boolean")
- response.partial_state = val
+ raise TypeError(
+ "members_omitted (formerly org.matrix.msc370c.partial_state) must be a boolean"
+ )
+ response.members_omitted = val
@ijson.coroutine
@@ -904,11 +910,19 @@ class SendJoinParser(ByteParser[SendJoinResponse]):
if not v1_api:
self._coros.append(
ijson.items_coro(
- _partial_state_parser(self._response),
+ _members_omitted_parser(self._response),
"org.matrix.msc3706.partial_state",
use_float="True",
)
)
+ # The stable field name comes last, so it "wins" if the fields disagree
+ self._coros.append(
+ ijson.items_coro(
+ _members_omitted_parser(self._response),
+ "members_omitted",
+ use_float="True",
+ )
+ )
self._coros.append(
ijson.items_coro(
@@ -918,6 +932,15 @@ class SendJoinParser(ByteParser[SendJoinResponse]):
)
)
+ # Again, stable field name comes last
+ self._coros.append(
+ ijson.items_coro(
+ _servers_in_room_parser(self._response),
+ "servers_in_room",
+ use_float="True",
+ )
+ )
+
def write(self, data: bytes) -> int:
for c in self._coros:
c.send(data)
diff --git a/synapse/federation/transport/server/federation.py b/synapse/federation/transport/server/federation.py
index 53e77b4bb6..17c427387e 100644
--- a/synapse/federation/transport/server/federation.py
+++ b/synapse/federation/transport/server/federation.py
@@ -422,7 +422,7 @@ class FederationV2SendJoinServlet(BaseFederationServerServlet):
server_name: str,
):
super().__init__(hs, authenticator, ratelimiter, server_name)
- self._msc3706_enabled = hs.config.experimental.msc3706_enabled
+ self._read_msc3706_query_param = hs.config.experimental.msc3706_enabled
async def on_PUT(
self,
@@ -436,10 +436,16 @@ class FederationV2SendJoinServlet(BaseFederationServerServlet):
# match those given in content
partial_state = False
- if self._msc3706_enabled:
+ # The stable query parameter wins, if it disagrees with the unstable
+ # parameter for some reason.
+ stable_param = parse_boolean_from_args(query, "omit_members", default=None)
+ if stable_param is not None:
+ partial_state = stable_param
+ elif self._read_msc3706_query_param:
partial_state = parse_boolean_from_args(
query, "org.matrix.msc3706.partial_state", default=False
)
+
result = await self.handler.on_send_join_request(
origin, content, room_id, caller_supports_partial_state=partial_state
)
|