mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd:Ⓜ️:fed::well_known: Simplify interface; add opts struct.
This commit is contained in:
parent
543ff4d820
commit
888c62c156
6 changed files with 99 additions and 74 deletions
|
@ -11,23 +11,6 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_M_FED_H
|
||||
|
||||
/// Federation Interface
|
||||
namespace ircd::m::fed
|
||||
{
|
||||
id::event::buf fetch_head(const id::room &room_id, const string_view &remote, const id::user &);
|
||||
id::event::buf fetch_head(const id::room &room_id, const string_view &remote);
|
||||
|
||||
net::hostport matrix_service(net::hostport remote) noexcept;
|
||||
string_view server(const mutable_buffer &out, const string_view &origin);
|
||||
|
||||
bool errant(const string_view &origin);
|
||||
bool linked(const string_view &origin);
|
||||
bool exists(const string_view &origin);
|
||||
bool avail(const string_view &origin);
|
||||
|
||||
bool clear_error(const string_view &origin);
|
||||
}
|
||||
|
||||
#include "well_known.h"
|
||||
#include "request.h"
|
||||
#include "version.h"
|
||||
|
@ -50,6 +33,26 @@ namespace ircd::m::fed
|
|||
#include "send.h"
|
||||
#include "groups.h"
|
||||
|
||||
/// Federation Interface
|
||||
namespace ircd::m::fed
|
||||
{
|
||||
// Utils
|
||||
net::hostport matrix_service(net::hostport remote) noexcept;
|
||||
string_view server(const mutable_buffer &out, const string_view &name, const well_known::opts & = {});
|
||||
|
||||
id::event::buf fetch_head(const id::room &room_id, const string_view &remote, const id::user &);
|
||||
id::event::buf fetch_head(const id::room &room_id, const string_view &remote);
|
||||
|
||||
// Observers
|
||||
bool errant(const string_view &server_name);
|
||||
bool linked(const string_view &server_name);
|
||||
bool exists(const string_view &server_name);
|
||||
bool avail(const string_view &server_name);
|
||||
|
||||
// Control panel
|
||||
bool clear_error(const string_view &server_name);
|
||||
}
|
||||
|
||||
inline ircd::net::hostport
|
||||
ircd::m::fed::matrix_service(net::hostport remote)
|
||||
noexcept
|
||||
|
|
|
@ -52,6 +52,10 @@ struct ircd::m::fed::request::opts
|
|||
/// this request.
|
||||
const struct server::request::opts *sopts {nullptr};
|
||||
|
||||
/// Custom options to pass when resolving a server name with the well-known
|
||||
/// system.
|
||||
well_known::opts wkopts;
|
||||
|
||||
/// Whether dynamic content buffering for incoming data will be used.
|
||||
/// if false, the user supplied buffer handles all data sent from the
|
||||
/// remote server; this is faster, but if it runs out the request is
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
|
||||
namespace ircd::m::fed::well_known
|
||||
{
|
||||
string_view fetch(const mutable_buffer &out, const string_view &origin);
|
||||
string_view get(const mutable_buffer &out, const string_view &origin);
|
||||
struct opts;
|
||||
|
||||
string_view get(const mutable_buffer &, const string_view &, const opts &);
|
||||
|
||||
extern conf::item<size_t> fetch_redirects;
|
||||
extern conf::item<seconds> fetch_timeout;
|
||||
|
@ -22,3 +23,18 @@ namespace ircd::m::fed::well_known
|
|||
extern conf::item<seconds> cache_error;
|
||||
extern conf::item<seconds> cache_default;
|
||||
}
|
||||
|
||||
struct ircd::m::fed::well_known::opts
|
||||
{
|
||||
/// Whether to check the cache before making any request.
|
||||
bool cache_check {true};
|
||||
|
||||
/// Allow expired cache results to be returned without making any refresh.
|
||||
bool expired {false};
|
||||
|
||||
/// Allow a query to be made to a remote.
|
||||
bool request {true};
|
||||
|
||||
/// Whether to cache the result of any request.
|
||||
bool cache_result {true};
|
||||
};
|
||||
|
|
|
@ -1491,7 +1491,7 @@ ircd::m::fed::request::request(const mutable_buffer &buf_,
|
|||
// well-known this fails silently by just returning the input (likely).
|
||||
const string_view &target
|
||||
{
|
||||
fed::server(buf_, opts.remote)
|
||||
fed::server(buf_, opts.remote, opts.wkopts)
|
||||
};
|
||||
|
||||
// Devote the remaining buffer for HTTP as otherwise intended.
|
||||
|
@ -1615,7 +1615,8 @@ ircd::m::fed::errant(const string_view &origin)
|
|||
|
||||
ircd::string_view
|
||||
ircd::m::fed::server(const mutable_buffer &buf,
|
||||
const string_view &origin)
|
||||
const string_view &origin,
|
||||
const well_known::opts &opts)
|
||||
{
|
||||
net::hostport remote
|
||||
{
|
||||
|
@ -1625,7 +1626,7 @@ ircd::m::fed::server(const mutable_buffer &buf,
|
|||
string_view target
|
||||
{
|
||||
!port(remote)?
|
||||
well_known::get(buf, host(remote)):
|
||||
well_known::get(buf, host(remote), opts):
|
||||
origin
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace ircd::m::fed::well_known
|
|||
static void submit(request &);
|
||||
static void receive(request &);
|
||||
static int handle(request &);
|
||||
static string_view fetch(const mutable_buffer &, const string_view &);
|
||||
|
||||
extern log::log log;
|
||||
}
|
||||
|
@ -92,7 +93,8 @@ ircd::m::fed::well_known::fetch_redirects
|
|||
|
||||
ircd::string_view
|
||||
ircd::m::fed::well_known::get(const mutable_buffer &buf,
|
||||
const string_view &origin)
|
||||
const string_view &origin,
|
||||
const opts &opts)
|
||||
try
|
||||
{
|
||||
static const string_view type
|
||||
|
@ -112,7 +114,9 @@ try
|
|||
|
||||
const m::event::idx event_idx
|
||||
{
|
||||
room.get(std::nothrow, type, origin)
|
||||
likely(opts.cache_check)?
|
||||
room.get(std::nothrow, type, origin):
|
||||
0UL
|
||||
};
|
||||
|
||||
const milliseconds origin_server_ts
|
||||
|
@ -153,7 +157,7 @@ try
|
|||
};
|
||||
|
||||
// Branch on valid cache hit to return result.
|
||||
if(valid && !expired)
|
||||
if(valid && (!expired || opts.expired))
|
||||
{
|
||||
char tmbuf[48];
|
||||
log::debug
|
||||
|
@ -168,15 +172,16 @@ try
|
|||
return cached;
|
||||
}
|
||||
|
||||
// Crucial value that will provide us with a return string for this
|
||||
// function in any case. This is obtained by either using the value
|
||||
// found in cache or making a network query for a new value. expired=true
|
||||
// when a network query needs to be made, otherwise we can return the
|
||||
// cached value. If the network query fails, this value is still defaulted
|
||||
// as the origin string to return and we'll also cache that too.
|
||||
const string_view fetched
|
||||
{
|
||||
opts.request?
|
||||
fetch(buf + size(cached), origin):
|
||||
string_view{}
|
||||
};
|
||||
|
||||
const string_view delegated
|
||||
{
|
||||
fetch(buf + size(cached), origin)
|
||||
data(buf), move(buf, fetched?: origin)
|
||||
};
|
||||
|
||||
// Conditions for valid expired cache hit w/ failure to reacquire.
|
||||
|
@ -201,39 +206,43 @@ try
|
|||
timef(tmbuf, expires, localtime),
|
||||
};
|
||||
|
||||
assert(opts.cache_check);
|
||||
return cached;
|
||||
}
|
||||
|
||||
// Any time the well-known result is the same as the origin (that
|
||||
// includes legitimate errors where fetch_well_known() returns the
|
||||
// origin to default) we consider that an error and use the error
|
||||
// TTL value. Sorry, no exponential backoff implemented yet.
|
||||
const auto cache_ttl
|
||||
if(likely(opts.request && opts.cache_result))
|
||||
{
|
||||
origin == delegated?
|
||||
seconds(cache_error).count():
|
||||
seconds(cache_default).count()
|
||||
};
|
||||
|
||||
// Write our record to the cache room; note that this doesn't really
|
||||
// match the format of other DNS records in this room since it's a bit
|
||||
// simpler, but we don't share the ircd.dns.rr type prefix anyway.
|
||||
const auto cache_id
|
||||
{
|
||||
m::send(room, m::me(), type, origin, json::members
|
||||
// Any time the well-known result is the same as the origin (that
|
||||
// includes legitimate errors where fetch_well_known() returns the
|
||||
// origin to default) we consider that an error and use the error
|
||||
// TTL value. Sorry, no exponential backoff implemented yet.
|
||||
const auto cache_ttl
|
||||
{
|
||||
{ "ttl", cache_ttl },
|
||||
{ "m.server", delegated },
|
||||
})
|
||||
};
|
||||
origin == delegated?
|
||||
seconds(cache_error).count():
|
||||
seconds(cache_default).count()
|
||||
};
|
||||
|
||||
log::debug
|
||||
{
|
||||
log, "%s caching delegation to %s to cache in %s",
|
||||
origin,
|
||||
delegated,
|
||||
string_view{cache_id},
|
||||
};
|
||||
// Write our record to the cache room; note that this doesn't really
|
||||
// match the format of other DNS records in this room since it's a bit
|
||||
// simpler, but we don't share the ircd.dns.rr type prefix anyway.
|
||||
const auto cache_id
|
||||
{
|
||||
m::send(room, m::me(), type, origin, json::members
|
||||
{
|
||||
{ "ttl", cache_ttl },
|
||||
{ "m.server", delegated },
|
||||
})
|
||||
};
|
||||
|
||||
log::debug
|
||||
{
|
||||
log, "%s caching delegation to %s to cache in %s",
|
||||
origin,
|
||||
delegated,
|
||||
string_view{cache_id},
|
||||
};
|
||||
}
|
||||
|
||||
return delegated;
|
||||
}
|
||||
|
@ -289,10 +298,7 @@ try
|
|||
}
|
||||
}
|
||||
|
||||
return string_view
|
||||
{
|
||||
data(user_buf), move(user_buf, target)
|
||||
};
|
||||
return {};
|
||||
}
|
||||
catch(const ctx::interrupted &)
|
||||
{
|
||||
|
@ -307,10 +313,7 @@ catch(const std::exception &e)
|
|||
e.what(),
|
||||
};
|
||||
|
||||
return string_view
|
||||
{
|
||||
data(user_buf), move(user_buf, target)
|
||||
};
|
||||
return {};
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -386,12 +389,6 @@ ircd::m::fed::well_known::receive(request &req)
|
|||
};
|
||||
}
|
||||
|
||||
/// Launch requestReturn a tuple of the HTTP code, any Location header, and the response
|
||||
/// content. These values are unconditional if this function doesn't throw,
|
||||
/// but if there's no Location header and/or content then those will be empty
|
||||
/// string_view's. This function is intended to be run in a loop by the caller
|
||||
/// to chase redirection. No HTTP codes will throw from here; server and
|
||||
/// network errors (and others) will.
|
||||
void
|
||||
ircd::m::fed::well_known::submit(request &req)
|
||||
{
|
||||
|
|
|
@ -15996,9 +15996,13 @@ console_cmd__well_known__matrix__server(opt &out, const string_view &line)
|
|||
1_KiB
|
||||
};
|
||||
|
||||
m::fed::well_known::opts opts;
|
||||
opts.cache_check = false;
|
||||
opts.cache_result = false;
|
||||
|
||||
const net::hostport result
|
||||
{
|
||||
m::fed::well_known::fetch(buf, remote)
|
||||
m::fed::well_known::get(buf, remote, opts)
|
||||
};
|
||||
|
||||
out << result << std::endl;
|
||||
|
|
Loading…
Reference in a new issue