0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 10:08:56 +02:00

ircd:Ⓜ️ Checkpoint matrix.

This commit is contained in:
Jason Volk 2017-10-25 09:47:03 -07:00
parent f89d6f651c
commit f10662fe7d
20 changed files with 2769 additions and 964 deletions

View file

@ -945,7 +945,7 @@ try
token_count(args, ' ') >= 2? lex_cast<uint>(token(args, ' ', 2)) : 0U
};
m::backfill(room, event_id, limit);
m::vm::backfill(room, event_id, limit);
break;
}
@ -1025,13 +1025,7 @@ try
token(args, ' ', 1)
};
m::room room
{
room_id
};
json::iov content{};
room.join(user_id, content);
m::join(room_id, user_id);
break;
}
@ -1052,12 +1046,12 @@ try
token(args, ' ', 1)
};
m::state(room, event_id);
m::vm::state(room, event_id);
break;
}
case hash("fetch"):
case hash("get"):
{
const auto args
{
@ -1074,6 +1068,92 @@ try
break;
}
case hash("fetch"):
{
const auto args
{
tokens_after(line, ' ', 0)
};
const m::event::id event_id
{
token(args, ' ', 0)
};
const net::remote remote
{
token(args, ' ', 1)
};
static char buf[65536];
m::event::fetch fetch
{
event_id, buf, remote
};
std::cout << m::io::acquire(fetch) << std::endl;
break;
}
case hash("mfetch"):
{
const auto args
{
tokens_after(line, ' ', 0)
};
const auto event_ids
{
tokens_after(line, ' ', 0)
};
// const net::remote remote
// {
// token(args, ' ', 0)
// };
string_view event_id[8];
const auto count
{
tokens(event_ids, ' ', event_id)
};
static char buf[8][65536];
m::event::fetch tab[count];
for(size_t i(0); i < count; ++i)
{
tab[i].event_id = event_id[i];
tab[i].buf = buf[i];
// tab[i].hint = remote;
}
m::io::acquire({tab, count});
for(size_t i(0); i < count; ++i)
{
std::cout << tab[i].event_id << ": size: " << string_view{tab[i].pdu}.size() << std::endl;
}
break;
}
case hash("acquire"):
{
const auto args
{
tokens_after(line, ' ', 0)
};
const m::event::id event_id
{
token(args, ' ', 0)
};
static char buf[65536];
std::cout << m::vm::acquire(event_id, buf) << std::endl;
break;
}
case hash("trace"):
{
const auto args
@ -1086,7 +1166,7 @@ try
token(args, ' ', 0)
};
m::trace(event_id, []
m::vm::trace(event_id, []
(const auto &event, auto &next)
{
std::cout << event << std::endl << std::endl;

View file

@ -24,6 +24,8 @@
#pragma once
#define HAVE_IRCD_M_EVENT_H
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsubobject-linkage"
///////////////////////////////////////////////////////////////////////////////
// Protocol notes
@ -55,12 +57,12 @@ namespace ircd::m::name
constexpr const char *const depth {"depth"};
constexpr const char *const event_id {"event_id"};
constexpr const char *const hashes {"hashes"};
constexpr const char *const is_state {"is_state"};
constexpr const char *const membership {"membership"};
constexpr const char *const origin {"origin"};
constexpr const char *const origin_server_ts {"origin_server_ts"};
constexpr const char *const prev_ids {"prev_ids"};
constexpr const char *const prev_events {"prev_ids"};
constexpr const char *const prev_state {"prev_ids"};
constexpr const char *const prev_events {"prev_events"};
constexpr const char *const prev_state {"prev_state"};
constexpr const char *const room_id {"room_id"};
constexpr const char *const sender {"sender"};
constexpr const char *const signatures {"signatures"};
@ -75,22 +77,27 @@ struct ircd::m::event
json::property<name::auth_events, string_view>,
json::property<name::content, json::object>,
json::property<name::depth, int64_t>,
json::property<name::event_id, string_view>,
json::property<name::hashes, string_view>,
json::property<name::membership, string_view>,
json::property<name::origin, string_view>,
json::property<name::event_id, json::string>,
json::property<name::hashes, json::object>,
json::property<name::is_state, bool>,
json::property<name::membership, json::string>,
json::property<name::origin, json::string>,
json::property<name::origin_server_ts, time_t>,
json::property<name::prev_ids, string_view>,
json::property<name::prev_events, string_view>,
json::property<name::prev_state, string_view>,
json::property<name::room_id, string_view>,
json::property<name::sender, string_view>,
json::property<name::signatures, string_view>,
json::property<name::state_key, string_view>,
json::property<name::type, string_view>,
json::property<name::prev_events, json::array>,
json::property<name::prev_state, json::array>,
json::property<name::room_id, json::string>,
json::property<name::sender, json::string>,
json::property<name::signatures, json::object>,
json::property<name::state_key, json::string>,
json::property<name::type, json::string>,
json::property<name::unsigned_, string_view>
>
{
enum lineage : int;
enum temporality : int;
struct fetch;
using id = m::id::event;
static database *events;
@ -100,13 +107,36 @@ struct ircd::m::event
using where = db::where;
template<enum db::where w = where::noop> using query = cursor::query_type<w>;
// Queue of contexts waiting to see the next inserted event
static ctx::view<const event> inserted;
static id::buf head;
static const_iterator find(const id &);
static void insert(json::iov &);
using super_type::tuple;
using super_type::operator=;
};
namespace ircd::m
{
string_view reflect(const event::temporality &);
event::temporality temporality(const event &, const int64_t &rel);
string_view reflect(const event::lineage &);
event::lineage lineage(const event &);
}
enum ircd::m::event::temporality
:int
{
FUTURE = 1, ///< Event has a depth 1 or more into the future.
PRESENT = 0, ///< Event has a depth equal to the current depth.
PAST = -1, ///< Event has a depth less than the current depth.
};
enum ircd::m::event::lineage
:int
{
ROOT = 0, ///< Event has no parents (must be m.room.create then)
FORWARD = 1, ///< Event has one parent at the previous depth
MERGE = 2, ///< Event has multiple parents at the previous depth
};
#pragma GCC diagnostic pop

View file

@ -24,6 +24,8 @@
#pragma once
#define HAVE_IRCD_M_FILTER_H
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsubobject-linkage"
namespace ircd::m
{
@ -118,3 +120,5 @@ struct ircd::m::filter
filter(const string_view &filter_id, const mutable_buffer &);
};
#pragma GCC diagnostic pop

View file

@ -95,10 +95,8 @@ namespace ircd::m
const char *reflect(const enum id::sigil &);
}
//
// ID object backed by an internal buffer. Useful for creating or composing
// a new ID.
//
/// ID object backed by an internal buffer of wost-case size.
///
template<class T,
size_t MAX = 256>
struct ircd::m::id::buf

158
include/ircd/m/io.h Normal file
View file

@ -0,0 +1,158 @@
/*
* charybdis: 21st Century IRC++d
*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#define HAVE_IRCD_M_IO_H
namespace ircd::m::io
{
struct session;
struct request;
struct response;
bool verify_x_matrix_authorization(const string_view &authorization, const string_view &method, const string_view &uri, const string_view &content);
// Synchronous acquire
size_t acquire(vector_view<event::fetch>);
json::object acquire(event::fetch &);
size_t acquire(vector_view<room::fetch>);
json::array acquire(room::fetch &);
size_t acquire(vector_view<room::state::fetch>);
json::array acquire(room::state::fetch &);
// Synchronous acquire with user buffer
json::object get(const id::event &, const mutable_buffer &);
}
namespace ircd::m
{
using io::get;
using io::session;
using io::request;
using io::response;
}
struct ircd::m::event::fetch
{
// out
event::id event_id;
mutable_buffer buf;
net::remote hint;
// in
json::object pdu;
std::exception_ptr error;
};
struct ircd::m::room::fetch
{
// out
event::id event_id;
room::id room_id;
mutable_buffer buf;
net::remote hint;
uint64_t limit {128};
// in
json::array pdus;
json::array auth_chain;
std::exception_ptr error;
};
struct ircd::m::room::state::fetch
{
// out
event::id event_id;
room::id room_id;
mutable_buffer buf;
net::remote hint;
uint64_t limit {128};
// in
json::array pdus;
json::array auth_chain;
std::exception_ptr error;
};
struct ircd::m::io::request
{
struct authorization;
struct keys;
string_view origin;
string_view destination;
string_view method;
string_view path;
string_view query;
string_view fragment;
std::string _content;
json::object content;
string_view generate_authorization(const mutable_buffer &out) const;
void operator()(server &, const vector_view<const http::header> & = {}) const;
void operator()(const vector_view<const http::header> & = {}) const;
request(const string_view &method,
const string_view &path,
const string_view &query = {},
json::members body = {})
:method{method}
,path{path}
,query{query}
,_content{json::strung(body)}
,content{_content}
{}
request(const string_view &method,
const string_view &path,
const string_view &query,
const json::object &content)
:method{method}
,path{path}
,query{query}
,content{content}
{}
request() = default;
};
struct ircd::m::io::response
:json::object
{
response(server &, parse::buffer &);
};
struct ircd::m::io::session
{
ircd::server server;
std::string destination;
std::string access_token;
json::object operator()(parse::buffer &pb, request &);
session(const net::remote &);
session() = default;
};

View file

@ -50,8 +50,6 @@ namespace ircd
#include "filter.h"
#include "keys.h"
#include "txn.h"
#include "request.h"
#include "session.h"
namespace ircd::m::dbs
{

View file

@ -1,77 +0,0 @@
/*
* charybdis: 21st Century IRC++d
*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#pragma once
#define HAVE_IRCD_M_REQUEST_H
namespace ircd {
namespace m {
struct request
{
string_view method;
string_view path;
string_view query;
string_view access_token;
std::string _content;
json::object content;
request(const string_view &method,
const string_view &path,
const string_view &query = {},
json::members body = {});
request(const string_view &method,
const string_view &path,
const string_view &query,
const json::object &content);
};
} // namespace m
} // namespace ircd
inline
ircd::m::request::request(const string_view &method,
const string_view &path,
const string_view &query,
json::members body)
:method{method}
,path{path}
,query{query}
,_content{json::string(body)}
,content{_content}
{
}
inline
ircd::m::request::request(const string_view &method,
const string_view &path,
const string_view &query,
const json::object &content)
:method{method}
,path{path}
,query{query}
,content{content}
{
}

View file

@ -24,6 +24,8 @@
#pragma once
#define HAVE_IRCD_M_ROOM_H
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsubobject-linkage"
namespace ircd::m
{
@ -32,27 +34,42 @@ namespace ircd::m
IRCD_M_EXCEPTION(CONFLICT, ALREADY_MEMBER, http::CONFLICT);
struct room;
room create(const id::room &room_id, const id::user &creator, const id::room &parent, const string_view &type);
room create(const id::room &room_id, const id::user &creator, const string_view &type = {});
void membership(const id::room &room_id, const m::id::user &, const string_view &membership);
void leave(const id::room &room_id, const m::id::user &);
void join(const id::room &room_id, const m::id::user &);
}
struct ircd::m::room
{
struct alias;
struct state;
struct members;
struct fetch;
using id = m::id::room;
id room_id;
operator const id &() const
{
return room_id;
}
bool membership(const m::id::user &, const string_view &membership = "join") const;
event::id head(event::id::buf &) const;
std::vector<std::string> barren(const int64_t &min_depth = 0) const;
uint64_t maxdepth(event::id::buf &) const;
uint64_t maxdepth() const;
event::id::buf send(json::iov &event);
event::id::buf send(const json::members &event);
void membership(const m::id::user &, json::iov &content);
void leave(const m::id::user &, json::iov &content);
void join(const m::id::user &, json::iov &content);
void create(const m::id::user &sender, const m::id::user &creator, json::iov &content);
void membership(json::iov &event, json::iov &content);
void create(json::iov &event, json::iov &content);
room(const id &room_id)
:room_id{room_id}
@ -62,3 +79,39 @@ struct ircd::m::room
:room_id{}
{}
};
namespace ircd::m::name
{
constexpr const char *const m_room_aliases {"m.room.aliases"};
constexpr const char *const m_room_canonical_alias {"m.room.canonical_alias"};
constexpr const char *const m_room_create {"m.room.create"};
constexpr const char *const m_room_join_rules {"m.room.join_rules"};
constexpr const char *const m_room_member {"m.room.member"};
constexpr const char *const m_room_power_levels {"m.room.power_levels"};
constexpr const char *const m_room_redaction {"m.room.redaction"};
constexpr const char *const m_room_message {"m.room.message"};
constexpr const char *const m_room_name {"m.room.name"};
constexpr const char *const m_room_topic {"m.room.topic"};
constexpr const char *const m_room_avatar {"m.room.avatar"};
}
struct ircd::m::room::state
:json::tuple
<
json::property<m::name::m_room_aliases, event>,
json::property<m::name::m_room_canonical_alias, event>,
json::property<m::name::m_room_create, event>,
json::property<m::name::m_room_join_rules, event>,
json::property<m::name::m_room_member, event>,
json::property<m::name::m_room_power_levels, event>,
json::property<m::name::m_room_redaction, event>,
json::property<m::name::m_room_message, event>,
json::property<m::name::m_room_name, event>,
json::property<m::name::m_room_topic, event>,
json::property<m::name::m_room_avatar, event>
>
{
struct fetch;
};
#pragma GCC diagnostic pop

View file

@ -1,8 +1,8 @@
/*
* charybdis: 21st Century IRC++d
*
* Copyright (C) 2016 Charybdis Development Team
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
* Copyright (C) 2017 Charybdis Development Team
* Copyright (C) 2017 Jason Volk <jason@zemos.net>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@ -23,22 +23,8 @@
*/
#pragma once
#define HAVE_IRCD_M_SESSION_H
#define HAVE_IRCD_M_SIG_H
namespace ircd {
namespace m {
struct session
namespace ircd::m
{
std::shared_ptr<ircd::client> client;
std::string access_token;
std::deque<std::string> tape;
std::multimap<string_view, string_view> resource;
json::object operator()(parse::buffer &pb, request &);
session(const hostport &);
};
} // namespace m
} // namespace ircd
}

View file

@ -23,9 +23,9 @@
*/
#pragma once
#define HAVE_IRCD_M_EVENTS_H
#define HAVE_IRCD_M_VM_H
namespace ircd::m::events
namespace ircd::m::vm
{
using closure = std::function<void (const event &)>;
using closure_bool = std::function<bool (const event &)>;
@ -42,3 +42,26 @@ namespace ircd::m::events
bool test(const event::query<> &, const closure_bool &);
bool test(const event::query<> &);
};
namespace ircd::m::vm
{
extern uint64_t current_sequence;
extern ctx::view<const event> inserted;
// Synchronous fetch and eval
size_t acquire(const vector_view<id::event> &, const vector_view<mutable_buffer> &);
json::object acquire(const id::event &, const mutable_buffer &);
void state(const room::id &, const event::id &);
void backfill(const room::id &, const event::id &v, const size_t &limit);
using tracer = std::function<bool (const event &, event::id::buf &)>;
void trace(const id::event &, const tracer &);
// Hypostasis
void eval(const vector_view<event> &);
void eval(const json::array &);
void eval(const event &);
event::id::buf commit(json::iov &event);
event::id::buf join(const room::id &, json::iov &iov);
}

File diff suppressed because it is too large Load diff

View file

@ -131,7 +131,7 @@ try
const bool result
{
m::events::test(query, [&request, &access_token](const m::event &event)
m::vm::test(query, [&request, &access_token](const m::event &event)
{
// Checks if the access token has expired. Tokens are expired when
// an m.room.redaction event is issued for the ircd.access_token
@ -187,7 +187,7 @@ ircd::verify_origin(client &client,
const auto verified
{
m::verify_x_matrix_authorization(authorization, method.name, uri, request.content)
m::io::verify_x_matrix_authorization(authorization, method.name, uri, request.content)
};
if(!verified)

View file

@ -41,38 +41,31 @@ try
unquote(request["visibility"])
};
const m::id::user sender_id
{
request.user_id
};
const m::id::room::buf room_id
{
m::id::generate, "localhost"
m::id::generate, my_host()
};
const m::id::user::buf sender_id
json::iov event;
json::iov content;
const json::iov::push push[]
{
m::id::generate, "localhost"
{ event, { "sender", sender_id }},
{ content, { "creator", sender_id }},
};
const m::id::event::buf create_event_id
m::room room
{
m::id::generate, "localhost",
room_id
};
const time_t origin_server_ts
{
time(NULL)
};
/*
db::object<m::db::events, m::event> event
{
create_event_id
};
room.create(event, content);
db::write
({
{ event["type"], "m.room.create" },
{ event["room_id"], room_id },
{ event["origin_server_ts"], binary_view(origin_server_ts) },
});
*/
return resource::response
{
client, http::CREATED,

View file

@ -41,14 +41,14 @@ get_events(client &client, const resource::request &request)
};
size_t i(0);
m::events::for_each(query, [&i](const auto &event)
m::vm::for_each(query, [&i](const auto &event)
{
++i;
});
size_t j(0);
json::value ret[i];
m::events::for_each(query, [&i, &j, &ret](const m::event &event)
m::vm::for_each(query, [&i, &j, &ret](const m::event &event)
{
if(j < i)
ret[j++] = event;

View file

@ -45,27 +45,15 @@ get_messages(client &client,
const resource::request &request,
const m::room::id &room_id)
{
const m::event::query<m::event::where::equal> event_in_room
const m::event::query<m::event::where::equal> query
{
{ "room_id", room_id }
};
const m::event::query<m::event::where::test> event_not_state
{
[](const auto &event)
{
return !defined(json::get<"state_key"_>(event));
}
};
const auto query
{
event_in_room && event_not_state
{ "room_id", room_id },
{ "is_state", false },
};
const size_t count
{
std::min(m::events::count(query), 128UL)
std::min(m::vm::count(query), 128UL)
};
if(!count)
@ -75,8 +63,8 @@ get_messages(client &client,
};
size_t j(0);
json::value ret[count];
m::events::for_each(query, [&count, &j, &ret]
std::vector<json::value> ret(count);
m::vm::for_each(query, [&count, &j, &ret]
(const auto &event)
{
if(j < count)
@ -87,7 +75,7 @@ get_messages(client &client,
{
client, json::members
{
{ "chunk", json::value { ret, j } }
{ "chunk", json::value { ret.data(), j } }
}
};
}
@ -102,12 +90,11 @@ get_members(client &client,
{
{ "room_id", room_id },
{ "type", "m.room.member" },
{ "state_key", "" },
};
const auto count
{
m::events::count(query)
m::vm::count(query)
};
if(!count)
@ -117,8 +104,8 @@ get_members(client &client,
};
size_t j(0);
json::value ret[count];
m::events::for_each(query, [&count, &j, &ret]
std::vector<json::value> ret(count);
m::vm::for_each(query, [&count, &j, &ret]
(const auto &event)
{
if(j < count)
@ -129,7 +116,7 @@ get_members(client &client,
{
client, json::members
{
{ "chunk", json::value { ret, j } }
{ "chunk", json::value { ret.data(), j } }
}
};
}
@ -141,7 +128,7 @@ get_state(client &client,
{
const auto count
{
m::events::count(query)
m::vm::count(query)
};
if(!count)
@ -151,8 +138,8 @@ get_state(client &client,
};
size_t j(0);
json::value ret[count];
m::events::for_each(query, [&count, &j, &ret]
std::vector<json::value> ret(count);
m::vm::for_each(query, [&count, &j, &ret]
(const auto &event)
{
if(j < count)
@ -163,7 +150,7 @@ get_state(client &client,
{
client, json::value
{
ret, j
ret.data(), j
}
};
}
@ -180,6 +167,7 @@ get_state(client &client,
{ "room_id", room_id },
{ "type", type },
{ "state_key", state_key },
{ "is_state", true },
};
return get_state(client, request, query);
@ -194,7 +182,8 @@ get_state(client &client,
const m::event::query<m::event::where::equal> query
{
{ "room_id", room_id },
{ "type", type }
{ "type", type },
{ "is_state", true },
};
return get_state(client, request, query);
@ -205,14 +194,16 @@ get_state(client &client,
const resource::request &request,
const m::room::id &room_id)
{
char type_buf[uint(256 * 1.34 + 1)];
const string_view &type
{
request.parv[2]
urldecode(request.parv[2], type_buf)
};
char skey_buf[uint(256 * 1.34 + 1)];
const string_view &state_key
{
request.parv[3]
urldecode(request.parv[3], skey_buf)
};
if(type && state_key)
@ -224,7 +215,7 @@ get_state(client &client,
const m::event::query<m::event::where::equal> query
{
{ "room_id", room_id },
{ "state_key", "" },
{ "is_state", true },
};
return get_state(client, request, query);
@ -235,29 +226,36 @@ get_context(client &client,
const resource::request &request,
const m::room::id &room_id)
{
const m::event::id &event_id
m::event::id::buf event_id
{
request.parv[2]
urldecode(request.parv[2], event_id)
};
const auto it
const m::event::query<m::event::where::equal> query
{
m::event::find(event_id)
{ "room_id", room_id },
{ "event_id", event_id },
};
if(!it)
std::string ret;
const bool found
{
m::vm::test(query, [&ret]
(const m::event &event)
{
ret = json::strung{event};
return true;
})
};
if(!found)
throw m::NOT_FOUND{"event not found"};
const auto event
{
json::string(*it)
};
return resource::response
{
client, json::members
{
{ "event", event }
{ "event", ret }
}
};
}
@ -265,10 +263,10 @@ get_context(client &client,
resource::response
get_rooms(client &client, const resource::request &request)
{
if(request.parv.size() != 2)
if(request.parv.size() < 2)
throw m::error
{
http::MULTIPLE_CHOICES, "/rooms command required"
http::MULTIPLE_CHOICES, "M_NOT_FOUND", "/rooms command required"
};
m::room::id::buf room_id
@ -276,7 +274,10 @@ get_rooms(client &client, const resource::request &request)
urldecode(request.parv[0], room_id)
};
const string_view &cmd{request.parv[1]};
const string_view &cmd
{
request.parv[1]
};
if(cmd == "context")
return get_context(client, request, room_id);
@ -306,11 +307,17 @@ put_send(client &client,
const resource::request &request,
const m::room::id &room_id)
{
if(request.parv.size() < 3)
throw m::BAD_REQUEST{"type parameter missing"};
const string_view &type
{
request.parv[2]
};
if(request.parv.size() < 4)
throw m::BAD_REQUEST{"txnid parameter missing"};
const string_view &txnid
{
request.parv[3]
@ -320,17 +327,17 @@ put_send(client &client,
const json::iov::push _type
{
event, "type", type
event, { "type", type }
};
const json::iov::push _sender
{
event, "sender", request.user_id
event, { "sender", request.user_id }
};
const json::iov::push _content
{
event, "content", json::object{request}
event, { "content", json::object{request} }
};
m::room room
@ -352,10 +359,49 @@ put_send(client &client,
};
}
resource::response
put_typing(client &client,
const resource::request &request,
const m::room::id &room_id)
{
if(request.parv.size() < 3)
throw m::BAD_REQUEST{"user_id parameter missing"};
m::user::id::buf user_id
{
urldecode(request.parv[2], user_id)
};
static const milliseconds timeout_default
{
30 * 1000
};
const auto timeout
{
request.get("timeout", timeout_default)
};
const auto typing
{
request.at<bool>("typing")
};
log::debug("%s typing: %d timeout: %ld",
user_id,
typing,
timeout.count());
return resource::response
{
client, http::OK
};
}
resource::response
put_rooms(client &client, const resource::request &request)
{
if(request.parv.size() != 2)
if(request.parv.size() < 2)
throw m::BAD_REQUEST{"/rooms command required"};
m::room::id::buf room_id
@ -371,6 +417,9 @@ put_rooms(client &client, const resource::request &request)
if(cmd == "send")
return put_send(client, request, room_id);
if(cmd == "typing")
return put_typing(client, request, room_id);
throw m::NOT_FOUND{"/rooms command not found"};
}
@ -387,19 +436,20 @@ post_receipt(client &client,
const resource::request &request,
const m::room::id &room_id)
{
if(request.parv.size() != 4)
if(request.parv.size() < 4)
throw m::BAD_REQUEST{"receipt type and event_id required"};
const string_view &receipt_type{request.parv[2]};
const string_view &event_id{request.parv[3]};
std::cout << "type: " << receipt_type << " eid: " << event_id << std::endl;
//std::cout << "type: " << receipt_type << " eid: " << event_id << std::endl;
return {};
}
resource::response
post_rooms(client &client,
const resource::request &request)
{
if(request.parv.size() != 2)
if(request.parv.size() < 2)
throw m::BAD_REQUEST{"/rooms command required"};
m::room::id::buf room_id
@ -414,6 +464,11 @@ post_rooms(client &client,
if(cmd == "receipt")
return post_receipt(client, request, room_id);
throw m::error
{
http::MULTIPLE_CHOICES, "M_NOT_FOUND", "/rooms command required"
};
}
resource::method method_post

View file

@ -133,15 +133,15 @@ sync(client &client, const resource::request &request)
{ "state_key", request.query.at("access_token") },
};
m::event::id::buf head;
if(!m::events::test(query, [&head](const auto &event)
int64_t sequence{0};
if(!m::vm::test(query, [&sequence](const auto &event)
{
const json::object &content
{
at<"content"_>(event)
};
head = unquote(content.at("event_id"));
sequence = content.at<int64_t>("sequence");
return true;
}))
throw m::NOT_FOUND{"since parameter invalid"};
@ -300,15 +300,15 @@ try
{
while(1) try
{
std::unique_lock<decltype(m::event::inserted)> lock
std::unique_lock<decltype(m::vm::inserted)> lock
{
m::event::inserted
m::vm::inserted
};
// reference to the event on the inserter's stack
const auto &event
{
m::event::inserted.wait(lock)
m::vm::inserted.wait(lock)
};
if(!syncpoll::polling.empty())
@ -485,7 +485,7 @@ initial_sync_room(client &client,
{ "is_state", true },
};
m::events::for_each(state_query, [&state](const auto &event)
m::vm::for_each(state_query, [&state](const auto &event)
{
state.emplace_back(json::strung(event));
});
@ -503,7 +503,7 @@ initial_sync_room(client &client,
{ "room_id", room.room_id },
};
m::events::query(timeline_query, [&timeline](const auto &event)
m::vm::query(timeline_query, [&timeline](const auto &event)
{
if(timeline.size() > 10)
return true;
@ -543,7 +543,7 @@ initial_sync_rooms(client &client,
std::array<std::vector<std::string>, 3> r;
std::array<std::vector<json::member>, 3> m;
m::events::for_each(query, [&r, &m, &client, &request, &full_state](const auto &event)
m::vm::for_each(query, [&r, &m, &client, &request, &full_state](const auto &event)
{
const auto &content{json::get<"content"_>(event)};
const auto &membership{unquote(content["membership"])};
@ -588,14 +588,14 @@ initial_sync(client &client,
"{}"
};
const string_view next_batch
const int64_t &next_batch
{
m::event::head
m::vm::current_sequence
};
const json::members content
{
{ "event_id", next_batch }
{ "sequence", next_batch }
};
m::user::sessions.send(

View file

@ -35,12 +35,12 @@ get_filter(client &client, const resource::request &request)
{
m::user::id::buf user_id
{
urldecode(request.parv[4], user_id)
urldecode(request.parv[0], user_id)
};
const auto &filter_id
{
request.parv[6]
request.parv[2]
};
const m::event::query<m::event::where::equal> query
@ -67,7 +67,7 @@ get_filter(client &client, const resource::request &request)
return true;
}};
if(!m::events::test(query, result))
if(!m::vm::test(query, result))
throw m::NOT_FOUND("No matching filter with that ID");
// Response already made
@ -91,7 +91,7 @@ post_filter(client &client, const resource::request::object<const m::filter> &re
// token must be authorized to make requests for this user id.
m::user::id::buf user_id
{
urldecode(request.parv[4], user_id)
urldecode(request.parv[0], user_id)
};
user_id.validate();

View file

@ -169,6 +169,24 @@ const database::descriptor events_state_key_descriptor
}
};
const database::descriptor events_is_state_descriptor
{
// name
"is_state",
// explanation
R"(### protocol note:
### developer note:
key is event_id
)",
// typing (key, value)
{
typeid(string_view), typeid(bool)
}
};
const database::descriptor events_origin_descriptor
{
// name
@ -215,31 +233,6 @@ const database::descriptor events_origin_server_ts_descriptor
}
};
const database::descriptor events_prev_ids_descriptor
{
// name
"prev_ids",
// explanation
R"(### protocol note:
FEDERATION 4.1 (INCONSISTENT)
List of (String, String, Object) Triplets
The originating homeserver, PDU ids and hashes of the most recent PDUs the homeserver was
aware of for the room when it made this PDU. ["blue.example.com","99d16afbc8", {"sha256":
"abase64encodedsha256hashshouldbe43byteslong"}]
### developer note:
key is event_id
)",
// typing (key, value)
{
typeid(string_view), typeid(string_view)
}
};
const database::descriptor events_unsigned_descriptor
{
// name
@ -457,7 +450,7 @@ const database::descriptor event_id_in_room_id
{},
// comparator - sorts from highest to lowest
ircd::db::reverse_cmp_string_view{},
{}, //ircd::db::reverse_cmp_string_view{},
// prefix transform
event_id_in,
@ -585,6 +578,7 @@ const database::description events_description
events_room_id_descriptor,
events_sender_descriptor,
events_state_key_descriptor,
events_is_state_descriptor,
events_origin_descriptor,
events_origin_server_ts_descriptor,
events_prev_ids_descriptor,

View file

@ -53,7 +53,7 @@ handle_get(client &client,
std::string my_key;
m::keys::get(my_host(), key_id, [&my_key](const auto &key)
{
my_key = json::string(key);
my_key = json::strung(key);
});
return resource::response
@ -116,7 +116,7 @@ void foop()
<< std::endl;
std::cout <<
test(json::string(json::members
test(json::strung(json::members
{
{ "one", 1 },
{ "two", "Two" }

View file

@ -50,7 +50,9 @@ get_root(client &client, const resource::request &request)
{
const auto &path
{
request.head.path?: "index.html"
!request.head.path? "index.html":
request.head.path == "/"? "index.html":
request.head.path
};
auto it(files.find(lstrip(path, '/')));