From 9da4316ca574f2d552136941d92ce722fabfe29e Mon Sep 17 00:00:00 2001 From: Pablo Saavedra Date: Sat, 13 May 2017 18:17:54 +0200 Subject: [PATCH 1/3] Configurable maximum number of events requested by /sync and /messages (#2220) Set the limit on the returned events in the timeline in the get and sync operations. The default value is -1, means no upper limit. For example, using `filter_timeline_limit: 5000`: POST /_matrix/client/r0/user/user:id/filter { room: { timeline: { limit: 1000000000000000000 } } } GET /_matrix/client/r0/user/user:id/filter/filter:id { room: { timeline: { limit: 5000 } } } The server cuts down the room.timeline.limit. --- synapse/config/server.py | 6 ++++++ synapse/rest/client/v2_alpha/_base.py | 8 ++++++++ synapse/rest/client/v2_alpha/filter.py | 4 ++++ synapse/rest/client/v2_alpha/sync.py | 3 +++ 4 files changed, 21 insertions(+) diff --git a/synapse/config/server.py b/synapse/config/server.py index 25e6666238..3910b9dc31 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -35,6 +35,8 @@ class ServerConfig(Config): # "disable" federation self.send_federation = config.get("send_federation", True) + self.filter_timeline_limit = config.get("filter_timeline_limit", -1) + if self.public_baseurl is not None: if self.public_baseurl[-1] != '/': self.public_baseurl += '/' @@ -161,6 +163,10 @@ class ServerConfig(Config): # The GC threshold parameters to pass to `gc.set_threshold`, if defined # gc_thresholds: [700, 10, 10] + # Set the limit on the returned events in the timeline in the get + # and sync operations. The default value is -1, means no upper limit. + # filter_timeline_limit: 5000 + # List of ports that Synapse should listen on, their purpose and their # configuration. listeners: diff --git a/synapse/rest/client/v2_alpha/_base.py b/synapse/rest/client/v2_alpha/_base.py index 20e765f48f..279e2a7751 100644 --- a/synapse/rest/client/v2_alpha/_base.py +++ b/synapse/rest/client/v2_alpha/_base.py @@ -47,3 +47,11 @@ def client_v2_patterns(path_regex, releases=(0,), new_prefix = CLIENT_V2_ALPHA_PREFIX.replace("/v2_alpha", "/r%d" % release) patterns.append(re.compile("^" + new_prefix + path_regex)) return patterns + + +def set_timeline_upper_limit(filter_json, filter_timeline_limit): + if filter_timeline_limit < 0: + return # no upper limits + if 'room' in filter_json and 'limit' in filter_json['room']: + filter_json['room']["limit"] = min(filter_json['room']["limit"], + filter_timeline_limit) diff --git a/synapse/rest/client/v2_alpha/filter.py b/synapse/rest/client/v2_alpha/filter.py index b4084fec62..364d20d8e6 100644 --- a/synapse/rest/client/v2_alpha/filter.py +++ b/synapse/rest/client/v2_alpha/filter.py @@ -20,6 +20,7 @@ from synapse.http.servlet import RestServlet, parse_json_object_from_request from synapse.types import UserID from ._base import client_v2_patterns +from ._base import set_timeline_upper_limit import logging @@ -85,6 +86,9 @@ class CreateFilterRestServlet(RestServlet): raise AuthError(403, "Can only create filters for local users") content = parse_json_object_from_request(request) + set_timeline_upper_limit(content, + self.hs.config.filter_timeline_limit) + filter_id = yield self.filtering.add_user_filter( user_localpart=target_user.localpart, user_filter=content, diff --git a/synapse/rest/client/v2_alpha/sync.py b/synapse/rest/client/v2_alpha/sync.py index f30eab76fd..f5e7349c5c 100644 --- a/synapse/rest/client/v2_alpha/sync.py +++ b/synapse/rest/client/v2_alpha/sync.py @@ -28,6 +28,7 @@ from synapse.api.filtering import FilterCollection, DEFAULT_FILTER_COLLECTION from synapse.api.errors import SynapseError from synapse.api.constants import PresenceState from ._base import client_v2_patterns +from ._base import set_timeline_upper_limit import itertools import logging @@ -121,6 +122,8 @@ class SyncRestServlet(RestServlet): if filter_id.startswith('{'): try: filter_object = json.loads(filter_id) + set_timeline_upper_limit(filter_object, + self.hs.config.filter_timeline_limit) except: raise SynapseError(400, "Invalid filter JSON") self.filtering.check_valid_filter(filter_object) From 627e6ea2b0b941c67f8752736993f82a5f123e76 Mon Sep 17 00:00:00 2001 From: Pablo Saavedra Date: Mon, 15 May 2017 14:51:43 +0200 Subject: [PATCH 2/3] Fixed implementation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added HS as property in SyncRestServlet * Fixed set_timeline_upper_limit function implementat¡ion --- synapse/rest/client/v2_alpha/_base.py | 9 ++++++--- synapse/rest/client/v2_alpha/sync.py | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/synapse/rest/client/v2_alpha/_base.py b/synapse/rest/client/v2_alpha/_base.py index 279e2a7751..fd8f915655 100644 --- a/synapse/rest/client/v2_alpha/_base.py +++ b/synapse/rest/client/v2_alpha/_base.py @@ -52,6 +52,9 @@ def client_v2_patterns(path_regex, releases=(0,), def set_timeline_upper_limit(filter_json, filter_timeline_limit): if filter_timeline_limit < 0: return # no upper limits - if 'room' in filter_json and 'limit' in filter_json['room']: - filter_json['room']["limit"] = min(filter_json['room']["limit"], - filter_timeline_limit) + if 'room' in filter_json \ + and 'timeline' in filter_json['room'] \ + and 'limit' in filter_json['room']['timeline']: + filter_json['room']['timeline']["limit"] = min( + filter_json['room']['timeline']['limit'], + filter_timeline_limit) diff --git a/synapse/rest/client/v2_alpha/sync.py b/synapse/rest/client/v2_alpha/sync.py index f5e7349c5c..771e127ab9 100644 --- a/synapse/rest/client/v2_alpha/sync.py +++ b/synapse/rest/client/v2_alpha/sync.py @@ -79,6 +79,7 @@ class SyncRestServlet(RestServlet): def __init__(self, hs): super(SyncRestServlet, self).__init__() + self.hs = hs self.auth = hs.get_auth() self.sync_handler = hs.get_sync_handler() self.clock = hs.get_clock() From 224137fcf98b424c6b5d1ab4b76c24b6213c7174 Mon Sep 17 00:00:00 2001 From: Pablo Saavedra Date: Mon, 15 May 2017 16:21:02 +0200 Subject: [PATCH 3/3] Fixed syntax nits --- synapse/rest/client/v2_alpha/_base.py | 5 ++--- synapse/rest/client/v2_alpha/filter.py | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/synapse/rest/client/v2_alpha/_base.py b/synapse/rest/client/v2_alpha/_base.py index fd8f915655..1f5bc24cc3 100644 --- a/synapse/rest/client/v2_alpha/_base.py +++ b/synapse/rest/client/v2_alpha/_base.py @@ -52,9 +52,8 @@ def client_v2_patterns(path_regex, releases=(0,), def set_timeline_upper_limit(filter_json, filter_timeline_limit): if filter_timeline_limit < 0: return # no upper limits - if 'room' in filter_json \ - and 'timeline' in filter_json['room'] \ - and 'limit' in filter_json['room']['timeline']: + timeline = filter_json.get('room', {}).get('timeline', {}) + if 'limit' in timeline: filter_json['room']['timeline']["limit"] = min( filter_json['room']['timeline']['limit'], filter_timeline_limit) diff --git a/synapse/rest/client/v2_alpha/filter.py b/synapse/rest/client/v2_alpha/filter.py index 364d20d8e6..d2b2fd66e6 100644 --- a/synapse/rest/client/v2_alpha/filter.py +++ b/synapse/rest/client/v2_alpha/filter.py @@ -86,8 +86,10 @@ class CreateFilterRestServlet(RestServlet): raise AuthError(403, "Can only create filters for local users") content = parse_json_object_from_request(request) - set_timeline_upper_limit(content, - self.hs.config.filter_timeline_limit) + set_timeline_upper_limit( + content, + self.hs.config.filter_timeline_limit + ) filter_id = yield self.filtering.add_user_filter( user_localpart=target_user.localpart,