0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-19 16:30:52 +01:00
construct/include/ircd/m/io.h
2017-11-30 11:23:47 -08:00

288 lines
6.7 KiB
C++

/*
* 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
/// Interface to the matrix protocol IO bus making local and network queries.
///
/// This system is the backplane for the m::vm or anything else that needs to
/// get events, however it can, as best as it can, at a high level using a
/// convenient interface. Users of this interface fill out and maintain a
/// control structure (or several) on their stack and then make calls which may
/// yield their ircd::ctx with report given in the control structure. The
/// default behavior will try to hide all of the boilerplate from the user
/// when it comes to figuring out where to make a query and then verifying the
/// results. The control structure offers the ability to tailor very low level
/// aspects of the request and change behavior if desired.
///
/// For acquisition, this interface provides the means to find an event, or
/// set of events by first querying the local db and caches and then making
/// network queries using the matrix protocol endpoints.
///
/// For transmission, this interface provides the means to send events et al
/// to other servers; no local/database writes will happen here, just network.
///
/// There are several variations of requests to the bus; each reflects the matrix
/// protocol endpoint which is apt to best fulfill the request.
///
/// * fetch event - request for event by ID (/event)
/// * fetch room - request for vector of room events (/backfill)
/// * fetch room state - request for set of state events (/state)
///
/// Unless the control structure specifies otherwise, result data for these
/// requests may be filled entirely locally, remotely, or partially from
/// either.
///
namespace ircd::m::io
{
struct sync;
struct fetch;
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 many requests
size_t acquire(vector_view<event::fetch>);
size_t acquire(vector_view<room::fetch>);
size_t acquire(vector_view<room::state::fetch>);
// Synchronous acquire single request
json::object acquire(event::fetch &);
json::array acquire(room::fetch &);
json::array acquire(room::state::fetch &);
// Synchronous release
size_t release(vector_view<event::sync>);
void release(event::sync &);
// Convenience
json::object get(const event::id &, const mutable_buffer &);
}
namespace ircd::m
{
using io::get;
using io::session;
using io::request;
using io::response;
}
//
// Fetch & Sync base
//
struct ircd::m::io::fetch
{
struct opts;
static const opts defaults;
mutable_buffer buf;
const struct opts *opts {&defaults};
bool local_result {false};
std::exception_ptr error;
};
struct ircd::m::io::fetch::opts
{
net::remote hint;
uint64_t limit {256};
};
struct ircd::m::io::sync
{
struct opts;
static const opts defaults;
const_buffer buf;
const struct opts *opts {&defaults};
std::exception_ptr error;
};
struct ircd::m::io::sync::opts
{
net::remote hint;
};
//
// Event
//
struct ircd::m::event::fetch
:io::fetch
{
// out
event::id event_id;
// in
json::object pdu;
fetch(const event::id &event_id,
const mutable_buffer &buf,
const struct opts *const &opts = &defaults)
:io::fetch{buf, opts}
,event_id{event_id}
{}
fetch() = default;
};
struct ircd::m::event::sync
:io::sync
{
// out
string_view destination;
uint64_t txnid {0};
// in
std::exception_ptr error;
sync(const string_view &destination,
const const_buffer &buf,
const struct opts *const &opts = &defaults)
:io::sync{buf, opts}
,destination{destination}
{}
sync() = default;
};
//
// Room (backfill)
//
struct ircd::m::room::fetch
:io::fetch
{
// out
event::id event_id;
room::id room_id;
// in
json::array pdus;
json::array auth_chain;
fetch(const event::id &event_id,
const room::id &room_id,
const mutable_buffer &buf,
const struct opts *const &opts = &defaults)
:io::fetch{buf, opts}
,event_id{event_id}
,room_id{room_id}
{}
fetch() = default;
};
//
// Room (state)
//
struct ircd::m::room::state::fetch
:io::fetch
{
// out
event::id event_id;
room::id room_id;
// in
json::array pdus;
json::array auth_chain;
fetch(const event::id &event_id,
const room::id &room_id,
const mutable_buffer &buf,
const struct opts *const &opts = &defaults)
:io::fetch{buf, opts}
,event_id{event_id}
,room_id{room_id}
{}
fetch() = default;
};
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;
};