mirror of
https://github.com/matrix-construct/construct
synced 2024-06-11 06:28:55 +02:00
ircd::resource: Minor reorg class layout / opts.
This commit is contained in:
parent
cbbfbcac72
commit
d49b3ba7dd
|
@ -33,8 +33,7 @@ struct ircd::resource
|
|||
static std::map<string_view, resource *, iless> resources;
|
||||
|
||||
string_view path;
|
||||
string_view description;
|
||||
enum flag flags;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
std::map<string_view, method *> methods;
|
||||
unique_const_iterator<decltype(resources)> resources_it;
|
||||
|
||||
|
@ -48,7 +47,7 @@ struct ircd::resource
|
|||
|
||||
void operator()(client &, const http::request::head &, const string_view &content_partial);
|
||||
|
||||
resource(const string_view &path, const opts &);
|
||||
resource(const string_view &path, struct opts);
|
||||
resource(const string_view &path);
|
||||
resource() = default;
|
||||
virtual ~resource() noexcept;
|
||||
|
@ -84,6 +83,51 @@ struct ircd::resource::opts
|
|||
};
|
||||
};
|
||||
|
||||
struct ircd::resource::method
|
||||
{
|
||||
enum flag :uint;
|
||||
struct opts;
|
||||
using handler = std::function<response (client &, request &)>;
|
||||
|
||||
struct resource *resource;
|
||||
string_view name;
|
||||
handler function;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
unique_const_iterator<decltype(resource::methods)> methods_it;
|
||||
|
||||
public:
|
||||
virtual response operator()(client &, request &);
|
||||
|
||||
method(struct resource &, const string_view &name, handler, struct opts);
|
||||
method(struct resource &, const string_view &name, handler);
|
||||
virtual ~method() noexcept;
|
||||
};
|
||||
|
||||
enum ircd::resource::method::flag
|
||||
:uint
|
||||
{
|
||||
REQUIRES_AUTH = 0x01,
|
||||
RATE_LIMITED = 0x02,
|
||||
VERIFY_ORIGIN = 0x04,
|
||||
CONTENT_DISCRETION = 0x08,
|
||||
};
|
||||
|
||||
struct ircd::resource::method::opts
|
||||
{
|
||||
flag flags {(flag)0};
|
||||
|
||||
/// Timeout specific to this resource.
|
||||
seconds timeout {30s};
|
||||
|
||||
/// The maximum size of the Content-Length for this method. Anything
|
||||
/// larger will be summarily rejected with a 413.
|
||||
size_t payload_max {128_KiB};
|
||||
|
||||
/// MIME type; first part is the Registry (i.e application) and second
|
||||
/// part is the format (i.e json). Empty value means nothing rejected.
|
||||
std::pair<string_view, string_view> mime;
|
||||
};
|
||||
|
||||
struct ircd::resource::request
|
||||
:json::object
|
||||
{
|
||||
|
@ -185,45 +229,3 @@ struct ircd::resource::response::chunked
|
|||
chunked() = default;
|
||||
~chunked() noexcept;
|
||||
};
|
||||
|
||||
struct ircd::resource::method
|
||||
{
|
||||
using handler = std::function<response (client &, request &)>;
|
||||
|
||||
enum flag
|
||||
{
|
||||
REQUIRES_AUTH = 0x01,
|
||||
RATE_LIMITED = 0x02,
|
||||
VERIFY_ORIGIN = 0x04,
|
||||
CONTENT_DISCRETION = 0x08,
|
||||
};
|
||||
|
||||
struct opts
|
||||
{
|
||||
flag flags {(flag)0};
|
||||
|
||||
/// Timeout specific to this resource.
|
||||
seconds timeout {30s};
|
||||
|
||||
/// The maximum size of the Content-Length for this method. Anything
|
||||
/// larger will be summarily rejected with a 413.
|
||||
size_t payload_max {128_KiB};
|
||||
|
||||
/// MIME type; first part is the Registry (i.e application) and second
|
||||
/// part is the format (i.e json). Empty value means nothing rejected.
|
||||
std::pair<string_view, string_view> mime;
|
||||
};
|
||||
|
||||
string_view name;
|
||||
struct resource *resource;
|
||||
handler function;
|
||||
struct opts opts;
|
||||
unique_const_iterator<decltype(resource::methods)> methods_it;
|
||||
|
||||
public:
|
||||
virtual response operator()(client &, request &);
|
||||
|
||||
method(struct resource &, const string_view &name, const handler &, const struct opts &);
|
||||
method(struct resource &, const string_view &name, const handler &);
|
||||
virtual ~method() noexcept;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ ircd::resource::find(const string_view &path_)
|
|||
|
||||
--it;
|
||||
rpath = it->first;
|
||||
if(~it->second->flags & it->second->DIRECTORY)
|
||||
if(~it->second->opts->flags & it->second->DIRECTORY)
|
||||
continue;
|
||||
|
||||
// If the closest directory still doesn't match hand this off to the
|
||||
|
@ -75,13 +75,13 @@ ircd::resource::find(const string_view &path_)
|
|||
|
||||
// Check if the resource is a directory; if not, it can only
|
||||
// handle exact path matches.
|
||||
if(~it->second->flags & it->second->DIRECTORY && path != rpath)
|
||||
if(~it->second->opts->flags & it->second->DIRECTORY && path != rpath)
|
||||
throw http::error
|
||||
{
|
||||
http::code::NOT_FOUND
|
||||
};
|
||||
|
||||
if(it->second->flags & it->second->DIRECTORY)
|
||||
if(it->second->opts->flags & it->second->DIRECTORY)
|
||||
{
|
||||
const auto rem(lstrip(path, rpath));
|
||||
if(!empty(rem) && !startswith(rem, '/'))
|
||||
|
@ -101,19 +101,21 @@ ircd::resource::find(const string_view &path_)
|
|||
ircd::resource::resource(const string_view &path)
|
||||
:resource
|
||||
{
|
||||
path, opts{}
|
||||
path, {}
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::resource::resource(const string_view &path,
|
||||
const opts &opts)
|
||||
struct opts opts)
|
||||
:path
|
||||
{
|
||||
rstrip(path, '/')
|
||||
}
|
||||
,description{opts.description}
|
||||
,flags{opts.flags}
|
||||
,opts
|
||||
{
|
||||
std::make_unique<const struct opts>(std::move(opts))
|
||||
}
|
||||
,resources_it{[this]
|
||||
{
|
||||
const auto iit
|
||||
|
@ -189,7 +191,7 @@ ircd::authenticate(client &client,
|
|||
|
||||
const bool requires_auth
|
||||
{
|
||||
method.opts.flags & method.REQUIRES_AUTH
|
||||
method.opts->flags & method.REQUIRES_AUTH
|
||||
};
|
||||
|
||||
if(!request.access_token && requires_auth)
|
||||
|
@ -239,7 +241,7 @@ try
|
|||
{
|
||||
const bool required
|
||||
{
|
||||
method.opts.flags & method.VERIFY_ORIGIN
|
||||
method.opts->flags & method.VERIFY_ORIGIN
|
||||
};
|
||||
|
||||
const auto authorization
|
||||
|
@ -360,7 +362,7 @@ ircd::resource::operator()(client &client,
|
|||
};
|
||||
|
||||
// Bail out if the method limited the amount of content and it was exceeded.
|
||||
if(head.content_length > method.opts.payload_max)
|
||||
if(head.content_length > method.opts->payload_max)
|
||||
throw http::error
|
||||
{
|
||||
http::PAYLOAD_TOO_LARGE
|
||||
|
@ -368,12 +370,12 @@ ircd::resource::operator()(client &client,
|
|||
|
||||
// Check if the resource method wants a specific MIME type. If no option
|
||||
// is given by the resource then any Content-Type by the client will pass.
|
||||
if(method.opts.mime.first)
|
||||
if(method.opts->mime.first)
|
||||
{
|
||||
const auto &ct(split(head.content_type, ';'));
|
||||
const auto &supplied(split(ct.first, '/'));
|
||||
const auto &charset(ct.second);
|
||||
const auto &required(method.opts.mime);
|
||||
const auto &required(method.opts->mime);
|
||||
if(required.first != supplied.first
|
||||
||(required.second && required.second != supplied.second))
|
||||
throw http::error
|
||||
|
@ -387,7 +389,7 @@ ircd::resource::operator()(client &client,
|
|||
// disable this in its options structure.
|
||||
const net::scope_timeout timeout
|
||||
{
|
||||
*client.sock, method.opts.timeout, [&client, &head]
|
||||
*client.sock, method.opts->timeout, [&client, &head]
|
||||
(const bool &timed_out)
|
||||
{
|
||||
if(!timed_out)
|
||||
|
@ -433,7 +435,7 @@ ircd::resource::operator()(client &client,
|
|||
content_partial
|
||||
};
|
||||
|
||||
if(content_remain && ~method.opts.flags & method.CONTENT_DISCRETION)
|
||||
if(content_remain && ~method.opts->flags & method.CONTENT_DISCRETION)
|
||||
{
|
||||
// Copy any partial content to the final contiguous allocated buffer;
|
||||
client.content_buffer = unique_buffer<mutable_buffer>{head.content_length};
|
||||
|
@ -585,24 +587,40 @@ ircd::resource::allow_methods_list(const mutable_buffer &buf)
|
|||
return { data(buf), len };
|
||||
}
|
||||
|
||||
//
|
||||
// method::method
|
||||
//
|
||||
|
||||
ircd::resource::method::method(struct resource &resource,
|
||||
const string_view &name,
|
||||
const handler &handler)
|
||||
handler function)
|
||||
:method
|
||||
{
|
||||
resource, name, handler, {}
|
||||
resource, name, std::move(function), {}
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::resource::method::method(struct resource &resource,
|
||||
const string_view &name,
|
||||
const handler &handler,
|
||||
const struct opts &opts)
|
||||
:name{name}
|
||||
,resource{&resource}
|
||||
,function{handler}
|
||||
,opts{opts}
|
||||
handler function,
|
||||
struct opts opts)
|
||||
:resource
|
||||
{
|
||||
&resource
|
||||
}
|
||||
,name
|
||||
{
|
||||
name
|
||||
}
|
||||
,function
|
||||
{
|
||||
std::move(function)
|
||||
}
|
||||
,opts
|
||||
{
|
||||
std::make_unique<const struct opts>(std::move(opts))
|
||||
}
|
||||
,methods_it{[this, &name]
|
||||
{
|
||||
const auto iit
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
resource
|
||||
join_resource
|
||||
{
|
||||
"/_matrix/client/r0/join/", resource::opts
|
||||
"/_matrix/client/r0/join/",
|
||||
{
|
||||
"(7.4.2.3) Join room_id or alias.",
|
||||
resource::DIRECTORY,
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
ircd::resource
|
||||
keys_upload_resource
|
||||
{
|
||||
"/_matrix/client/unstable/keys/upload/", resource::opts
|
||||
"/_matrix/client/unstable/keys/upload/",
|
||||
{
|
||||
"(11.10.2.1) Keys Upload",
|
||||
resource::DIRECTORY,
|
||||
|
@ -29,7 +29,7 @@ keys_upload_resource
|
|||
ircd::resource
|
||||
keys_query_resource
|
||||
{
|
||||
"/_matrix/client/unstable/keys/query", resource::opts
|
||||
"/_matrix/client/unstable/keys/query",
|
||||
{
|
||||
"(11.10.2.2) Keys Query",
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
ircd::resource
|
||||
presence_resource
|
||||
{
|
||||
"/_matrix/client/r0/presence/", resource::opts
|
||||
"/_matrix/client/r0/presence/",
|
||||
{
|
||||
"(11.6.2) Presence",
|
||||
resource::DIRECTORY,
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
ircd::resource
|
||||
pushers_resource
|
||||
{
|
||||
"/_matrix/client/r0/pushers/", resource::opts
|
||||
"/_matrix/client/r0/pushers/",
|
||||
{
|
||||
"(11.12.1) Pushers",
|
||||
resource::DIRECTORY,
|
||||
|
|
|
@ -19,7 +19,7 @@ IRCD_MODULE
|
|||
resource
|
||||
versions_resource
|
||||
{
|
||||
"/_matrix/client/versions", resource::opts
|
||||
"/_matrix/client/versions",
|
||||
{
|
||||
"(2.1) Gets the versions of the specification supported by the server."
|
||||
}
|
||||
|
|
|
@ -3891,17 +3891,17 @@ console_cmd__resource(opt &out, const string_view &line)
|
|||
{
|
||||
const auto &r(*p.second);
|
||||
out << '`' << p.first << '\''
|
||||
<< (r.flags & resource::DIRECTORY? " DIRECTORY" : "")
|
||||
<< (r.opts->flags & resource::DIRECTORY? " DIRECTORY" : "")
|
||||
<< std::endl;
|
||||
|
||||
for(const auto &mp : p.second->methods)
|
||||
{
|
||||
const auto &m(*mp.second);
|
||||
out << mp.first
|
||||
<< (m.opts.flags & resource::method::REQUIRES_AUTH? " REQUIRES_AUTH" : "")
|
||||
<< (m.opts.flags & resource::method::RATE_LIMITED? " RATE_LIMITED" : "")
|
||||
<< (m.opts.flags & resource::method::VERIFY_ORIGIN? " VERIFY_ORIGIN" : "")
|
||||
<< (m.opts.flags & resource::method::CONTENT_DISCRETION? " CONTENT_DISCRETION" : "")
|
||||
<< (m.opts->flags & resource::method::REQUIRES_AUTH? " REQUIRES_AUTH" : "")
|
||||
<< (m.opts->flags & resource::method::RATE_LIMITED? " RATE_LIMITED" : "")
|
||||
<< (m.opts->flags & resource::method::VERIFY_ORIGIN? " VERIFY_ORIGIN" : "")
|
||||
<< (m.opts->flags & resource::method::CONTENT_DISCRETION? " CONTENT_DISCRETION" : "")
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue