Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.
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/4793.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Synapse is now permissive about trailing slashes on some of its federation endpoints, allowing zero or more to be present.
2 changes: 1 addition & 1 deletion synapse/federation/transport/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def send_transaction(self, transaction, json_data_callback=None):
# generated by the json_data_callback.
json_data = transaction.get_dict()

path = _create_v1_path("/send/%s/", transaction.transaction_id)
path = _create_v1_path("/send/%s", transaction.transaction_id)

response = yield self.client.put_json(
transaction.destination,
Expand Down
14 changes: 7 additions & 7 deletions synapse/federation/transport/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def register(self, server):


class FederationSendServlet(BaseFederationServlet):
PATH = "/send/(?P<transaction_id>[^/]*)/"
PATH = "/send/(?P<transaction_id>[^/]*)/?"

def __init__(self, handler, server_name, **kwargs):
super(FederationSendServlet, self).__init__(
Expand Down Expand Up @@ -378,15 +378,15 @@ def on_PUT(self, origin, content, query, transaction_id):


class FederationEventServlet(BaseFederationServlet):
PATH = "/event/(?P<event_id>[^/]*)/"
PATH = "/event/(?P<event_id>[^/]*)/?"

# This is when someone asks for a data item for a given server data_id pair.
def on_GET(self, origin, content, query, event_id):
return self.handler.on_pdu_request(origin, event_id)


class FederationStateServlet(BaseFederationServlet):
PATH = "/state/(?P<context>[^/]*)/"
PATH = "/state/(?P<context>[^/]*)/?"

# This is when someone asks for all data for a given context.
def on_GET(self, origin, content, query, context):
Expand All @@ -398,7 +398,7 @@ def on_GET(self, origin, content, query, context):


class FederationStateIdsServlet(BaseFederationServlet):
PATH = "/state_ids/(?P<room_id>[^/]*)/"
PATH = "/state_ids/(?P<room_id>[^/]*)/?"

def on_GET(self, origin, content, query, room_id):
return self.handler.on_state_ids_request(
Expand All @@ -409,7 +409,7 @@ def on_GET(self, origin, content, query, room_id):


class FederationBackfillServlet(BaseFederationServlet):
PATH = "/backfill/(?P<context>[^/]*)/"
PATH = "/backfill/(?P<context>[^/]*)/?"

def on_GET(self, origin, content, query, context):
versions = [x.decode('ascii') for x in query[b"v"]]
Expand Down Expand Up @@ -1080,7 +1080,7 @@ class FederationGroupsCategoriesServlet(BaseFederationServlet):
"""Get all categories for a group
"""
PATH = (
"/groups/(?P<group_id>[^/]*)/categories/"
"/groups/(?P<group_id>[^/]*)/categories/?"
)

@defer.inlineCallbacks
Expand Down Expand Up @@ -1150,7 +1150,7 @@ class FederationGroupsRolesServlet(BaseFederationServlet):
"""Get roles in a group
"""
PATH = (
"/groups/(?P<group_id>[^/]*)/roles/"
"/groups/(?P<group_id>[^/]*)/roles/?"
)

@defer.inlineCallbacks
Expand Down
1 change: 1 addition & 0 deletions synapse/http/matrixfederationclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ def _send_request_with_optional_trailing_slash(
# Retry with a trailing slash if we received a 400 with
# 'M_UNRECOGNIZED' which some endpoints can return when omitting a
# trailing slash on Synapse <= v0.99.3.
logger.info("Retrying request with trailing slash")
request.path += "/"

response = yield self._send_request(
Expand Down
6 changes: 3 additions & 3 deletions tests/handlers/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def test_started_typing_remote_send(self):
put_json = self.hs.get_http_client().put_json
put_json.assert_called_once_with(
"farm",
path="/_matrix/federation/v1/send/1000000/",
path="/_matrix/federation/v1/send/1000000",
data=_expect_edu_transaction(
"m.typing",
content={
Expand All @@ -202,7 +202,7 @@ def test_started_typing_remote_recv(self):

(request, channel) = self.make_request(
"PUT",
"/_matrix/federation/v1/send/1000000/",
"/_matrix/federation/v1/send/1000000",
_make_edu_transaction_json(
"m.typing",
content={
Expand Down Expand Up @@ -258,7 +258,7 @@ def test_stopped_typing(self):
put_json = self.hs.get_http_client().put_json
put_json.assert_called_once_with(
"farm",
path="/_matrix/federation/v1/send/1000000/",
path="/_matrix/federation/v1/send/1000000",
data=_expect_edu_transaction(
"m.typing",
content={
Expand Down