clang format
This commit is contained in:
@@ -5,13 +5,11 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
/** returns base64 encoded string */
|
||||
std::string B64Encode(const uint8_t * data, const std::size_t l);
|
||||
|
||||
/** @brief returns true if decode was successful */
|
||||
bool B64Decode(const std::string & data, std::vector<uint8_t> & out);
|
||||
/** returns base64 encoded string */
|
||||
std::string B64Encode(const uint8_t *data, const std::size_t l);
|
||||
|
||||
/** @brief returns true if decode was successful */
|
||||
bool B64Decode(const std::string &data, std::vector<uint8_t> &out);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,19 +1,19 @@
|
||||
#ifndef NNTPCHAN_BUFFER_HPP
|
||||
#define NNTPCHAN_BUFFER_HPP
|
||||
#include <uv.h>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
struct WriteBuffer
|
||||
{
|
||||
uv_write_t w;
|
||||
uv_buf_t b;
|
||||
struct WriteBuffer
|
||||
{
|
||||
uv_write_t w;
|
||||
uv_buf_t b;
|
||||
|
||||
WriteBuffer(const std::string & s);
|
||||
WriteBuffer(const char * b, const size_t s);
|
||||
~WriteBuffer();
|
||||
};
|
||||
WriteBuffer(const std::string &s);
|
||||
WriteBuffer(const char *b, const size_t s);
|
||||
~WriteBuffer();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,22 +1,21 @@
|
||||
#ifndef NNTPCHAN_CRYPTO_HPP
|
||||
#define NNTPCHAN_CRYPTO_HPP
|
||||
|
||||
#include <sodium/crypto_hash.h>
|
||||
#include <array>
|
||||
#include <sodium/crypto_hash.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
typedef std::array<uint8_t, crypto_hash_BYTES> SHA512Digest;
|
||||
typedef std::array<uint8_t, crypto_hash_BYTES> SHA512Digest;
|
||||
|
||||
void SHA512(const uint8_t * d, std::size_t l, SHA512Digest & h);
|
||||
void SHA512(const uint8_t *d, std::size_t l, SHA512Digest &h);
|
||||
|
||||
/** global crypto initializer */
|
||||
struct Crypto
|
||||
{
|
||||
Crypto();
|
||||
~Crypto();
|
||||
};
|
||||
/** global crypto initializer */
|
||||
struct Crypto
|
||||
{
|
||||
Crypto();
|
||||
~Crypto();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -4,23 +4,20 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
class Mainloop
|
||||
{
|
||||
public:
|
||||
class Mainloop
|
||||
{
|
||||
public:
|
||||
Mainloop();
|
||||
~Mainloop();
|
||||
|
||||
Mainloop();
|
||||
~Mainloop();
|
||||
operator uv_loop_t *() const { return m_loop; }
|
||||
|
||||
operator uv_loop_t * () const { return m_loop; }
|
||||
void Run(uv_run_mode mode = UV_RUN_DEFAULT);
|
||||
void Stop();
|
||||
|
||||
void Run(uv_run_mode mode = UV_RUN_DEFAULT);
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
|
||||
uv_loop_t * m_loop;
|
||||
|
||||
};
|
||||
private:
|
||||
uv_loop_t *m_loop;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -5,26 +5,23 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
class ExecFrontend : public Frontend
|
||||
{
|
||||
public:
|
||||
class ExecFrontend : public Frontend
|
||||
{
|
||||
public:
|
||||
ExecFrontend(const std::string &exe);
|
||||
|
||||
ExecFrontend(const std::string & exe);
|
||||
|
||||
~ExecFrontend();
|
||||
~ExecFrontend();
|
||||
|
||||
void ProcessNewMessage(const fs::path & fpath);
|
||||
bool AcceptsNewsgroup(const std::string & newsgroup);
|
||||
bool AcceptsMessage(const std::string & msgid);
|
||||
void ProcessNewMessage(const fs::path &fpath);
|
||||
bool AcceptsNewsgroup(const std::string &newsgroup);
|
||||
bool AcceptsMessage(const std::string &msgid);
|
||||
|
||||
private:
|
||||
private:
|
||||
int Exec(std::deque<std::string> args);
|
||||
|
||||
int Exec(std::deque<std::string> args);
|
||||
|
||||
private:
|
||||
std::string m_exec;
|
||||
|
||||
};
|
||||
private:
|
||||
std::string m_exec;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,23 +1,23 @@
|
||||
#ifndef NNTPCHAN_FILE_HANDLE_HPP
|
||||
#define NNTPCHAN_FILE_HANDLE_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include <experimental/filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
typedef std::unique_ptr<std::fstream> FileHandle_ptr;
|
||||
typedef std::unique_ptr<std::fstream> FileHandle_ptr;
|
||||
|
||||
enum FileMode
|
||||
{
|
||||
eRead,
|
||||
eWrite
|
||||
};
|
||||
enum FileMode
|
||||
{
|
||||
eRead,
|
||||
eWrite
|
||||
};
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
FileHandle_ptr OpenFile(const fs::path & fname, FileMode mode);
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
FileHandle_ptr OpenFile(const fs::path &fname, FileMode mode);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,29 +1,27 @@
|
||||
#ifndef NNTPCHAN_FRONTEND_HPP
|
||||
#define NNTPCHAN_FRONTEND_HPP
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <experimental/filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
/** @brief nntpchan frontend ui interface */
|
||||
class Frontend
|
||||
{
|
||||
public:
|
||||
namespace fs = std::experimental::filesystem;
|
||||
/** @brief nntpchan frontend ui interface */
|
||||
class Frontend
|
||||
{
|
||||
public:
|
||||
/** @brief process an inbound message stored at fpath that we have accepted. */
|
||||
virtual void ProcessNewMessage(const fs::path &fpath) = 0;
|
||||
|
||||
/** @brief process an inbound message stored at fpath that we have accepted. */
|
||||
virtual void ProcessNewMessage(const fs::path & fpath) = 0;
|
||||
/** @brief return true if we take posts in a newsgroup */
|
||||
virtual bool AcceptsNewsgroup(const std::string &newsgroup) = 0;
|
||||
|
||||
/** @brief return true if we take posts in a newsgroup */
|
||||
virtual bool AcceptsNewsgroup(const std::string & newsgroup) = 0;
|
||||
|
||||
/** @brief return true if we will accept a message given its message-id */
|
||||
virtual bool AcceptsMessage(const std::string & msgid) = 0;
|
||||
|
||||
};
|
||||
/** @brief return true if we will accept a message given its message-id */
|
||||
virtual bool AcceptsMessage(const std::string &msgid) = 0;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<Frontend> Frontend_ptr;
|
||||
typedef std::unique_ptr<Frontend> Frontend_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,4 @@
|
||||
#ifndef NNTPCHAN_HTTP_HPP
|
||||
#define NNTPCHAN_HTTP_HPP
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,5 +1,4 @@
|
||||
#ifndef NNTPCHAN_HTTP_CLIENT_HPP
|
||||
#define NNTPCHAN_HTTP_CLIENT_HPP
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,4 @@
|
||||
#ifndef NNTPCHAN_HTTP_SERVER_HPP
|
||||
#define NNTPCHAN_HTTP_SERVER_HPP
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#ifndef NNTPCHAN_IO_HANDLE_HPP
|
||||
#define NNTPCHAN_IO_HANDLE_HPP
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
typedef std::unique_ptr<std::iostream> IOHandle_ptr;
|
||||
|
||||
typedef std::unique_ptr<std::iostream> IOHandle_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -5,30 +5,28 @@
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
/** @brief a buffered line reader */
|
||||
class LineReader
|
||||
{
|
||||
public:
|
||||
/** @brief a buffered line reader */
|
||||
class LineReader
|
||||
{
|
||||
public:
|
||||
LineReader(size_t lineLimit);
|
||||
|
||||
LineReader(size_t lineLimit);
|
||||
/** @brief queue inbound data from connection */
|
||||
void Data(const char *data, ssize_t s);
|
||||
|
||||
/** @brief queue inbound data from connection */
|
||||
void Data(const char * data, ssize_t s);
|
||||
/** implements IConnHandler */
|
||||
virtual bool ShouldClose();
|
||||
|
||||
/** implements IConnHandler */
|
||||
virtual bool ShouldClose();
|
||||
protected:
|
||||
/** @brief handle a line from the client */
|
||||
virtual void HandleLine(const std::string &line) = 0;
|
||||
|
||||
protected:
|
||||
/** @brief handle a line from the client */
|
||||
virtual void HandleLine(const std::string & line) = 0;
|
||||
|
||||
|
||||
private:
|
||||
void OnLine(const char * d, const size_t l);
|
||||
std::string m_leftovers;
|
||||
bool m_close;
|
||||
const size_t lineLimit;
|
||||
};
|
||||
private:
|
||||
void OnLine(const char *d, const size_t l);
|
||||
std::string m_leftovers;
|
||||
bool m_close;
|
||||
const size_t lineLimit;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -6,16 +6,16 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
struct MessageDB
|
||||
{
|
||||
using BoardPage = nntpchan::model::BoardPage;
|
||||
using Thread = nntpchan::model::Thread;
|
||||
virtual bool LoadBoardPage(BoardPage & board, const std::string & newsgroup, uint32_t perpage, uint32_t page) const = 0;
|
||||
virtual bool FindThreadByHash(const std::string & hashhex, std::string & msgid) const = 0;
|
||||
virtual bool LoadThread(Thread & thread, const std::string & rootmsgid) const = 0;
|
||||
};
|
||||
struct MessageDB
|
||||
{
|
||||
using BoardPage = nntpchan::model::BoardPage;
|
||||
using Thread = nntpchan::model::Thread;
|
||||
virtual bool LoadBoardPage(BoardPage &board, const std::string &newsgroup, uint32_t perpage, uint32_t page) const = 0;
|
||||
virtual bool FindThreadByHash(const std::string &hashhex, std::string &msgid) const = 0;
|
||||
virtual bool LoadThread(Thread &thread, const std::string &rootmsgid) const = 0;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<MessageDB> MessageDB_ptr;
|
||||
typedef std::unique_ptr<MessageDB> MessageDB_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -9,22 +9,21 @@
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
typedef std::map<std::string, std::string> RawHeader;
|
||||
typedef std::map<std::string, std::string> RawHeader;
|
||||
|
||||
bool ReadHeader(const FileHandle_ptr & f, RawHeader & h);
|
||||
bool ReadHeader(const FileHandle_ptr &f, RawHeader &h);
|
||||
|
||||
struct MimePart
|
||||
{
|
||||
virtual RawHeader &Header() = 0;
|
||||
virtual IOHandle_ptr OpenPart() = 0;
|
||||
};
|
||||
|
||||
struct MimePart
|
||||
{
|
||||
virtual RawHeader & Header() = 0;
|
||||
virtual IOHandle_ptr OpenPart() = 0;
|
||||
};
|
||||
typedef std::unique_ptr<MimePart> MimePart_ptr;
|
||||
|
||||
typedef std::unique_ptr<MimePart> MimePart_ptr;
|
||||
|
||||
typedef std::function<bool(MimePart_ptr)> PartReader;
|
||||
|
||||
bool ReadParts(const FileHandle_ptr & f, PartReader r);
|
||||
typedef std::function<bool(MimePart_ptr)> PartReader;
|
||||
|
||||
bool ReadParts(const FileHandle_ptr &f, PartReader r);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,74 +2,58 @@
|
||||
#define NNTPCHAN_MODEL_HPP
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <nntpchan/sanitize.hpp>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
#include <nntpchan/sanitize.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
namespace model
|
||||
{
|
||||
// MIME Header
|
||||
typedef std::map<std::string, std::vector<std::string> > PostHeader;
|
||||
// text post contents
|
||||
typedef std::string PostBody;
|
||||
// single file attachment, (orig_filename, hexdigest, thumb_filename)
|
||||
typedef std::tuple<std::string, std::string, std::string> PostAttachment;
|
||||
// all attachments on a post
|
||||
typedef std::vector<PostAttachment> Attachments;
|
||||
// a post (header, Post Text, Attachments)
|
||||
typedef std::tuple<PostHeader, PostBody, Attachments> Post;
|
||||
// a thread (many posts in post order)
|
||||
typedef std::vector<Post> Thread;
|
||||
// a board page is many threads in bump order
|
||||
typedef std::vector<Thread> BoardPage;
|
||||
|
||||
static inline const std::string & GetFilename(const PostAttachment & att)
|
||||
{
|
||||
return std::get<0>(att);
|
||||
}
|
||||
|
||||
static inline const std::string & GetHexDigest(const PostAttachment & att)
|
||||
{
|
||||
return std::get<1>(att);
|
||||
}
|
||||
|
||||
static inline const std::string & GetThumbnail(const PostAttachment & att)
|
||||
{
|
||||
return std::get<2>(att);
|
||||
}
|
||||
|
||||
static inline const PostHeader & GetHeader(const Post & post)
|
||||
{
|
||||
return std::get<0>(post);
|
||||
}
|
||||
|
||||
static inline const PostBody & GetBody(const Post & post)
|
||||
{
|
||||
return std::get<1>(post);
|
||||
}
|
||||
|
||||
static inline const Attachments & GetAttachments(const Post & post)
|
||||
{
|
||||
return std::get<2>(post);
|
||||
}
|
||||
namespace model
|
||||
{
|
||||
// MIME Header
|
||||
typedef std::map<std::string, std::vector<std::string>> PostHeader;
|
||||
// text post contents
|
||||
typedef std::string PostBody;
|
||||
// single file attachment, (orig_filename, hexdigest, thumb_filename)
|
||||
typedef std::tuple<std::string, std::string, std::string> PostAttachment;
|
||||
// all attachments on a post
|
||||
typedef std::vector<PostAttachment> Attachments;
|
||||
// a post (header, Post Text, Attachments)
|
||||
typedef std::tuple<PostHeader, PostBody, Attachments> Post;
|
||||
// a thread (many posts in post order)
|
||||
typedef std::vector<Post> Thread;
|
||||
// a board page is many threads in bump order
|
||||
typedef std::vector<Thread> BoardPage;
|
||||
|
||||
static inline const std::string & HeaderIFind(const PostHeader & header, const std::string & val, const std::string & fallback)
|
||||
{
|
||||
std::string ival = ToLower(val);
|
||||
auto itr = std::find_if(header.begin(), header.end(), [ival](const auto & item) -> bool { return ToLower(item.first) == ival; });
|
||||
if (itr == std::end(header))
|
||||
return fallback;
|
||||
else
|
||||
return itr->second[0];
|
||||
}
|
||||
static inline const std::string &GetFilename(const PostAttachment &att) { return std::get<0>(att); }
|
||||
|
||||
using Model = std::variant<Thread, BoardPage>;
|
||||
}
|
||||
static inline const std::string &GetHexDigest(const PostAttachment &att) { return std::get<1>(att); }
|
||||
|
||||
static inline const std::string &GetThumbnail(const PostAttachment &att) { return std::get<2>(att); }
|
||||
|
||||
static inline const PostHeader &GetHeader(const Post &post) { return std::get<0>(post); }
|
||||
|
||||
static inline const PostBody &GetBody(const Post &post) { return std::get<1>(post); }
|
||||
|
||||
static inline const Attachments &GetAttachments(const Post &post) { return std::get<2>(post); }
|
||||
|
||||
static inline const std::string &HeaderIFind(const PostHeader &header, const std::string &val,
|
||||
const std::string &fallback)
|
||||
{
|
||||
std::string ival = ToLower(val);
|
||||
auto itr = std::find_if(header.begin(), header.end(),
|
||||
[ival](const auto &item) -> bool { return ToLower(item.first) == ival; });
|
||||
if (itr == std::end(header))
|
||||
return fallback;
|
||||
else
|
||||
return itr->second[0];
|
||||
}
|
||||
|
||||
using Model = std::variant<Thread, BoardPage>;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,23 +1,23 @@
|
||||
#ifndef NNTPCHAN_NET_HPP
|
||||
#define NNTPCHAN_NET_HPP
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
struct NetAddr
|
||||
{
|
||||
NetAddr();
|
||||
|
||||
sockaddr_in6 addr;
|
||||
operator sockaddr * () { return (sockaddr *) &addr; }
|
||||
operator const sockaddr * () const { return (sockaddr *) &addr; }
|
||||
std::string to_string();
|
||||
};
|
||||
struct NetAddr
|
||||
{
|
||||
NetAddr();
|
||||
|
||||
NetAddr ParseAddr(const std::string & addr);
|
||||
sockaddr_in6 addr;
|
||||
operator sockaddr *() { return (sockaddr *)&addr; }
|
||||
operator const sockaddr *() const { return (sockaddr *)&addr; }
|
||||
std::string to_string();
|
||||
};
|
||||
|
||||
NetAddr ParseAddr(const std::string &addr);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -1,61 +1,64 @@
|
||||
#ifndef NNTPCHAN_NNTP_AUTH_HPP
|
||||
#define NNTPCHAN_NNTP_AUTH_HPP
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
#include "line.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
/** @brief nntp credential db interface */
|
||||
class NNTPCredentialDB
|
||||
{
|
||||
public:
|
||||
/** @brief open connection to database, return false on error otherwise return true */
|
||||
virtual bool Open() = 0;
|
||||
/** @brief close connection to database */
|
||||
virtual void Close() = 0;
|
||||
/** @brief return true if username password combo is correct */
|
||||
virtual bool CheckLogin(const std::string & user, const std::string & passwd) = 0;
|
||||
virtual ~NNTPCredentialDB() {}
|
||||
};
|
||||
/** @brief nntp credential db interface */
|
||||
class NNTPCredentialDB
|
||||
{
|
||||
public:
|
||||
/** @brief open connection to database, return false on error otherwise return true */
|
||||
virtual bool Open() = 0;
|
||||
/** @brief close connection to database */
|
||||
virtual void Close() = 0;
|
||||
/** @brief return true if username password combo is correct */
|
||||
virtual bool CheckLogin(const std::string &user, const std::string &passwd) = 0;
|
||||
virtual ~NNTPCredentialDB() {}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<NNTPCredentialDB> CredDB_ptr;
|
||||
|
||||
/** @brief nntp credential db using hashed+salted passwords */
|
||||
class HashedCredDB : public NNTPCredentialDB, public LineReader
|
||||
{
|
||||
public:
|
||||
HashedCredDB();
|
||||
bool CheckLogin(const std::string & user, const std::string & passwd);
|
||||
protected:
|
||||
void SetStream(std::istream * i);
|
||||
typedef std::shared_ptr<NNTPCredentialDB> CredDB_ptr;
|
||||
|
||||
std::string Hash(const std::string & data, const std::string & salt);
|
||||
void HandleLine(const std::string & line);
|
||||
private:
|
||||
bool ProcessLine(const std::string & line);
|
||||
/** @brief nntp credential db using hashed+salted passwords */
|
||||
class HashedCredDB : public NNTPCredentialDB, public LineReader
|
||||
{
|
||||
public:
|
||||
HashedCredDB();
|
||||
bool CheckLogin(const std::string &user, const std::string &passwd);
|
||||
|
||||
std::mutex m_access;
|
||||
std::string m_user, m_passwd;
|
||||
bool m_found;
|
||||
/** return true if we have a line that matches this username / password combo */
|
||||
std::istream * m_instream;
|
||||
};
|
||||
protected:
|
||||
void SetStream(std::istream *i);
|
||||
|
||||
class HashedFileDB : public HashedCredDB
|
||||
{
|
||||
public:
|
||||
HashedFileDB(const std::string & fname);
|
||||
~HashedFileDB();
|
||||
bool Open();
|
||||
void Close();
|
||||
private:
|
||||
std::string m_fname;
|
||||
std::ifstream f;
|
||||
};
|
||||
std::string Hash(const std::string &data, const std::string &salt);
|
||||
void HandleLine(const std::string &line);
|
||||
|
||||
private:
|
||||
bool ProcessLine(const std::string &line);
|
||||
|
||||
std::mutex m_access;
|
||||
std::string m_user, m_passwd;
|
||||
bool m_found;
|
||||
/** return true if we have a line that matches this username / password combo */
|
||||
std::istream *m_instream;
|
||||
};
|
||||
|
||||
class HashedFileDB : public HashedCredDB
|
||||
{
|
||||
public:
|
||||
HashedFileDB(const std::string &fname);
|
||||
~HashedFileDB();
|
||||
bool Open();
|
||||
void Close();
|
||||
|
||||
private:
|
||||
std::string m_fname;
|
||||
std::ifstream f;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,62 +1,61 @@
|
||||
#ifndef NNTPCHAN_NNTP_HANDLER_HPP
|
||||
#define NNTPCHAN_NNTP_HANDLER_HPP
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include "line.hpp"
|
||||
#include "nntp_auth.hpp"
|
||||
#include "storage.hpp"
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
class NNTPServerHandler : public LineReader, public IConnHandler
|
||||
class NNTPServerHandler : public LineReader, public IConnHandler
|
||||
{
|
||||
public:
|
||||
NNTPServerHandler(const fs::path &storage);
|
||||
~NNTPServerHandler();
|
||||
|
||||
virtual bool ShouldClose();
|
||||
|
||||
void SetAuth(CredDB_ptr creds);
|
||||
|
||||
virtual void OnData(const char *, ssize_t);
|
||||
|
||||
void Greet();
|
||||
|
||||
protected:
|
||||
void HandleLine(const std::string &line);
|
||||
void HandleCommand(const std::deque<std::string> &command);
|
||||
|
||||
private:
|
||||
enum State
|
||||
{
|
||||
public:
|
||||
NNTPServerHandler(const fs::path & storage);
|
||||
~NNTPServerHandler();
|
||||
|
||||
virtual bool ShouldClose();
|
||||
|
||||
void SetAuth(CredDB_ptr creds);
|
||||
|
||||
virtual void OnData(const char *, ssize_t);
|
||||
|
||||
void Greet();
|
||||
|
||||
protected:
|
||||
void HandleLine(const std::string & line);
|
||||
void HandleCommand(const std::deque<std::string> & command);
|
||||
private:
|
||||
|
||||
enum State {
|
||||
eStateReadCommand,
|
||||
eStateStoreArticle,
|
||||
eStateQuit
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
void EnterState(State st);
|
||||
|
||||
void ArticleObtained();
|
||||
|
||||
// handle quit command, this queues a reply
|
||||
void Quit();
|
||||
|
||||
// switch nntp modes, this queues a reply
|
||||
void SwitchMode(const std::string & mode);
|
||||
|
||||
bool PostingAllowed();
|
||||
|
||||
private:
|
||||
std::string m_articleName;
|
||||
FileHandle_ptr m_article;
|
||||
CredDB_ptr m_auth;
|
||||
ArticleStorage_ptr m_store;
|
||||
std::string m_mode;
|
||||
bool m_authed;
|
||||
State m_state;
|
||||
eStateReadCommand,
|
||||
eStateStoreArticle,
|
||||
eStateQuit
|
||||
};
|
||||
|
||||
private:
|
||||
void EnterState(State st);
|
||||
|
||||
void ArticleObtained();
|
||||
|
||||
// handle quit command, this queues a reply
|
||||
void Quit();
|
||||
|
||||
// switch nntp modes, this queues a reply
|
||||
void SwitchMode(const std::string &mode);
|
||||
|
||||
bool PostingAllowed();
|
||||
|
||||
private:
|
||||
std::string m_articleName;
|
||||
FileHandle_ptr m_article;
|
||||
CredDB_ptr m_auth;
|
||||
ArticleStorage_ptr m_store;
|
||||
std::string m_mode;
|
||||
bool m_authed;
|
||||
State m_state;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,62 +1,57 @@
|
||||
#ifndef NNTPCHAN_NNTP_SERVER_HPP
|
||||
#define NNTPCHAN_NNTP_SERVER_HPP
|
||||
#include <uv.h>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include "frontend.hpp"
|
||||
#include "server.hpp"
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
class NNTPServer : public Server
|
||||
{
|
||||
public:
|
||||
class NNTPServer : public Server
|
||||
{
|
||||
public:
|
||||
NNTPServer(uv_loop_t *loop);
|
||||
|
||||
NNTPServer(uv_loop_t * loop);
|
||||
virtual ~NNTPServer();
|
||||
|
||||
virtual ~NNTPServer();
|
||||
void SetStoragePath(const std::string &path);
|
||||
|
||||
void SetStoragePath(const std::string & path);
|
||||
void SetLoginDB(const std::string path);
|
||||
|
||||
void SetLoginDB(const std::string path);
|
||||
void SetInstanceName(const std::string &name);
|
||||
|
||||
void SetInstanceName(const std::string & name);
|
||||
std::string InstanceName() const;
|
||||
|
||||
std::string InstanceName() const;
|
||||
void Close();
|
||||
|
||||
void Close();
|
||||
virtual IServerConn *CreateConn(uv_stream_t *s);
|
||||
|
||||
virtual IServerConn * CreateConn(uv_stream_t * s);
|
||||
virtual void OnAcceptError(int status);
|
||||
|
||||
virtual void OnAcceptError(int status);
|
||||
void SetFrontend(Frontend *f);
|
||||
|
||||
void SetFrontend(Frontend * f);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string m_logindbpath;
|
||||
std::string m_storagePath;
|
||||
std::string m_servername;
|
||||
|
||||
std::string m_logindbpath;
|
||||
std::string m_storagePath;
|
||||
std::string m_servername;
|
||||
Frontend_ptr m_frontend;
|
||||
};
|
||||
|
||||
Frontend_ptr m_frontend;
|
||||
class NNTPServerConn : public IServerConn
|
||||
{
|
||||
public:
|
||||
NNTPServerConn(uv_loop_t *l, uv_stream_t *s, Server *parent, IConnHandler *h) : IServerConn(l, s, parent, h) {}
|
||||
|
||||
};
|
||||
virtual bool IsTimedOut() { return false; };
|
||||
|
||||
class NNTPServerConn : public IServerConn
|
||||
{
|
||||
public:
|
||||
/** @brief send next queued reply */
|
||||
virtual void SendNextReply();
|
||||
|
||||
NNTPServerConn(uv_loop_t * l, uv_stream_t * s, Server * parent, IConnHandler * h) : IServerConn(l, s, parent, h) {}
|
||||
|
||||
virtual bool IsTimedOut() { return false; };
|
||||
|
||||
/** @brief send next queued reply */
|
||||
virtual void SendNextReply();
|
||||
|
||||
virtual void Greet();
|
||||
|
||||
};
|
||||
virtual void Greet();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -4,11 +4,11 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
std::string NNTPSanitizeLine(const std::string & str);
|
||||
std::string ToLower(const std::string & str);
|
||||
std::string StripWhitespaces(const std::string & str);
|
||||
bool IsValidMessageID(const std::string & msgid);
|
||||
bool IsValidNewsgroup(const std::string & group);
|
||||
std::string NNTPSanitizeLine(const std::string &str);
|
||||
std::string ToLower(const std::string &str);
|
||||
std::string StripWhitespaces(const std::string &str);
|
||||
bool IsValidMessageID(const std::string &msgid);
|
||||
bool IsValidNewsgroup(const std::string &group);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,98 +1,97 @@
|
||||
#ifndef NNTPCHAN_SERVER_HPP
|
||||
#define NNTPCHAN_SERVER_HPP
|
||||
#include <uv.h>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
class Server;
|
||||
class Server;
|
||||
|
||||
struct IConnHandler
|
||||
{
|
||||
|
||||
struct IConnHandler
|
||||
{
|
||||
virtual ~IConnHandler(){};
|
||||
|
||||
virtual ~IConnHandler() {};
|
||||
/** got inbound data */
|
||||
virtual void OnData(const char *data, ssize_t s) = 0;
|
||||
|
||||
/** got inbound data */
|
||||
virtual void OnData(const char * data, ssize_t s) = 0;
|
||||
/** get next line of data to send */
|
||||
std::string GetNextLine();
|
||||
|
||||
/** get next line of data to send */
|
||||
std::string GetNextLine();
|
||||
/** return true if we have a line to send */
|
||||
bool HasNextLine();
|
||||
|
||||
/** return true if we have a line to send */
|
||||
bool HasNextLine();
|
||||
/** return true if we should close this connection otherwise return false */
|
||||
virtual bool ShouldClose() = 0;
|
||||
|
||||
/** return true if we should close this connection otherwise return false */
|
||||
virtual bool ShouldClose() = 0;
|
||||
/** queue a data send */
|
||||
void QueueLine(const std::string &line);
|
||||
|
||||
/** queue a data send */
|
||||
void QueueLine(const std::string & line);
|
||||
virtual void Greet() = 0;
|
||||
|
||||
virtual void Greet() = 0;
|
||||
private:
|
||||
std::deque<std::string> m_sendlines;
|
||||
};
|
||||
|
||||
/** server connection handler interface */
|
||||
struct IServerConn
|
||||
{
|
||||
IServerConn(uv_loop_t *l, uv_stream_t *s, Server *parent, IConnHandler *h);
|
||||
virtual ~IServerConn();
|
||||
virtual void Close();
|
||||
virtual void Greet() = 0;
|
||||
virtual void SendNextReply() = 0;
|
||||
virtual bool IsTimedOut() = 0;
|
||||
void SendString(const std::string &str);
|
||||
Server *Parent() { return m_parent; };
|
||||
IConnHandler *GetHandler() { return m_handler; };
|
||||
uv_loop_t *GetLoop() { return m_loop; };
|
||||
|
||||
private:
|
||||
std::deque<std::string> m_sendlines;
|
||||
};
|
||||
private:
|
||||
uv_tcp_t m_conn;
|
||||
uv_loop_t *m_loop;
|
||||
Server *m_parent;
|
||||
IConnHandler *m_handler;
|
||||
};
|
||||
|
||||
/** server connection handler interface */
|
||||
struct IServerConn
|
||||
{
|
||||
IServerConn(uv_loop_t * l, uv_stream_t * s, Server * parent, IConnHandler * h);
|
||||
virtual ~IServerConn();
|
||||
virtual void Close();
|
||||
virtual void Greet() = 0;
|
||||
virtual void SendNextReply() = 0;
|
||||
virtual bool IsTimedOut() = 0;
|
||||
void SendString(const std::string & str);
|
||||
Server * Parent() { return m_parent; };
|
||||
IConnHandler * GetHandler() { return m_handler; };
|
||||
uv_loop_t * GetLoop() { return m_loop; };
|
||||
private:
|
||||
uv_tcp_t m_conn;
|
||||
uv_loop_t * m_loop;
|
||||
Server * m_parent;
|
||||
IConnHandler * m_handler;
|
||||
};
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(uv_loop_t *loop);
|
||||
/** called after socket close, NEVER call directly */
|
||||
virtual ~Server() {}
|
||||
/** create connection handler from open stream */
|
||||
virtual IServerConn *CreateConn(uv_stream_t *s) = 0;
|
||||
/** close all sockets and stop */
|
||||
void Close();
|
||||
/** bind to address */
|
||||
void Bind(const std::string &addr);
|
||||
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(uv_loop_t * loop);
|
||||
/** called after socket close, NEVER call directly */
|
||||
virtual ~Server() {}
|
||||
/** create connection handler from open stream */
|
||||
virtual IServerConn * CreateConn(uv_stream_t * s) = 0;
|
||||
/** close all sockets and stop */
|
||||
void Close();
|
||||
/** bind to address */
|
||||
void Bind(const std::string & addr);
|
||||
typedef std::function<void(IServerConn *)> ConnVisitor;
|
||||
|
||||
typedef std::function<void(IServerConn *)> ConnVisitor;
|
||||
/** visit all open connections */
|
||||
void VisitConns(ConnVisitor v);
|
||||
|
||||
/** visit all open connections */
|
||||
void VisitConns(ConnVisitor v);
|
||||
/** remove connection from server, called after proper close */
|
||||
void RemoveConn(IServerConn *conn);
|
||||
|
||||
/** remove connection from server, called after proper close */
|
||||
void RemoveConn(IServerConn * conn);
|
||||
protected:
|
||||
uv_loop_t *GetLoop() { return m_loop; }
|
||||
virtual void OnAcceptError(int status) = 0;
|
||||
|
||||
protected:
|
||||
uv_loop_t * GetLoop() { return m_loop; }
|
||||
virtual void OnAcceptError(int status) = 0;
|
||||
private:
|
||||
operator uv_handle_t * () { return (uv_handle_t*) &m_server; }
|
||||
operator uv_tcp_t * () { return &m_server; }
|
||||
operator uv_stream_t * () { return (uv_stream_t *) &m_server; }
|
||||
private:
|
||||
operator uv_handle_t *() { return (uv_handle_t *)&m_server; }
|
||||
operator uv_tcp_t *() { return &m_server; }
|
||||
operator uv_stream_t *() { return (uv_stream_t *)&m_server; }
|
||||
|
||||
void OnAccept(uv_stream_t * s, int status);
|
||||
std::deque<IServerConn *> m_conns;
|
||||
uv_tcp_t m_server;
|
||||
uv_loop_t * m_loop;
|
||||
};
|
||||
void OnAccept(uv_stream_t *s, int status);
|
||||
std::deque<IServerConn *> m_conns;
|
||||
uv_tcp_t m_server;
|
||||
uv_loop_t *m_loop;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
std::string sha1_hex(const std::string & data);
|
||||
std::string sha1_hex(const std::string &data);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,34 +2,33 @@
|
||||
#define NNTPCHAN_STATICFILE_FRONTEND_HPP
|
||||
#include "frontend.hpp"
|
||||
#include "message.hpp"
|
||||
#include "template_engine.hpp"
|
||||
#include "model.hpp"
|
||||
#include "template_engine.hpp"
|
||||
#include <experimental/filesystem>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
class StaticFileFrontend : public Frontend
|
||||
{
|
||||
public:
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
StaticFileFrontend(TemplateEngine * tmpl, const std::string & templateDir, const std::string & outDir, uint32_t pages);
|
||||
|
||||
~StaticFileFrontend();
|
||||
class StaticFileFrontend : public Frontend
|
||||
{
|
||||
public:
|
||||
StaticFileFrontend(TemplateEngine *tmpl, const std::string &templateDir, const std::string &outDir, uint32_t pages);
|
||||
|
||||
void ProcessNewMessage(const fs::path & fpath);
|
||||
bool AcceptsNewsgroup(const std::string & newsgroup);
|
||||
bool AcceptsMessage(const std::string & msgid);
|
||||
~StaticFileFrontend();
|
||||
|
||||
private:
|
||||
MessageDB_ptr m_MessageDB;
|
||||
TemplateEngine_ptr m_TemplateEngine;
|
||||
fs::path m_TemplateDir;
|
||||
fs::path m_OutDir;
|
||||
uint32_t m_Pages;
|
||||
};
|
||||
void ProcessNewMessage(const fs::path &fpath);
|
||||
bool AcceptsNewsgroup(const std::string &newsgroup);
|
||||
bool AcceptsMessage(const std::string &msgid);
|
||||
|
||||
private:
|
||||
MessageDB_ptr m_MessageDB;
|
||||
TemplateEngine_ptr m_TemplateEngine;
|
||||
fs::path m_TemplateDir;
|
||||
fs::path m_OutDir;
|
||||
uint32_t m_Pages;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,53 +1,50 @@
|
||||
#ifndef NNTPCHAN_STORAGE_HPP
|
||||
#define NNTPCHAN_STORAGE_HPP
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <string>
|
||||
#include "file_handle.hpp"
|
||||
#include "message.hpp"
|
||||
#include <experimental/filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
class ArticleStorage : public MessageDB
|
||||
{
|
||||
public:
|
||||
ArticleStorage();
|
||||
ArticleStorage(const fs::path & fpath);
|
||||
~ArticleStorage();
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
FileHandle_ptr OpenWrite(const std::string & msgid) const;
|
||||
FileHandle_ptr OpenRead(const std::string & msgid) const;
|
||||
class ArticleStorage : public MessageDB
|
||||
{
|
||||
public:
|
||||
ArticleStorage(const fs::path &fpath);
|
||||
~ArticleStorage();
|
||||
|
||||
/**
|
||||
return true if we should accept a new message give its message id
|
||||
*/
|
||||
bool Accept(const std::string & msgid) const;
|
||||
FileHandle_ptr OpenWrite(const std::string &msgid) const;
|
||||
FileHandle_ptr OpenRead(const std::string &msgid) const;
|
||||
|
||||
bool LoadBoardPage(BoardPage & board, const std::string & newsgroup, uint32_t perpage, uint32_t page) const;
|
||||
bool FindThreadByHash(const std::string & hashhex, std::string & msgid) const;
|
||||
bool LoadThread(Thread & thread, const std::string & rootmsgid) const;
|
||||
/**
|
||||
return true if we should accept a new message give its message id
|
||||
*/
|
||||
bool Accept(const std::string &msgid) const;
|
||||
|
||||
/** ensure symlinks are formed for this article by message id */
|
||||
void EnsureSymlinks(const std::string & msgid) const;
|
||||
|
||||
private:
|
||||
void SetPath(const fs::path & fpath);
|
||||
bool LoadBoardPage(BoardPage &board, const std::string &newsgroup, uint32_t perpage, uint32_t page) const;
|
||||
bool FindThreadByHash(const std::string &hashhex, std::string &msgid) const;
|
||||
bool LoadThread(Thread &thread, const std::string &rootmsgid) const;
|
||||
|
||||
fs::path MessagePath(const std::string & msgid) const;
|
||||
/** ensure symlinks are formed for this article by message id */
|
||||
void EnsureSymlinks(const std::string &msgid) const;
|
||||
|
||||
bool init_skiplist(const std::string & subdir) const;
|
||||
private:
|
||||
void SetPath(const fs::path &fpath);
|
||||
|
||||
fs::path skiplist_root(const std::string & name) const;
|
||||
|
||||
fs::path basedir;
|
||||
fs::path MessagePath(const std::string &msgid) const;
|
||||
|
||||
};
|
||||
bool init_skiplist(const std::string &subdir) const;
|
||||
|
||||
typedef std::unique_ptr<ArticleStorage> ArticleStorage_ptr;
|
||||
fs::path skiplist_root(const std::string &name) const;
|
||||
|
||||
fs::path basedir;
|
||||
};
|
||||
|
||||
typedef std::unique_ptr<ArticleStorage> ArticleStorage_ptr;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -10,15 +10,15 @@
|
||||
namespace nntpchan
|
||||
{
|
||||
|
||||
struct TemplateEngine
|
||||
{
|
||||
typedef std::map<std::string, std::variant<nntpchan::model::Model, std::string>> Args_t;
|
||||
virtual bool WriteTemplate(const fs::path & template_fpath, const Args_t & args, const FileHandle_ptr & out) = 0;
|
||||
};
|
||||
struct TemplateEngine
|
||||
{
|
||||
typedef std::map<std::string, std::variant<nntpchan::model::Model, std::string>> Args_t;
|
||||
virtual bool WriteTemplate(const fs::path &template_fpath, const Args_t &args, const FileHandle_ptr &out) = 0;
|
||||
};
|
||||
|
||||
TemplateEngine * CreateTemplateEngine(const std::string & dialect);
|
||||
TemplateEngine *CreateTemplateEngine(const std::string &dialect);
|
||||
|
||||
typedef std::unique_ptr<TemplateEngine> TemplateEngine_ptr;
|
||||
typedef std::unique_ptr<TemplateEngine> TemplateEngine_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user