diff --git a/include/ircd/m/v1/send.h b/include/ircd/m/v1/send.h new file mode 100644 index 000000000..328aa1be6 --- /dev/null +++ b/include/ircd/m/v1/send.h @@ -0,0 +1,34 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// 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. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_M_V1_SEND_H + +namespace ircd::m::v1 +{ + struct send; +}; + +struct ircd::m::v1::send +:server::request +{ + struct opts; + + send(const string_view &txnid, const const_buffer &content, const mutable_buffer &head, opts); +}; + +struct ircd::m::v1::send::opts +{ + net::hostport remote; + m::request request; + server::out out; + server::in in; + const struct server::request::opts *sopts {nullptr}; +}; diff --git a/include/ircd/m/v1/send_join.h b/include/ircd/m/v1/send_join.h new file mode 100644 index 000000000..705e56496 --- /dev/null +++ b/include/ircd/m/v1/send_join.h @@ -0,0 +1,41 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// 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. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_M_V1_SEND_JOIN_H + +namespace ircd::m::v1 +{ + struct send_join; +}; + +struct ircd::m::v1::send_join +:server::request +{ + struct opts; + + static const opts default_opts; + + operator json::array() const + { + return json::array{in.content}; + } + + send_join(const room::id &, const user::id &, const const_buffer &, const mutable_buffer &, opts); +}; + +struct ircd::m::v1::send_join::opts +{ + net::hostport remote; + m::request request; + server::out out; + server::in in; + const struct server::request::opts *sopts {nullptr}; +}; diff --git a/include/ircd/m/v1/v1.h b/include/ircd/m/v1/v1.h index bf809cbf0..a2805bdcf 100644 --- a/include/ircd/m/v1/v1.h +++ b/include/ircd/m/v1/v1.h @@ -12,6 +12,8 @@ #define HAVE_IRCD_M_V1_H #include "make_join.h" +#include "send_join.h" #include "event.h" #include "state.h" #include "backfill.h" +#include "send.h" diff --git a/ircd/m/v1.cc b/ircd/m/v1.cc index 5476e6ba7..dd5f49314 100644 --- a/ircd/m/v1.cc +++ b/ircd/m/v1.cc @@ -10,6 +10,68 @@ #include +/////////////////////////////////////////////////////////////////////////////// +// +// v1/send.h +// + +ircd::m::v1::send::send(const string_view &txnid, + const const_buffer &content, + const mutable_buffer &buf, + opts opts) +:server::request{[&] +{ + assert(!!opts.remote); + + assert(!size(opts.out.content)); + opts.out.content = content; + + assert(!defined(json::get<"content"_>(opts.request))); + json::get<"content"_>(opts.request) = json::object{opts.out.content}; + + if(!defined(json::get<"origin"_>(opts.request))) + json::get<"origin"_>(opts.request) = my_host(); + + if(!defined(json::get<"destination"_>(opts.request))) + json::get<"destination"_>(opts.request) = host(opts.remote); + + if(!defined(json::get<"uri"_>(opts.request))) + { + thread_local char urlbuf[1024], txnidbuf[512]; + json::get<"uri"_>(opts.request) = + { + fmt::sprintf + { + urlbuf, "/_matrix/federation/v1/send/%s/", + //url::encode(txnid, txnidbuf), + txnid + } + }; + } + + json::get<"method"_>(opts.request) = "PUT"; + opts.out.head = opts.request(buf); + + if(!size(opts.in)) + { + const auto in_max + { + std::max(ssize_t(size(buf) - size(opts.out.head)), ssize_t(0)) + }; + + assert(in_max >= ssize_t(size(buf) / 2)); + opts.in.head = { data(buf) + size(opts.out.head), size_t(in_max) }; + opts.in.content = opts.in.head; + } + + return server::request + { + opts.remote, std::move(opts.out), std::move(opts.in), opts.sopts + }; +}()} +{ +} + /////////////////////////////////////////////////////////////////////////////// // // v1/backfill.h @@ -41,7 +103,7 @@ ircd::m::v1::backfill::backfill(const room::id &room_id, room_id, m::me.user_id, buf }; - request.wait(); + request.get(); const json::object proto { request.in.content @@ -78,7 +140,7 @@ ircd::m::v1::backfill::backfill(const room::id &room_id, if(!defined(json::get<"uri"_>(opts.request))) { - thread_local char urlbuf[1024], ridbuf[768], eidbuf[768]; + thread_local char urlbuf[2048], ridbuf[768], eidbuf[768]; json::get<"uri"_>(opts.request) = { fmt::sprintf @@ -145,7 +207,7 @@ ircd::m::v1::state::state(const room::id &room_id, room_id, m::me.user_id, buf }; - request.wait(); + request.get(); const json::object proto { request.in.content @@ -182,7 +244,7 @@ ircd::m::v1::state::state(const room::id &room_id, if(!defined(json::get<"uri"_>(opts.request))) { - thread_local char urlbuf[1024], ridbuf[768], eidbuf[768]; + thread_local char urlbuf[2048], ridbuf[768], eidbuf[768]; json::get<"uri"_>(opts.request) = { fmt::sprintf @@ -291,6 +353,73 @@ ircd::m::v1::event::event(const m::event::id &event_id, { } +/////////////////////////////////////////////////////////////////////////////// +// +// v1/send_join.h +// + +decltype(ircd::m::v1::send_join::default_opts) +ircd::m::v1::send_join::default_opts +{}; + +ircd::m::v1::send_join::send_join(const room::id &room_id, + const user::id &user_id, + const const_buffer &content, + const mutable_buffer &buf, + opts opts) +:server::request{[&] +{ + assert(!!opts.remote); + + assert(!size(opts.out.content)); + opts.out.content = content; + + assert(!defined(json::get<"content"_>(opts.request))); + json::get<"content"_>(opts.request) = json::object{opts.out.content}; + + if(!defined(json::get<"origin"_>(opts.request))) + json::get<"origin"_>(opts.request) = my_host(); + + if(!defined(json::get<"destination"_>(opts.request))) + json::get<"destination"_>(opts.request) = host(opts.remote); + + if(!defined(json::get<"uri"_>(opts.request))) + { + thread_local char urlbuf[2048], ridbuf[768], uidbuf[768]; + json::get<"uri"_>(opts.request) = + { + fmt::sprintf + { + urlbuf, "/_matrix/federation/v1/send_join/%s/%s", + url::encode(room_id, ridbuf), + url::encode(user_id, uidbuf) + } + }; + } + + json::get<"method"_>(opts.request) = "PUT"; + opts.out.head = opts.request(buf); + + if(!size(opts.in)) + { + const auto in_max + { + std::max(ssize_t(size(buf) - size(opts.out.head)), ssize_t(0)) + }; + + assert(in_max >= ssize_t(size(buf) / 2)); + opts.in.head = { data(buf) + size(opts.out.head), size_t(in_max) }; + opts.in.content = opts.in.head; + } + + return server::request + { + opts.remote, std::move(opts.out), std::move(opts.in), opts.sopts + }; +}()} +{ +} + /////////////////////////////////////////////////////////////////////////////// // // v1/make_join.h