From 42309c1c96c29fdcefad392567c4a71a0aa42ddb Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 14 Mar 2019 13:55:44 -0700 Subject: [PATCH] modules/client/rooms/members: Upgrade /members and /joined_members to streamed responses. --- modules/client/rooms/members.cc | 141 ++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 33 deletions(-) diff --git a/modules/client/rooms/members.cc b/modules/client/rooms/members.cc index 3829f18fe..01e5f2cda 100644 --- a/modules/client/rooms/members.cc +++ b/modules/client/rooms/members.cc @@ -17,26 +17,57 @@ get__members(client &client, const resource::request &request, const m::room::id &room_id) { - const m::room::members members + const m::room room { room_id }; - std::vector ret; - ret.reserve(32); + if(!exists(room)) + throw m::NOT_FOUND + { + "Room %s does not exist.", + string_view{room_id} + }; - members.for_each([&ret](const m::event &event) + if(!room.visible(request.user_id)) + throw m::ACCESS_DENIED + { + "You do not have permission to view %s members.", + string_view{room_id} + }; + + resource::response::chunked response { - ret.emplace_back(event); + client, http::OK + }; + + json::stack out + { + response.buf, response.flusher() + }; + + json::stack::object top + { + out + }; + + json::stack::array chunk + { + top, "chunk" + }; + + const m::room::members members + { + room + }; + + members.for_each([&request, &chunk] + (const m::event &event) + { + chunk.append(event); }); - return resource::response - { - client, json::members - { - { "chunk", json::value { ret.data(), ret.size() } } - } - }; + return response; } resource::response @@ -44,32 +75,76 @@ get__joined_members(client &client, const resource::request &request, const m::room::id &room_id) { - const m::room::members members + const m::room room { room_id }; - std::vector ret; - ret.reserve(32); - - members.for_each("join", [&ret](const m::event &event) - { - ret.emplace_back(json::member + if(!exists(room)) + throw m::NOT_FOUND { - at<"sender"_>(event), at<"content"_>(event) + "Room %s does not exist.", + string_view{room_id} + }; + + if(!room.visible(request.user_id)) + throw m::ACCESS_DENIED + { + "You do not have permission to view %s joined members.", + string_view{room_id} + }; + + resource::response::chunked response + { + client, http::OK + }; + + json::stack out + { + response.buf, response.flusher() + }; + + json::stack::object top + { + out + }; + + json::stack::object joined + { + top, "joined" + }; + + const m::room::members members + { + room + }; + + members.for_each("join", m::room::members::closure{[&joined, &room] + (const m::user::id &user_id) + { + const m::event::idx &event_idx + { + room.get(std::nothrow, "m.room.member", user_id) + }; + + if(!event_idx) + return; + + json::stack::object room_member + { + joined, user_id + }; + + m::get(std::nothrow, event_idx, "content", [&room_member] + (const json::object &content) + { + for(const auto &[key, val] : content) + json::stack::member + { + room_member, key, val + }; }); - }); + }}); - const json::strung joined - { - ret.data(), ret.data() + ret.size() - }; - - return resource::response - { - client, json::members - { - { "joined", joined } - } - }; + return response; }