mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 15:04:10 +01:00
ircd: Split up resource.h.
This commit is contained in:
parent
476f198075
commit
f0ce1cdcae
7 changed files with 298 additions and 248 deletions
|
@ -55,7 +55,7 @@
|
|||
#include "net/net.h"
|
||||
#include "server/server.h"
|
||||
#include "m/m.h"
|
||||
#include "resource.h"
|
||||
#include "resource/resource.h"
|
||||
#include "client.h"
|
||||
|
||||
/// \brief Internet Relay Chat daemon. This is the principal namespace for IRCd.
|
||||
|
|
|
@ -1,244 +0,0 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_H
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
struct client;
|
||||
struct resource;
|
||||
}
|
||||
|
||||
/// The target of an HTTP request specified by clients with a path.
|
||||
///
|
||||
struct ircd::resource
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
||||
enum flag :uint;
|
||||
struct opts;
|
||||
struct method;
|
||||
struct request;
|
||||
struct response;
|
||||
|
||||
static log::log log;
|
||||
static std::map<string_view, resource *, iless> resources;
|
||||
|
||||
string_view path;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
std::map<string_view, method *> methods;
|
||||
unique_const_iterator<decltype(resources)> resources_it;
|
||||
|
||||
string_view allow_methods_list(const mutable_buffer &buf) const;
|
||||
|
||||
public:
|
||||
method &operator[](const string_view &name) const;
|
||||
|
||||
resource(const string_view &path, struct opts);
|
||||
resource(const string_view &path);
|
||||
resource() = default;
|
||||
~resource() noexcept;
|
||||
|
||||
static resource &find(const string_view &path);
|
||||
};
|
||||
|
||||
enum ircd::resource::flag
|
||||
:uint
|
||||
{
|
||||
DIRECTORY = 0x01,
|
||||
};
|
||||
|
||||
struct ircd::resource::opts
|
||||
{
|
||||
/// developer's literal description of the resource
|
||||
string_view description
|
||||
{
|
||||
"no description"
|
||||
};
|
||||
|
||||
/// flags for the resource
|
||||
flag flags
|
||||
{
|
||||
flag(0)
|
||||
};
|
||||
|
||||
/// parameter count limits (DIRECTORY only)
|
||||
std::pair<short, short> parc
|
||||
{
|
||||
0, // minimum params
|
||||
15 // maximum params
|
||||
};
|
||||
};
|
||||
|
||||
struct ircd::resource::method
|
||||
{
|
||||
enum flag :uint;
|
||||
struct opts;
|
||||
struct stats;
|
||||
using handler = std::function<response (client &, request &)>;
|
||||
|
||||
static conf::item<bool> x_matrix_verify_origin;
|
||||
static conf::item<bool> x_matrix_verify_destination;
|
||||
|
||||
struct resource *resource;
|
||||
string_view name;
|
||||
handler function;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
std::unique_ptr<struct stats> stats;
|
||||
unique_const_iterator<decltype(resource::methods)> methods_it;
|
||||
|
||||
string_view verify_origin(client &, request &) const;
|
||||
string_view authenticate(client &, request &) const;
|
||||
void handle_timeout(client &) const;
|
||||
void call_handler(client &, request &);
|
||||
|
||||
public:
|
||||
void operator()(client &, const http::request::head &, const string_view &content_partial);
|
||||
|
||||
method(struct resource &, const string_view &name, handler, struct opts);
|
||||
method(struct resource &, const string_view &name, handler);
|
||||
~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::method::stats
|
||||
{
|
||||
uint64_t requests {0}; // The method was found and called.
|
||||
uint64_t timeouts {0}; // The method's timeout was exceeded.
|
||||
uint64_t completions {0}; // The handler returned without throwing.
|
||||
uint64_t internal_errors {0}; // The handler threw a very bad exception.
|
||||
};
|
||||
|
||||
struct ircd::resource::request
|
||||
:json::object
|
||||
{
|
||||
template<class> struct object;
|
||||
|
||||
http::request::head head;
|
||||
string_view content;
|
||||
http::query::string query;
|
||||
string_view origin;
|
||||
string_view access_token;
|
||||
vector_view<string_view> parv;
|
||||
string_view param[8];
|
||||
m::user::id::buf user_id;
|
||||
m::node::id::buf node_id;
|
||||
|
||||
request(const http::request::head &head,
|
||||
const string_view &content)
|
||||
:json::object{content}
|
||||
,head{head}
|
||||
,content{content}
|
||||
,query{this->head.query}
|
||||
{}
|
||||
|
||||
request() = default;
|
||||
};
|
||||
|
||||
template<class tuple>
|
||||
struct ircd::resource::request::object
|
||||
:tuple
|
||||
{
|
||||
resource::request &r;
|
||||
const http::request::head &head;
|
||||
const string_view &content;
|
||||
const http::query::string &query;
|
||||
const decltype(r.origin) &origin;
|
||||
const decltype(r.user_id) &user_id;
|
||||
const decltype(r.node_id) &node_id;
|
||||
const decltype(r.access_token) &access_token;
|
||||
const vector_view<string_view> &parv;
|
||||
const json::object &body;
|
||||
|
||||
object(resource::request &r)
|
||||
:tuple{r}
|
||||
,r{r}
|
||||
,head{r.head}
|
||||
,content{r.content}
|
||||
,query{r.query}
|
||||
,origin{r.origin}
|
||||
,user_id{r.user_id}
|
||||
,node_id{r.node_id}
|
||||
,access_token{r.access_token}
|
||||
,parv{r.parv}
|
||||
,body{r}
|
||||
{}
|
||||
};
|
||||
|
||||
struct ircd::resource::response
|
||||
{
|
||||
struct chunked;
|
||||
|
||||
static const size_t HEAD_BUF_SZ;
|
||||
static conf::item<std::string> access_control_allow_origin;
|
||||
|
||||
response(client &, const http::code &, const string_view &content_type, const size_t &content_length, const string_view &headers = {});
|
||||
response(client &, const string_view &str, const string_view &content_type, const http::code &, const vector_view<const http::header> &);
|
||||
response(client &, const string_view &str, const string_view &content_type, const http::code & = http::OK, const string_view &headers = {});
|
||||
response(client &, const json::object &str, const http::code & = http::OK);
|
||||
response(client &, const json::array &str, const http::code & = http::OK);
|
||||
response(client &, const json::members & = {}, const http::code & = http::OK);
|
||||
response(client &, const json::value &, const http::code & = http::OK);
|
||||
response(client &, const json::iov &, const http::code & = http::OK);
|
||||
response(client &, const http::code &, const json::members &);
|
||||
response(client &, const http::code &, const json::value &);
|
||||
response(client &, const http::code &, const json::iov &);
|
||||
response(client &, const http::code &);
|
||||
response() = default;
|
||||
};
|
||||
|
||||
struct ircd::resource::response::chunked
|
||||
:resource::response
|
||||
{
|
||||
static conf::item<size_t> default_buffer_size;
|
||||
|
||||
client *c {nullptr};
|
||||
unique_buffer<mutable_buffer> buf;
|
||||
|
||||
size_t write(const const_buffer &chunk);
|
||||
const_buffer flush(const const_buffer &);
|
||||
bool finish();
|
||||
|
||||
std::function<const_buffer (const const_buffer &)> flusher();
|
||||
|
||||
chunked(client &, const http::code &, const string_view &content_type, const string_view &headers = {});
|
||||
chunked(client &, const http::code &, const string_view &content_type, const vector_view<const http::header> &);
|
||||
chunked(client &, const http::code &, const vector_view<const http::header> &);
|
||||
chunked(client &, const http::code &);
|
||||
chunked(const chunked &) = delete;
|
||||
chunked(chunked &&) noexcept;
|
||||
chunked() = default;
|
||||
~chunked() noexcept;
|
||||
};
|
75
include/ircd/resource/method.h
Normal file
75
include/ircd/resource/method.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_METHOD_H
|
||||
|
||||
struct ircd::resource::method
|
||||
{
|
||||
enum flag :uint;
|
||||
struct opts;
|
||||
struct stats;
|
||||
using handler = std::function<response (client &, request &)>;
|
||||
|
||||
static conf::item<bool> x_matrix_verify_origin;
|
||||
static conf::item<bool> x_matrix_verify_destination;
|
||||
|
||||
struct resource *resource;
|
||||
string_view name;
|
||||
handler function;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
std::unique_ptr<struct stats> stats;
|
||||
unique_const_iterator<decltype(resource::methods)> methods_it;
|
||||
|
||||
string_view verify_origin(client &, request &) const;
|
||||
string_view authenticate(client &, request &) const;
|
||||
void handle_timeout(client &) const;
|
||||
void call_handler(client &, request &);
|
||||
|
||||
public:
|
||||
void operator()(client &, const http::request::head &, const string_view &content_partial);
|
||||
|
||||
method(struct resource &, const string_view &name, handler, struct opts);
|
||||
method(struct resource &, const string_view &name, handler);
|
||||
~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::method::stats
|
||||
{
|
||||
uint64_t requests {0}; // The method was found and called.
|
||||
uint64_t timeouts {0}; // The method's timeout was exceeded.
|
||||
uint64_t completions {0}; // The handler returned without throwing.
|
||||
uint64_t internal_errors {0}; // The handler threw a very bad exception.
|
||||
};
|
68
include/ircd/resource/request.h
Normal file
68
include/ircd/resource/request.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_REQUEST_H
|
||||
|
||||
struct ircd::resource::request
|
||||
:json::object
|
||||
{
|
||||
template<class> struct object;
|
||||
|
||||
http::request::head head;
|
||||
string_view content;
|
||||
http::query::string query;
|
||||
string_view origin;
|
||||
string_view access_token;
|
||||
vector_view<string_view> parv;
|
||||
string_view param[8];
|
||||
m::user::id::buf user_id;
|
||||
m::node::id::buf node_id;
|
||||
|
||||
request(const http::request::head &head,
|
||||
const string_view &content)
|
||||
:json::object{content}
|
||||
,head{head}
|
||||
,content{content}
|
||||
,query{this->head.query}
|
||||
{}
|
||||
|
||||
request() = default;
|
||||
};
|
||||
|
||||
template<class tuple>
|
||||
struct ircd::resource::request::object
|
||||
:tuple
|
||||
{
|
||||
resource::request &r;
|
||||
const http::request::head &head;
|
||||
const string_view &content;
|
||||
const http::query::string &query;
|
||||
const decltype(r.origin) &origin;
|
||||
const decltype(r.user_id) &user_id;
|
||||
const decltype(r.node_id) &node_id;
|
||||
const decltype(r.access_token) &access_token;
|
||||
const vector_view<string_view> &parv;
|
||||
const json::object &body;
|
||||
|
||||
object(resource::request &r)
|
||||
:tuple{r}
|
||||
,r{r}
|
||||
,head{r.head}
|
||||
,content{r.content}
|
||||
,query{r.query}
|
||||
,origin{r.origin}
|
||||
,user_id{r.user_id}
|
||||
,node_id{r.node_id}
|
||||
,access_token{r.access_token}
|
||||
,parv{r.parv}
|
||||
,body{r}
|
||||
{}
|
||||
};
|
83
include/ircd/resource/resource.h
Normal file
83
include/ircd/resource/resource.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_RESOURCE_H
|
||||
|
||||
namespace ircd
|
||||
{
|
||||
struct client;
|
||||
struct resource;
|
||||
}
|
||||
|
||||
/// The target of an HTTP request specified by clients with a path.
|
||||
///
|
||||
struct ircd::resource
|
||||
{
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
|
||||
enum flag :uint;
|
||||
struct opts;
|
||||
struct method;
|
||||
struct request;
|
||||
struct response;
|
||||
|
||||
static log::log log;
|
||||
static std::map<string_view, resource *, iless> resources;
|
||||
|
||||
string_view path;
|
||||
std::unique_ptr<const struct opts> opts;
|
||||
std::map<string_view, method *> methods;
|
||||
unique_const_iterator<decltype(resources)> resources_it;
|
||||
|
||||
string_view allow_methods_list(const mutable_buffer &buf) const;
|
||||
|
||||
public:
|
||||
method &operator[](const string_view &name) const;
|
||||
|
||||
resource(const string_view &path, struct opts);
|
||||
resource(const string_view &path);
|
||||
resource() = default;
|
||||
~resource() noexcept;
|
||||
|
||||
static resource &find(const string_view &path);
|
||||
};
|
||||
|
||||
#include "method.h"
|
||||
#include "request.h"
|
||||
#include "response.h"
|
||||
|
||||
enum ircd::resource::flag
|
||||
:uint
|
||||
{
|
||||
DIRECTORY = 0x01,
|
||||
};
|
||||
|
||||
struct ircd::resource::opts
|
||||
{
|
||||
/// developer's literal description of the resource
|
||||
string_view description
|
||||
{
|
||||
"no description"
|
||||
};
|
||||
|
||||
/// flags for the resource
|
||||
flag flags
|
||||
{
|
||||
flag(0)
|
||||
};
|
||||
|
||||
/// parameter count limits (DIRECTORY only)
|
||||
std::pair<short, short> parc
|
||||
{
|
||||
0, // minimum params
|
||||
15 // maximum params
|
||||
};
|
||||
};
|
58
include/ircd/resource/response.h
Normal file
58
include/ircd/resource/response.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2019 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. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_RESOURCE_RESPONSE_H
|
||||
|
||||
struct ircd::resource::response
|
||||
{
|
||||
struct chunked;
|
||||
|
||||
static const size_t HEAD_BUF_SZ;
|
||||
static conf::item<std::string> access_control_allow_origin;
|
||||
|
||||
response(client &, const http::code &, const string_view &content_type, const size_t &content_length, const string_view &headers = {});
|
||||
response(client &, const string_view &str, const string_view &content_type, const http::code &, const vector_view<const http::header> &);
|
||||
response(client &, const string_view &str, const string_view &content_type, const http::code & = http::OK, const string_view &headers = {});
|
||||
response(client &, const json::object &str, const http::code & = http::OK);
|
||||
response(client &, const json::array &str, const http::code & = http::OK);
|
||||
response(client &, const json::members & = {}, const http::code & = http::OK);
|
||||
response(client &, const json::value &, const http::code & = http::OK);
|
||||
response(client &, const json::iov &, const http::code & = http::OK);
|
||||
response(client &, const http::code &, const json::members &);
|
||||
response(client &, const http::code &, const json::value &);
|
||||
response(client &, const http::code &, const json::iov &);
|
||||
response(client &, const http::code &);
|
||||
response() = default;
|
||||
};
|
||||
|
||||
struct ircd::resource::response::chunked
|
||||
:resource::response
|
||||
{
|
||||
static conf::item<size_t> default_buffer_size;
|
||||
|
||||
client *c {nullptr};
|
||||
unique_buffer<mutable_buffer> buf;
|
||||
|
||||
size_t write(const const_buffer &chunk);
|
||||
const_buffer flush(const const_buffer &);
|
||||
bool finish();
|
||||
|
||||
std::function<const_buffer (const const_buffer &)> flusher();
|
||||
|
||||
chunked(client &, const http::code &, const string_view &content_type, const string_view &headers = {});
|
||||
chunked(client &, const http::code &, const string_view &content_type, const vector_view<const http::header> &);
|
||||
chunked(client &, const http::code &, const vector_view<const http::header> &);
|
||||
chunked(client &, const http::code &);
|
||||
chunked(const chunked &) = delete;
|
||||
chunked(chunked &&) noexcept;
|
||||
chunked() = default;
|
||||
~chunked() noexcept;
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
// Copyright (C) 2016-2019 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
|
||||
|
@ -95,7 +95,7 @@ ircd::resource::find(const string_view &path_)
|
|||
}
|
||||
|
||||
//
|
||||
// resource
|
||||
// resource::resource
|
||||
//
|
||||
|
||||
ircd::resource::resource(const string_view &path)
|
||||
|
@ -198,8 +198,9 @@ const
|
|||
return { data(buf), len };
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// method::method
|
||||
// resource/method.h
|
||||
//
|
||||
|
||||
namespace ircd
|
||||
|
@ -208,6 +209,10 @@ namespace ircd
|
|||
static void cache_warm_origin(const string_view &origin);
|
||||
}
|
||||
|
||||
//
|
||||
// method::method
|
||||
//
|
||||
|
||||
ircd::resource::method::method(struct resource &resource,
|
||||
const string_view &name,
|
||||
handler function)
|
||||
|
@ -708,6 +713,11 @@ catch(const std::exception &e)
|
|||
};
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// resource/response.h
|
||||
//
|
||||
|
||||
//
|
||||
// resource::response::chunked
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue