diff options
Diffstat (limited to '')
-rw-r--r-- | synapse/federation/federation_client.py | 20 | ||||
-rw-r--r-- | synapse/federation/federation_server.py | 14 | ||||
-rw-r--r-- | synapse/federation/transport/client.py | 7 | ||||
-rw-r--r-- | synapse/handlers/federation.py | 14 |
4 files changed, 46 insertions, 9 deletions
diff --git a/synapse/federation/federation_client.py b/synapse/federation/federation_client.py index ffd1781252..b32b548500 100644 --- a/synapse/federation/federation_client.py +++ b/synapse/federation/federation_client.py @@ -881,7 +881,7 @@ class FederationClient(FederationBase): # content. return resp[1] - async def send_knock(self, destinations: List[str], pdu: EventBase): + async def send_knock(self, destinations: List[str], pdu: EventBase) -> JsonDict: """Attempts to send a knock event to given a list of servers. Iterates through the list until one attempt succeeds. @@ -893,6 +893,14 @@ class FederationClient(FederationBase): participating in the room. pdu: The event to be sent. + Returns: + The remote homeserver return some state from the room. The response + dictionary is in the form: + + {"knock_state_events": [<state event dict>, ...]} + + The list of state events may be empty. + Raises: SynapseError: If the chosen remote server returns a 3xx/4xx code. RuntimeError: If no servers were reachable. @@ -905,12 +913,20 @@ class FederationClient(FederationBase): "send_knock", destinations, send_request ) - async def _do_send_knock(self, destination: str, pdu: EventBase): + async def _do_send_knock(self, destination: str, pdu: EventBase) -> JsonDict: """Send a knock event to a remote homeserver. Args: destination: The homeserver to send to. pdu: The event to send. + + Returns: + The remote homeserver can optionally return some state from the room. The response + dictionary is in the form: + + {"knock_state_events": [<state event dict>, ...]} + + The list of state events may be empty. """ time_now = self._clock.time_msec() diff --git a/synapse/federation/federation_server.py b/synapse/federation/federation_server.py index 50c8a64aa8..3417f62916 100644 --- a/synapse/federation/federation_server.py +++ b/synapse/federation/federation_server.py @@ -118,6 +118,8 @@ class FederationServer(FederationBase): hs, "fed_txn_handler", timeout_ms=30000 ) # type: ResponseCache[Tuple[str, str]] + self._room_knock_state_types = hs.config.room_knock_state_types + self.transaction_actions = TransactionActions(self.store) self.registry = hs.get_federation_registry() @@ -588,10 +590,16 @@ class FederationServer(FederationBase): pdu = await self._check_sigs_and_hash(room_version, pdu) - # Handle the event - await self.handler.on_send_knock_request(origin, pdu) + # Handle the event, and retrieve the EventContext + event_context = await self.handler.on_send_knock_request(origin, pdu) - return {} + # Retrieve stripped state events from the room and send them back to the remote + # server. This will allow the remote server's clients to display information + # related to the room while the knock request is pending. + stripped_room_state = await self.store.get_stripped_room_state_from_event_context( + event_context, self._room_knock_state_types + ) + return {"knock_state_events": stripped_room_state} async def on_event_auth( self, origin: str, room_id: str, event_id: str diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py index 4650c009f9..ca369af2de 100644 --- a/synapse/federation/transport/client.py +++ b/synapse/federation/transport/client.py @@ -313,7 +313,12 @@ class TransportLayerClient: itself represented as a JSON dict. Returns: - An empty JSON dictionary. + The remote homeserver can optionally return some state from the room. The response + dictionary is in the form: + + {"knock_state_events": [<state event dict>, ...]} + + The list of state events may be empty. """ path = _create_v1_path("/send_knock/%s/%s", room_id, event_id) diff --git a/synapse/handlers/federation.py b/synapse/handlers/federation.py index c89b5d61d4..377180886f 100644 --- a/synapse/handlers/federation.py +++ b/synapse/handlers/federation.py @@ -1484,10 +1484,18 @@ class FederationHandler(BaseHandler): except ValueError: pass - # Send the signed event back to the room - await self.federation_client.send_knock(target_hosts, event) + # Send the signed event back to the room, and potentially receive some + # further information about the room in the form of partial state events + stripped_room_state = await self.federation_client.send_knock( + target_hosts, event + ) + + # Store any stripped room state events in the "unsigned" key of the event. + # This is a bit of a hack and is cribbing off of invites. Basically we + # store the room state here and retrieve it again when this event appears + # in the invitee's sync stream. It is stripped out for all other local users. + event.unsigned["knock_room_state"] = stripped_room_state["knock_state_events"] - # Store the event locally context = await self.state_handler.compute_event_context(event) stream_id = await self.persist_events_and_notify( event.room_id, [(event, context)] |