mirror of
https://github.com/matrix-construct/construct
synced 2025-01-14 00:34:18 +01:00
modules/client/rooms/state: Refactor GET handlers for chunk streaming and spec behavior.
This commit is contained in:
parent
42309c1c96
commit
8ebb51bd9f
1 changed files with 107 additions and 130 deletions
|
@ -13,72 +13,29 @@
|
|||
using namespace ircd::m;
|
||||
using namespace ircd;
|
||||
|
||||
static resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id);
|
||||
|
||||
static resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id,
|
||||
const string_view &type);
|
||||
|
||||
static resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key);
|
||||
|
||||
resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id)
|
||||
{
|
||||
char type_buf[m::event::TYPE_MAX_SIZE];
|
||||
const string_view &type
|
||||
{
|
||||
url::decode(type_buf, request.parv[2])
|
||||
};
|
||||
|
||||
char skey_buf[m::event::STATE_KEY_MAX_SIZE];
|
||||
const string_view &state_key
|
||||
{
|
||||
url::decode(skey_buf, request.parv[3])
|
||||
};
|
||||
|
||||
// (non-standard) Allow an event_id to be passed in the query string
|
||||
// for reference framing.
|
||||
char evid_buf[m::id::MAX_SIZE];
|
||||
const string_view &event_id
|
||||
{
|
||||
url::decode(evid_buf, request.query["event_id"])
|
||||
};
|
||||
|
||||
if(type && state_key)
|
||||
return get__state(client, request, room_id, event_id, type, state_key);
|
||||
|
||||
if(type)
|
||||
return get__state(client, request, room_id, event_id, type);
|
||||
|
||||
return get__state(client, request, room_id, event_id);
|
||||
}
|
||||
|
||||
resource::response
|
||||
put__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id)
|
||||
{
|
||||
if(request.parv.size() < 3)
|
||||
throw m::NEED_MORE_PARAMS
|
||||
{
|
||||
"'type' path parameter required."
|
||||
};
|
||||
|
||||
char type_buf[m::event::TYPE_MAX_SIZE];
|
||||
const string_view &type
|
||||
{
|
||||
url::decode(type_buf, request.parv[2])
|
||||
};
|
||||
|
||||
if(request.parv.size() < 3)
|
||||
throw m::NEED_MORE_PARAMS
|
||||
{
|
||||
"'state_key' path parameter required."
|
||||
};
|
||||
|
||||
char skey_buf[m::event::STATE_KEY_MAX_SIZE];
|
||||
const string_view &state_key
|
||||
{
|
||||
|
@ -104,89 +61,109 @@ put__state(client &client,
|
|||
};
|
||||
}
|
||||
|
||||
static resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const m::room::state &state);
|
||||
|
||||
resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id)
|
||||
const room::id &room_id)
|
||||
{
|
||||
const room::state state
|
||||
char type_buf[m::event::TYPE_MAX_SIZE];
|
||||
const string_view &type
|
||||
{
|
||||
room{room_id, event_id}
|
||||
url::decode(type_buf, request.parv[2])
|
||||
};
|
||||
|
||||
std::vector<json::value> ret;
|
||||
ret.reserve(32);
|
||||
|
||||
state.for_each([&ret]
|
||||
(const event &event)
|
||||
char skey_buf[m::event::STATE_KEY_MAX_SIZE];
|
||||
const string_view &state_key
|
||||
{
|
||||
ret.emplace_back(event);
|
||||
url::decode(skey_buf, request.parv[3])
|
||||
};
|
||||
|
||||
// (non-standard) Allow an event_id to be passed in the query string
|
||||
// for reference framing.
|
||||
m::event::id::buf event_id;
|
||||
if(request.query["event_id"])
|
||||
url::decode(event_id, request.query["event_id"]);
|
||||
|
||||
const m::room room
|
||||
{
|
||||
room_id, event_id
|
||||
};
|
||||
|
||||
if(!exists(room))
|
||||
throw m::NOT_FOUND
|
||||
{
|
||||
"Room %s not found.",
|
||||
string_view{room_id}
|
||||
};
|
||||
|
||||
if(!room.visible(request.user_id))
|
||||
throw m::ACCESS_DENIED
|
||||
{
|
||||
"You are not permitted to view %s",
|
||||
string_view{room_id}
|
||||
};
|
||||
|
||||
const m::room::state state
|
||||
{
|
||||
room
|
||||
};
|
||||
|
||||
if(!type)
|
||||
return get__state(client, request, state);
|
||||
|
||||
m::event::fetch::opts fopts;
|
||||
fopts.query_json_force = true;
|
||||
const m::event::fetch event
|
||||
{
|
||||
state.get(type, state_key), fopts
|
||||
};
|
||||
|
||||
if(!visible(event, request.user_id))
|
||||
throw m::ACCESS_DENIED
|
||||
{
|
||||
"You are not permitted to view this state in %s",
|
||||
string_view{room_id}
|
||||
};
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, event.source
|
||||
};
|
||||
}
|
||||
|
||||
resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const m::room::state &state)
|
||||
{
|
||||
resource::response::chunked response
|
||||
{
|
||||
client, http::OK
|
||||
};
|
||||
|
||||
json::stack out
|
||||
{
|
||||
response.buf, response.flusher()
|
||||
};
|
||||
|
||||
json::stack::array top
|
||||
{
|
||||
out
|
||||
};
|
||||
|
||||
state.for_each([&request, &top]
|
||||
(const m::event &event)
|
||||
{
|
||||
if(!visible(event, request.user_id))
|
||||
return;
|
||||
|
||||
top.append(event);
|
||||
});
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, json::value
|
||||
{
|
||||
ret.data(), ret.size()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id,
|
||||
const string_view &type)
|
||||
{
|
||||
const room::state state
|
||||
{
|
||||
room{room_id, event_id}
|
||||
};
|
||||
|
||||
std::vector<json::value> ret;
|
||||
ret.reserve(32);
|
||||
state.for_each(type, [&ret]
|
||||
(const event &event)
|
||||
{
|
||||
ret.emplace_back(event);
|
||||
});
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, json::value
|
||||
{
|
||||
ret.data(), ret.size()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
resource::response
|
||||
get__state(client &client,
|
||||
const resource::request &request,
|
||||
const room::id &room_id,
|
||||
const string_view &event_id,
|
||||
const string_view &type,
|
||||
const string_view &state_key)
|
||||
{
|
||||
const room::state state
|
||||
{
|
||||
room{room_id, event_id}
|
||||
};
|
||||
|
||||
std::array<json::value, 1> ret;
|
||||
const bool i{state.get(std::nothrow, type, state_key, [&ret]
|
||||
(const event &event)
|
||||
{
|
||||
ret[0] = event;
|
||||
})};
|
||||
|
||||
return resource::response
|
||||
{
|
||||
client, json::value
|
||||
{
|
||||
ret.data(), i
|
||||
}
|
||||
};
|
||||
return response;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue