mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd: Various fixes.
This commit is contained in:
parent
065395d274
commit
49c2a5361c
16 changed files with 334 additions and 133 deletions
|
@ -42,6 +42,25 @@ struct buffer
|
|||
{}
|
||||
};
|
||||
|
||||
struct const_buffer
|
||||
:buffer<const char *>
|
||||
{
|
||||
operator boost::asio::const_buffer() const;
|
||||
|
||||
using buffer<const char *>::buffer;
|
||||
const_buffer(const string_view &s)
|
||||
:buffer<const char *>{begin(s), end(s)}
|
||||
{}
|
||||
};
|
||||
|
||||
struct mutable_buffer
|
||||
:buffer<char *>
|
||||
{
|
||||
operator boost::asio::mutable_buffer() const;
|
||||
|
||||
using buffer<char *>::buffer;
|
||||
};
|
||||
|
||||
template<class it,
|
||||
size_t align = 16>
|
||||
struct unique_buffer
|
||||
|
@ -53,22 +72,6 @@ struct unique_buffer
|
|||
~unique_buffer() noexcept;
|
||||
};
|
||||
|
||||
struct const_buffer
|
||||
:buffer<const char *>
|
||||
{
|
||||
operator boost::asio::const_buffer() const;
|
||||
|
||||
using buffer<const char *>::buffer;
|
||||
};
|
||||
|
||||
struct mutable_buffer
|
||||
:buffer<char *>
|
||||
{
|
||||
operator boost::asio::mutable_buffer() const;
|
||||
|
||||
using buffer<char *>::buffer;
|
||||
};
|
||||
|
||||
template<class T> using buffers = std::initializer_list<T>;
|
||||
using const_buffers = buffers<const_buffer>;
|
||||
using mutable_buffers = buffers<mutable_buffer>;
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace http {
|
|||
|
||||
enum code
|
||||
{
|
||||
OK = 200,
|
||||
|
||||
BAD_REQUEST = 400,
|
||||
NOT_FOUND = 404,
|
||||
METHOD_NOT_ALLOWED = 405,
|
||||
|
@ -37,7 +39,7 @@ enum code
|
|||
INTERNAL_SERVER_ERROR = 500,
|
||||
};
|
||||
|
||||
extern std::map<code, string_view> reason;
|
||||
extern std::map<code, std::string> reason;
|
||||
|
||||
struct error
|
||||
:ircd::error
|
||||
|
|
|
@ -29,32 +29,30 @@ struct doc
|
|||
:string_view
|
||||
{
|
||||
struct member;
|
||||
struct iterator;
|
||||
struct const_iterator;
|
||||
|
||||
using key_type = string_view;
|
||||
using mapped_type = string_view;
|
||||
using value_type = const member;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
using const_iterator = iterator;
|
||||
using iterator = const_iterator;
|
||||
using size_type = size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using key_compare = std::less<member>;
|
||||
|
||||
bool contains(const string_view &) const;
|
||||
|
||||
iterator end() const;
|
||||
iterator begin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator begin() const;
|
||||
|
||||
iterator find(const char *const &name) const;
|
||||
const_iterator find(const char *const &name) const;
|
||||
size_t count() const;
|
||||
|
||||
string_view at(const char *const &name) const;
|
||||
string_view operator[](const char *const &name) const;
|
||||
|
||||
doc(const string_view &s = {})
|
||||
:string_view{s}
|
||||
{}
|
||||
using string_view::string_view;
|
||||
|
||||
friend size_t print(char *const &buf, const size_t &max, const doc &);
|
||||
friend std::ostream &operator<<(std::ostream &, const doc &);
|
||||
|
@ -75,7 +73,7 @@ struct doc::member
|
|||
friend std::ostream &operator<<(std::ostream &, const doc::member &);
|
||||
};
|
||||
|
||||
struct doc::iterator
|
||||
struct doc::const_iterator
|
||||
{
|
||||
using value_type = const member;
|
||||
using pointer = value_type *;
|
||||
|
@ -90,7 +88,7 @@ struct doc::iterator
|
|||
const char *stop;
|
||||
mutable member state;
|
||||
|
||||
iterator(const char *const &start, const char *const &stop)
|
||||
const_iterator(const char *const &start, const char *const &stop)
|
||||
:start{start}
|
||||
,stop{stop}
|
||||
{}
|
||||
|
@ -99,48 +97,48 @@ struct doc::iterator
|
|||
value_type *operator->() const { return &state; }
|
||||
value_type &operator*() const { return *operator->(); }
|
||||
|
||||
iterator &operator++();
|
||||
const_iterator &operator++();
|
||||
|
||||
friend bool operator==(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator!=(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator<=(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator>=(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator<(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator>(const doc::iterator &, const doc::iterator &);
|
||||
friend bool operator==(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator!=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator<=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator>=(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator<(const doc::const_iterator &, const doc::const_iterator &);
|
||||
friend bool operator>(const doc::const_iterator &, const doc::const_iterator &);
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator==(const doc::iterator &a, const doc::iterator &b)
|
||||
operator==(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start == b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(const doc::iterator &a, const doc::iterator &b)
|
||||
operator!=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start != b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<=(const doc::iterator &a, const doc::iterator &b)
|
||||
operator<=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start <= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>=(const doc::iterator &a, const doc::iterator &b)
|
||||
operator>=(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start >= b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(const doc::iterator &a, const doc::iterator &b)
|
||||
operator<(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start < b.start;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator>(const doc::iterator &a, const doc::iterator &b)
|
||||
operator>(const doc::const_iterator &a, const doc::const_iterator &b)
|
||||
{
|
||||
return a.start > b.start;
|
||||
}
|
||||
|
@ -205,7 +203,7 @@ const
|
|||
return it->second;
|
||||
}
|
||||
|
||||
inline ircd::json::doc::iterator
|
||||
inline ircd::json::doc::const_iterator
|
||||
ircd::json::doc::find(const char *const &name)
|
||||
const
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ struct obj
|
|||
using size_type = size_t;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using key_compare = std::less<member>;
|
||||
using index = std::set<member>;
|
||||
using index = std::vector<member>;
|
||||
|
||||
doc state;
|
||||
index idx;
|
||||
|
@ -67,7 +67,7 @@ struct obj
|
|||
delta operator[](const char *const &name);
|
||||
|
||||
obj(const doc &d);
|
||||
obj() = default;
|
||||
obj();
|
||||
obj(obj &&) = default;
|
||||
explicit obj(const obj &);
|
||||
~obj() noexcept;
|
||||
|
@ -105,6 +105,7 @@ struct obj::delta
|
|||
void set(const std::string &);
|
||||
void set(const char *const &);
|
||||
void set(const string_view &);
|
||||
void set(const json::obj &);
|
||||
|
||||
public:
|
||||
delta(struct obj &, obj::member &, const string_view &);
|
||||
|
@ -193,14 +194,14 @@ const
|
|||
inline ircd::json::obj::iterator
|
||||
ircd::json::obj::find(const char *const &name)
|
||||
{
|
||||
return { *this, idx.find(string_view{name}) };
|
||||
return { *this, std::find(std::begin(idx), std::end(idx), string_view{name}) };
|
||||
}
|
||||
|
||||
inline ircd::json::obj::const_iterator
|
||||
ircd::json::obj::find(const char *const &name)
|
||||
const
|
||||
{
|
||||
return idx.find(string_view{name});
|
||||
return std::find(std::begin(idx), std::end(idx), string_view{name});
|
||||
}
|
||||
|
||||
inline size_t
|
||||
|
|
|
@ -55,7 +55,9 @@ struct resource
|
|||
|
||||
struct resource::response
|
||||
{
|
||||
response();
|
||||
response(client &, const json::doc &doc, const http::code &code = http::OK);
|
||||
response(client &, const json::obj &obj, const http::code &code = http::OK);
|
||||
response() = default;
|
||||
~response() noexcept;
|
||||
};
|
||||
|
||||
|
@ -66,9 +68,9 @@ struct resource::request
|
|||
};
|
||||
|
||||
struct resource::method
|
||||
:std::function<void (client &, request &, response &)>
|
||||
:std::function<response (client &, request &)>
|
||||
{
|
||||
using handler = std::function<void (client &, request &, response &)>;
|
||||
using handler = std::function<response (client &, request &)>;
|
||||
|
||||
protected:
|
||||
public:
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_CLIENT_SOCK_H
|
||||
#define HAVE_IRCD_CLIENT_SOCKET_H
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
@ -156,12 +156,6 @@ struct socket::init
|
|||
~init() noexcept;
|
||||
};
|
||||
|
||||
char *read(socket &, char *&start, char *const &stop);
|
||||
string_view readline(socket &, char *&start, char *const &stop);
|
||||
|
||||
size_t write(socket &, const char *const &buf, const size_t &max);
|
||||
size_t write(socket &, const string_view &);
|
||||
|
||||
ip::address remote_address(const socket &);
|
||||
std::string remote_ip(const socket &);
|
||||
uint16_t remote_port(const socket &);
|
||||
|
@ -169,6 +163,12 @@ ip::address local_address(const socket &);
|
|||
std::string local_ip(const socket &);
|
||||
uint16_t local_port(const socket &);
|
||||
|
||||
char *read(socket &, char *&start, char *const &stop);
|
||||
string_view readline(socket &, char *&start, char *const &stop);
|
||||
|
||||
size_t write(socket &, const char *const &buf, const size_t &max);
|
||||
size_t write(socket &, const string_view &);
|
||||
|
||||
|
||||
inline
|
||||
socket::io::io(struct socket &sock,
|
||||
|
|
|
@ -80,7 +80,7 @@ template<template<class, class, class>
|
|||
class T = string_view,
|
||||
class Comp = std::less<T>,
|
||||
class A>
|
||||
C<T, Comp, A> token(A allocator, const string_view &str, const char *const &sep);
|
||||
C<T, Comp, A> tokens(A allocator, const string_view &str, const char *const &sep);
|
||||
|
||||
// Receive token view into new associative container
|
||||
template<template<class, class, class>
|
||||
|
@ -88,7 +88,7 @@ template<template<class, class, class>
|
|||
class T = string_view,
|
||||
class Comp = std::less<T>,
|
||||
class A = std::allocator<T>>
|
||||
C<T, Comp, A> token(const string_view &str, const char *const &sep);
|
||||
C<T, Comp, A> tokens(const string_view &str, const char *const &sep);
|
||||
|
||||
// Convenience to get individual tokens
|
||||
size_t tokens_count(const string_view &str, const char *const &sep);
|
||||
|
|
|
@ -445,7 +445,7 @@ at(It &&start,
|
|||
It &&stop,
|
||||
ssize_t i)
|
||||
{
|
||||
for(; start != stop; --i, std::next(start, 1))
|
||||
for(; start != stop; --i, std::advance(start, 1))
|
||||
if(!i)
|
||||
return start;
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ catch(const http::error &e)
|
|||
{ "HTTP/1.1 ", 9 },
|
||||
{ e.what(), strlen(e.what()) },
|
||||
{ "\r\n", 2 },
|
||||
{ content_len, size_t(content_len_len) },
|
||||
{ string_view(content_len) },
|
||||
{ "\r\n", 2 },
|
||||
{ e.content.data(), e.content.size() }
|
||||
};
|
||||
|
|
12
ircd/http.cc
12
ircd/http.cc
|
@ -382,13 +382,15 @@ ircd::http::line::line(parse::context &pc)
|
|||
namespace ircd {
|
||||
namespace http {
|
||||
|
||||
std::map<code, string_view> reason
|
||||
std::map<code, std::string> reason
|
||||
{
|
||||
{ code::BAD_REQUEST, "Bad Request" },
|
||||
{ code::NOT_FOUND, "Not Found" },
|
||||
{ code::METHOD_NOT_ALLOWED, "Method Not Allowed" },
|
||||
{ code::OK, "OK"s },
|
||||
|
||||
{ code::INTERNAL_SERVER_ERROR, "Internal Server Error" },
|
||||
{ code::BAD_REQUEST, "Bad Request"s },
|
||||
{ code::NOT_FOUND, "Not Found"s },
|
||||
{ code::METHOD_NOT_ALLOWED, "Method Not Allowed"s },
|
||||
|
||||
{ code::INTERNAL_SERVER_ERROR, "Internal Server Error"s },
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
|
|
105
ircd/json.cc
105
ircd/json.cc
|
@ -34,14 +34,7 @@ BOOST_FUSION_ADAPT_STRUCT
|
|||
( decltype(ircd::json::doc::member::first), first )
|
||||
( decltype(ircd::json::doc::member::second), second )
|
||||
)
|
||||
/*
|
||||
BOOST_FUSION_ADAPT_STRUCT
|
||||
(
|
||||
ircd::json::obj::member,
|
||||
( decltype(ircd::json::obj::member::first), first )
|
||||
( decltype(ircd::json::obj::member::second), second )
|
||||
)
|
||||
*/
|
||||
|
||||
namespace ircd {
|
||||
namespace json {
|
||||
|
||||
|
@ -69,6 +62,7 @@ using karma::char_;
|
|||
using karma::maxwidth;
|
||||
using karma::buffer;
|
||||
using karma::eps;
|
||||
using karma::attr_cast;
|
||||
|
||||
template<class it>
|
||||
struct input
|
||||
|
@ -266,26 +260,22 @@ struct output
|
|||
rule<string_view> string { quote << chars << quote ,"string" };
|
||||
|
||||
rule<string_view> name { string ,"name" };
|
||||
rule<string_view> value { rule<string_view>{} ,"value" };
|
||||
rule<string_view> value { karma::string ,"value" };
|
||||
|
||||
rule<const json::array &> elems { *(value % value_sep) ,"elements" };
|
||||
rule<const json::array &> elems { (value % value_sep) ,"elements" };
|
||||
rule<const json::array &> array { array_begin << elems << array_end ,"array" };
|
||||
|
||||
rule<doc::member> dmember { name << name_sep << value ,"member" };
|
||||
rule<const json::doc &> dmembers { *(dmember % value_sep) ,"members" };
|
||||
rule<const json::doc &> dmembers { (dmember % value_sep) ,"members" };
|
||||
rule<const json::doc &> document { object_begin << dmembers << object_end ,"document" };
|
||||
|
||||
rule<doc::member> member { name << name_sep << value ,"member" };
|
||||
rule<const json::obj &> members { *(member % value_sep) ,"members" };
|
||||
rule<const json::obj &> members { (member % value_sep) ,"members" };
|
||||
rule<const json::obj &> object { object_begin << members << object_end ,"object" };
|
||||
|
||||
output()
|
||||
:output::base_type{rule<>{}}
|
||||
{
|
||||
array %= array_begin << elems << array_end;
|
||||
object %= object_begin << members << object_end;
|
||||
document %= object_begin << dmembers << object_end;
|
||||
}
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace json
|
||||
|
@ -304,14 +294,14 @@ const parser;
|
|||
struct printer
|
||||
:output<char *>
|
||||
{
|
||||
using output<char *>::output;
|
||||
printer();
|
||||
}
|
||||
const printer;
|
||||
|
||||
struct ostreamer
|
||||
:output<karma::ostream_iterator<char>>
|
||||
{
|
||||
using output<karma::ostream_iterator<char>>::output;
|
||||
ostreamer();
|
||||
}
|
||||
const ostreamer;
|
||||
|
||||
|
@ -326,6 +316,49 @@ std::ostream &operator<<(std::ostream &, const obj &);
|
|||
} // namespace json
|
||||
} // namespace ircd
|
||||
|
||||
ircd::json::printer::printer()
|
||||
{
|
||||
const auto recursor([this](auto &a, auto &b, auto &c)
|
||||
{
|
||||
const auto recurse_document([&]
|
||||
{
|
||||
char *out(const_cast<char *>(a.data()));
|
||||
karma::generate(out, maxwidth(a.size())[document], json::doc(a));
|
||||
a.resize(size_t(out - a.data()));
|
||||
});
|
||||
|
||||
if(likely(!a.empty())) switch(a.front())
|
||||
{
|
||||
case '{': recurse_document(); break;
|
||||
default: break;
|
||||
}
|
||||
});
|
||||
|
||||
value %= karma::string[recursor];
|
||||
}
|
||||
|
||||
ircd::json::ostreamer::ostreamer()
|
||||
{
|
||||
const auto recursor([this](auto &a, auto &b, auto &c)
|
||||
{
|
||||
const auto recurse_document([&]
|
||||
{
|
||||
char *out(const_cast<char *>(a.data()));
|
||||
const auto count(print(out, a.size(), json::doc(a)));
|
||||
a.resize(count);
|
||||
});
|
||||
|
||||
if(likely(!a.empty())) switch(a.front())
|
||||
{
|
||||
case '{': recurse_document(); break;
|
||||
case '[': c = false; break;
|
||||
default: break;
|
||||
}
|
||||
});
|
||||
|
||||
value %= karma::string[recursor];
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::json::print(char *const &buf,
|
||||
const size_t &max,
|
||||
|
@ -387,6 +420,11 @@ ircd::json::operator<<(std::ostream &s, const obj &obj)
|
|||
return s;
|
||||
}
|
||||
|
||||
ircd::json::obj::obj()
|
||||
:owns_state{false}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::json::obj::obj(const doc &doc)
|
||||
:state{doc}
|
||||
,idx{std::begin(doc), std::end(doc)}
|
||||
|
@ -449,8 +487,8 @@ const
|
|||
ircd::json::obj::delta
|
||||
ircd::json::obj::operator[](const char *const &name)
|
||||
{
|
||||
auto pit(idx.emplace(string_view{name}, string_view{}));
|
||||
auto &member(const_cast<obj::member &>(*pit.first));
|
||||
const auto it(idx.emplace(idx.end(), string_view{name}, string_view{}));
|
||||
auto &member(const_cast<obj::member &>(*it));
|
||||
/*
|
||||
if(pit.second)
|
||||
{
|
||||
|
@ -468,7 +506,7 @@ ircd::json::obj::operator[](const char *const &name)
|
|||
ircd::json::obj::delta
|
||||
ircd::json::obj::at(const char *const &name)
|
||||
{
|
||||
const auto it(idx.find(string_view{name}));
|
||||
const auto it(std::find(std::begin(idx), std::end(idx), string_view{name}));
|
||||
if(unlikely(it == idx.end()))
|
||||
throw not_found("name \"%s\"", name);
|
||||
|
||||
|
@ -549,6 +587,18 @@ ircd::json::obj::delta::delta(struct obj &obj,
|
|||
{
|
||||
}
|
||||
|
||||
void
|
||||
ircd::json::obj::delta::set(const json::obj &obj)
|
||||
{
|
||||
const size_t size(obj.size());
|
||||
std::unique_ptr<char[]> buf(new char[size + 1]);
|
||||
const auto doc(serialize(obj, buf.get(), buf.get() + size));
|
||||
buf.get()[size] = '\0';
|
||||
commit(doc);
|
||||
member->owns_second = true;
|
||||
buf.release();
|
||||
}
|
||||
|
||||
void
|
||||
ircd::json::obj::delta::set(const string_view &value)
|
||||
{
|
||||
|
@ -667,13 +717,14 @@ ircd::json::print(char *const &buf,
|
|||
std::ostream &
|
||||
ircd::json::operator<<(std::ostream &s, const doc &doc)
|
||||
{
|
||||
const auto &os(ostreamer);
|
||||
static const auto throws([]
|
||||
{
|
||||
throw print_error("The JSON generator failed to output document to stream");
|
||||
});
|
||||
|
||||
karma::ostream_iterator<char> osi(s);
|
||||
karma::generate(osi, ostreamer.document | eps[throws], doc);
|
||||
karma::generate(osi, os.document | eps[throws], doc);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -690,8 +741,8 @@ ircd::json::operator<<(std::ostream &s, const doc::member &member)
|
|||
return s;
|
||||
}
|
||||
|
||||
ircd::json::doc::iterator &
|
||||
ircd::json::doc::iterator::operator++()
|
||||
ircd::json::doc::const_iterator &
|
||||
ircd::json::doc::const_iterator::operator++()
|
||||
{
|
||||
static const qi::rule<const char *, json::doc::member> member
|
||||
{
|
||||
|
@ -711,7 +762,7 @@ ircd::json::doc::iterator::operator++()
|
|||
return *this;
|
||||
}
|
||||
|
||||
ircd::json::doc::iterator
|
||||
ircd::json::doc::const_iterator
|
||||
ircd::json::doc::begin()
|
||||
const
|
||||
{
|
||||
|
@ -732,7 +783,7 @@ const
|
|||
return ret;
|
||||
}
|
||||
|
||||
ircd::json::doc::iterator
|
||||
ircd::json::doc::const_iterator
|
||||
ircd::json::doc::end()
|
||||
const
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ircd/socket.h>
|
||||
|
||||
namespace ircd {
|
||||
|
||||
IRCD_INIT_PRIORITY(STD_CONTAINER)
|
||||
|
@ -65,8 +67,7 @@ const try
|
|||
head, content
|
||||
};
|
||||
|
||||
resource::response response;
|
||||
method(client, request, response);
|
||||
response r(method(client, request));
|
||||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
|
@ -99,8 +100,57 @@ noexcept
|
|||
resource->methods.erase(methods_it);
|
||||
}
|
||||
|
||||
ircd::resource::response::response()
|
||||
ircd::resource::response::response(client &client,
|
||||
const json::obj &doc,
|
||||
const http::code &code)
|
||||
{
|
||||
char cbuf[1024];
|
||||
mutable_buffer buf(cbuf, sizeof(cbuf));
|
||||
response(client, serialize(doc, data(buf), data(buf) + size(buf)), code);
|
||||
}
|
||||
|
||||
ircd::resource::response::response(client &client,
|
||||
const json::doc &doc,
|
||||
const http::code &code)
|
||||
{
|
||||
char status_line[64]; const auto status_line_len
|
||||
{
|
||||
snprintf(status_line, sizeof(status_line), "HTTP/1.1 %u %s\r\n",
|
||||
uint(code),
|
||||
http::reason[code].data())
|
||||
};
|
||||
|
||||
char server_line[128]; const auto server_line_len
|
||||
{
|
||||
snprintf(server_line, sizeof(server_line), "Server: %s (IRCd) %s\r\n",
|
||||
BRANDING_NAME,
|
||||
BRANDING_VERSION)
|
||||
};
|
||||
|
||||
const time_t ltime(time(nullptr));
|
||||
struct tm *const tm(localtime(<ime));
|
||||
char date_line[64]; const auto date_line_len
|
||||
{
|
||||
strftime(date_line, sizeof(date_line), "Date: %a, %d %b %Y %T %z\r\n", tm)
|
||||
};
|
||||
|
||||
char content_len[64]; const auto content_len_len
|
||||
{
|
||||
snprintf(content_len, sizeof(content_len), "Content-Length: %zu\r\n",
|
||||
doc.size())
|
||||
};
|
||||
|
||||
const const_buffers iov
|
||||
{
|
||||
{ status_line, size_t(status_line_len) },
|
||||
{ server_line, size_t(server_line_len) },
|
||||
{ date_line, size_t(date_line_len) },
|
||||
{ content_len, size_t(content_len_len) },
|
||||
{ "\r\n", 2 },
|
||||
{ doc.data(), doc.size() }
|
||||
};
|
||||
|
||||
client.sock->write(iov);
|
||||
}
|
||||
|
||||
ircd::resource::response::~response()
|
||||
|
|
|
@ -26,12 +26,12 @@ AM_LDFLAGS += \
|
|||
# library is client_X.so in the main modules dir.
|
||||
client_moduledir=@moduledir@
|
||||
client_client_versions_la_SOURCES = client/versions.cc
|
||||
client_client_login_la_SOURCES = client/login.cc
|
||||
client_client_register_la_SOURCES = client/register.cc
|
||||
client_client_login_la_SOURCES = client/login.cc
|
||||
client_module_LTLIBRARIES = \
|
||||
client/client_versions.la \
|
||||
client/client_login.la \
|
||||
client/client_register.la
|
||||
client/client_register.la \
|
||||
client/client_login.la
|
||||
|
||||
moduledir=@moduledir@
|
||||
listen_la_SOURCES = listen.cc
|
||||
|
|
|
@ -37,8 +37,8 @@ resource login_resource
|
|||
|
||||
resource::method getter
|
||||
{login_resource, "POST", [](client &client,
|
||||
resource::request &request,
|
||||
resource::response &response)
|
||||
resource::request &request)
|
||||
-> resource::response
|
||||
{
|
||||
char head[256], body[256];
|
||||
static const auto headfmt
|
||||
|
@ -97,6 +97,7 @@ resource::method getter
|
|||
};
|
||||
|
||||
client.sock->write(iov);
|
||||
return {};
|
||||
}};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
|
|
|
@ -23,55 +23,144 @@
|
|||
|
||||
//ircd::db::handle logins("login", db::opt::READ_ONLY);
|
||||
|
||||
using namespace ircd;
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
ircd::mapi::header IRCD_MODULE
|
||||
{
|
||||
"registers the resource 'client/register' to handle requests"
|
||||
};
|
||||
|
||||
resource register_resource
|
||||
ircd::resource register_resource
|
||||
{
|
||||
"/_matrix/client/r0/register",
|
||||
"Register for an account on this homeserver. (3.3.1)"
|
||||
};
|
||||
|
||||
void valid_username(const string_view &s);
|
||||
void handle_post(client &client, resource::request &request, resource::response &response);
|
||||
auto generate_access_token([] { });
|
||||
auto generate_refresh_token([] { });
|
||||
void valid_username(const ircd::string_view &s);
|
||||
ircd::resource::response handle_post(ircd::client &client, ircd::resource::request &request);
|
||||
|
||||
resource::member username { "username", json::STRING, valid_username };
|
||||
resource::member bind_email { "bind_email", json::LITERAL };
|
||||
resource::method on_post
|
||||
template<class T>
|
||||
struct in
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct out
|
||||
{
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct query
|
||||
{
|
||||
};
|
||||
|
||||
struct string
|
||||
{
|
||||
};
|
||||
|
||||
struct object
|
||||
{
|
||||
};
|
||||
|
||||
struct boolean
|
||||
{
|
||||
};
|
||||
|
||||
template<>
|
||||
struct in<string>
|
||||
{
|
||||
in(const char *const &name, const std::function<void (const ircd::string_view &)> &valid = nullptr) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct in<object>
|
||||
{
|
||||
in(const char *const &name) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct in<boolean>
|
||||
{
|
||||
in(const char *const &name) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct query<boolean>
|
||||
{
|
||||
template<class A, class B> query(A&&, B&&) {}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct out<string>
|
||||
{
|
||||
template<class T> out(const char *const &name, T&&) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Inputs
|
||||
//
|
||||
in<string> username { "username", valid_username };
|
||||
in<string> password { "password" };
|
||||
in<object> auth { "auth" };
|
||||
in<string> session { "auth.session" };
|
||||
in<string> type { "auth.type" };
|
||||
in<boolean> bind_email { "bind_email" };
|
||||
|
||||
//
|
||||
// Queries
|
||||
//
|
||||
ircd::db::handle users { "users" };
|
||||
query<boolean> username_exists { users, username };
|
||||
|
||||
//
|
||||
// Commitments
|
||||
//
|
||||
|
||||
//
|
||||
// Outputs
|
||||
//
|
||||
out<string> user_id { "user_id", username };
|
||||
out<string> home_server { "home_server", "pitcock's playground" };
|
||||
out<string> access_token { "access_token", generate_access_token };
|
||||
out<string> refresh_token { "refresh_token", generate_refresh_token };
|
||||
|
||||
ircd::resource::method post
|
||||
{
|
||||
register_resource, "POST", handle_post,
|
||||
{
|
||||
&username,
|
||||
&bind_email,
|
||||
//&username,
|
||||
//&bind_email,
|
||||
}
|
||||
};
|
||||
|
||||
void handle_post(client &client,
|
||||
resource::request &request,
|
||||
resource::response &response)
|
||||
ircd::resource::response
|
||||
handle_post(ircd::client &client,
|
||||
ircd::resource::request &request)
|
||||
{
|
||||
using namespace ircd;
|
||||
|
||||
const json::doc in{request.content};
|
||||
|
||||
char head[256], body[25];
|
||||
static const auto headfmt
|
||||
{
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
"Content-Length: %zu\r\n"
|
||||
"\r\n"
|
||||
};
|
||||
json::obj hoo;
|
||||
hoo["kaa"] = "\"choo\"";
|
||||
|
||||
std::cout << request.content << std::endl;
|
||||
//std::cout << in << std::endl;
|
||||
json::obj foo;
|
||||
foo["yea"] = "\"pie\"";
|
||||
foo["hoo"] = &hoo;
|
||||
|
||||
// write(client, in);
|
||||
json::obj out;
|
||||
out["user_id"] = in["username"];
|
||||
out["access_token"] = "\"ABCDEFG\"";
|
||||
out["home_server"] = "\"dereferenced\"";
|
||||
out["refresh_token"] = "\"tokenizeddd\"";
|
||||
|
||||
return { client, out };
|
||||
}
|
||||
|
||||
void valid_username(const string_view &s)
|
||||
void valid_username(const ircd::string_view &s)
|
||||
{
|
||||
using namespace ircd;
|
||||
|
||||
static conf::item<size_t> max_len
|
||||
{
|
||||
"client.register.username.max_len", 15
|
||||
|
|
|
@ -59,18 +59,20 @@ resource versions_resource
|
|||
};
|
||||
|
||||
resource::method getter
|
||||
{versions_resource, "GET", [](client &client,
|
||||
resource::request &request,
|
||||
resource::response &response)
|
||||
{
|
||||
static const const_buffers iov
|
||||
versions_resource, "GET", []
|
||||
(client &client, resource::request &request) -> resource::response
|
||||
{
|
||||
{ header.data(), header.size() },
|
||||
{ body.data(), body.size() },
|
||||
};
|
||||
static const const_buffers iov
|
||||
{
|
||||
{ header.data(), header.size() },
|
||||
{ body.data(), body.size() },
|
||||
};
|
||||
|
||||
client.sock->write(iov);
|
||||
}};
|
||||
client.sock->write(iov);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
mapi::header IRCD_MODULE
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue