Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Implement fallback for V2 invite API #4496

Merged
merged 2 commits into from
Jan 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/4496.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add infrastructure to support different event formats
64 changes: 52 additions & 12 deletions synapse/federation/federation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,18 +751,9 @@ def send_request(destination):

@defer.inlineCallbacks
def send_invite(self, destination, room_id, event_id, pdu):
time_now = self._clock.time_msec()
try:
code, content = yield self.transport_layer.send_invite(
destination=destination,
room_id=room_id,
event_id=event_id,
content=pdu.get_pdu_json(time_now),
)
except HttpResponseException as e:
if e.code == 403:
raise e.to_synapse_error()
raise
room_version = yield self.store.get_room_version(room_id)

content = yield self._do_send_invite(destination, pdu, room_version)

pdu_dict = content["event"]

Expand All @@ -780,6 +771,55 @@ def send_invite(self, destination, room_id, event_id, pdu):

defer.returnValue(pdu)

@defer.inlineCallbacks
def _do_send_invite(self, destination, pdu, room_version):
"""Actually sends the invite, first trying v2 API and falling back to
v1 API if necessary.

Args:
destination (str): Target server
pdu (FrozenEvent)
room_version (str)

Returns:
dict: The event as a dict as returned by the remote server
"""
time_now = self._clock.time_msec()

try:
content = yield self.transport_layer.send_invite_v2(
destination=destination,
room_id=pdu.room_id,
event_id=pdu.event_id,
content={
"event": pdu.get_pdu_json(time_now),
"room_version": room_version,
"invite_room_state": pdu.unsigned.get("invite_room_state", []),
},
)
defer.returnValue(content)
except HttpResponseException as e:
if e.code in [400, 404]:
if room_version in (RoomVersions.V1, RoomVersions.V2):
pass # We'll fall through
else:
raise Exception("Remote server is too old")
elif e.code == 403:
raise e.to_synapse_error()
else:
raise

# Didn't work, try v1 API.
# Note the v1 API returns a tuple of `(200, content)`

_, content = yield self.transport_layer.send_invite_v1(
destination=destination,
room_id=pdu.room_id,
event_id=pdu.event_id,
content=pdu.get_pdu_json(time_now),
)
defer.returnValue(content)

def send_leave(self, destinations, pdu):
"""Sends a leave event to one of a list of homeservers.

Expand Down
39 changes: 37 additions & 2 deletions synapse/federation/transport/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from twisted.internet import defer

from synapse.api.constants import Membership
from synapse.api.urls import FEDERATION_V1_PREFIX
from synapse.api.urls import FEDERATION_V1_PREFIX, FEDERATION_V2_PREFIX
from synapse.util.logutils import log_function

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -289,7 +289,7 @@ def send_leave(self, destination, room_id, event_id, content):

@defer.inlineCallbacks
@log_function
def send_invite(self, destination, room_id, event_id, content):
def send_invite_v1(self, destination, room_id, event_id, content):
path = _create_v1_path("/invite/%s/%s", room_id, event_id)

response = yield self.client.put_json(
Expand All @@ -301,6 +301,20 @@ def send_invite(self, destination, room_id, event_id, content):

defer.returnValue(response)

@defer.inlineCallbacks
@log_function
def send_invite_v2(self, destination, room_id, event_id, content):
path = _create_v2_path("/invite/%s/%s", room_id, event_id)

response = yield self.client.put_json(
destination=destination,
path=path,
data=content,
ignore_backoff=True,
)

defer.returnValue(response)

@defer.inlineCallbacks
@log_function
def get_public_rooms(self, remote_server, limit, since_token,
Expand Down Expand Up @@ -958,3 +972,24 @@ def _create_v1_path(path, *args):
FEDERATION_V1_PREFIX
+ path % tuple(urllib.parse.quote(arg, "") for arg in args)
)


def _create_v2_path(path, *args):
"""Creates a path against V2 federation API from the path template and
args. Ensures that all args are url encoded.

Example:

_create_v2_path("/event/%s/", event_id)

Args:
path (str): String template for the path
args: ([str]): Args to insert into path. Each arg will be url encoded

Returns:
str
"""
return (
FEDERATION_V2_PREFIX
+ path % tuple(urllib.parse.quote(arg, "") for arg in args)
)