From fa86a8701d698b6224cabc0cb6a692fc5d7e3272 Mon Sep 17 00:00:00 2001 From: Benjamin Lee Date: Mon, 3 Jun 2024 11:22:51 -0700 Subject: [PATCH] implement filter.limit in /context This seems to be completely redundant with the 'limit' body parameter, with the only difference being: > The filter may be applied before or/and after the limit parameter - filter> whichever the homeserver prefers. This sentence seems to apply to the 'limit' body parameter, but not to the 'limit' field on the filter. This was probably unintentional on the part of the spec authors, but I've switched to using same 'load_limit' pattern we're using elsewhere anyway. --- src/api/client_server/context.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/api/client_server/context.rs b/src/api/client_server/context.rs index 2c5b7cfc..14b19690 100644 --- a/src/api/client_server/context.rs +++ b/src/api/client_server/context.rs @@ -5,12 +5,14 @@ use ruma::{ context::get_context, error::ErrorKind, filter::LazyLoadOptions, }, events::StateEventType, - uint, + uint, UInt, }; use tracing::error; use crate::{ - services, utils::filter::CompiledRoomEventFilter, Ar, Error, Ra, Result, + services, + utils::filter::{load_limit, CompiledRoomEventFilter}, + Ar, Error, Ra, Result, }; /// # `GET /_matrix/client/r0/rooms/{roomId}/context` @@ -77,9 +79,13 @@ pub(crate) async fn get_context_route( lazy_loaded.insert(base_event.sender.as_str().to_owned()); } - // Use limit with maximum 100 - let half_limit = usize::try_from(body.limit.min(uint!(100)) / uint!(2)) - .expect("0-50 should fit in usize"); + let limit: usize = body + .limit + .min(body.filter.limit.unwrap_or(UInt::MAX)) + .min(uint!(100)) + .try_into() + .expect("0-100 should fit in usize"); + let half_limit = limit / 2; let base_event = base_event.to_room_event(); @@ -105,7 +111,7 @@ pub(crate) async fn get_context_route( .rooms .timeline .pdus_until(sender_user, &room_id, base_token)? - .take(half_limit) + .take(load_limit(half_limit)) .filter_map(Result::ok) .filter(|(_, pdu)| { services() @@ -114,6 +120,7 @@ pub(crate) async fn get_context_route( .user_can_see_event(sender_user, &room_id, &pdu.event_id) .unwrap_or(false) }) + .take(half_limit) .collect(); for (_, event) in &events_before { @@ -139,7 +146,7 @@ pub(crate) async fn get_context_route( .rooms .timeline .pdus_after(sender_user, &room_id, base_token)? - .take(half_limit) + .take(load_limit(half_limit)) .filter_map(Result::ok) .filter(|(_, pdu)| { services() @@ -148,6 +155,7 @@ pub(crate) async fn get_context_route( .user_can_see_event(sender_user, &room_id, &pdu.event_id) .unwrap_or(false) }) + .take(half_limit) .collect(); for (_, event) in &events_after {