diff --git a/contrib/backends/nntpchan-daemon/src/crypto.hpp b/contrib/backends/nntpchan-daemon/src/crypto.hpp index c563566..3f8bd04 100644 --- a/contrib/backends/nntpchan-daemon/src/crypto.hpp +++ b/contrib/backends/nntpchan-daemon/src/crypto.hpp @@ -10,6 +10,25 @@ namespace nntpchan void SHA512(const uint8_t * d, std::size_t l, SHA512Digest & h); + enum HashType + { + eHashTypeSHA1, + eHashTypeSHA256, + eHashTypeSHA512, + eHashTypeBLAKE2B + }; + + template + struct Hasher + { + typedef std::function DigestVisitor; + + Hasher(); + ~Hasher(); + void Update(const char * data, size_t sz); + void Final(DigestVisitor v); + }; + /** global crypto initializer */ struct Crypto { diff --git a/contrib/backends/nntpchan-daemon/src/io.cpp b/contrib/backends/nntpchan-daemon/src/io.cpp new file mode 100644 index 0000000..a8099de --- /dev/null +++ b/contrib/backends/nntpchan-daemon/src/io.cpp @@ -0,0 +1,58 @@ +#include "io.hpp" + +namespace nntpchan +{ + namespace io + { + + template + struct MultiWriter : public std::basic_streambuf , public std::basic_ostream + { + using Base = std::basic_streambuf; + using char_type = typename Base::char_type; + using int_type = typename Base::int_type; + + std::vector *> writers; + + int_type overflow(int_type ch) + { + return Base::overflow(ch); + } + + virtual std::streamsize xputn(const char_type * data, std::streamsize sz) + { + for(const auto & itr : writers) + itr->write(data, sz); + return sz; + } + + virtual int sync() + { + for(const auto & itr : writers) + itr->flush(); + return 0; + } + + void AddWriter(std::basic_ostream * wr) + { + writers.push_back(wr); + } + + virtual ~MultiWriter() + { + for(const auto & itr : writers) + delete itr; + } + + }; + + + std::basic_ostream * multiWriter(const std::vector *> & writers) + { + MultiWriter * wr = new MultiWriter; + for(auto & itr : writers) + wr->AddWriter(itr); + return wr; + } + } +} diff --git a/contrib/backends/nntpchan-daemon/src/io.hpp b/contrib/backends/nntpchan-daemon/src/io.hpp new file mode 100644 index 0000000..b36ef9a --- /dev/null +++ b/contrib/backends/nntpchan-daemon/src/io.hpp @@ -0,0 +1,34 @@ +#ifndef NNTPCHAN_IO_HPP +#define NNTPCHAN_IO_HPP +#include +#include + + +namespace nntpchan +{ + namespace io + { + template + ssize_t copy(std::ostream * dst, std::istream * src) + { + char buff[bufferSize]; + ssize_t n = 0; + while(!src->eof() && src->good()) + { + std::streamsize sz; + src->read(buff, bufferSize); + sz = src->gcount(); + n += sz; + dst->write(buff, sz); + if(!dst->good()) + break; + } + return n; + } + + std::basic_ostream * multiWriter(const std::vector *> & writers); + std::basic_istream * teeReader(std::basic_istream * i, std::basic_ostream * o); + } +} + +#endif diff --git a/contrib/backends/nntpchan-daemon/src/message.hpp b/contrib/backends/nntpchan-daemon/src/message.hpp index d9aa49b..8e018ea 100644 --- a/contrib/backends/nntpchan-daemon/src/message.hpp +++ b/contrib/backends/nntpchan-daemon/src/message.hpp @@ -1,33 +1,26 @@ #ifndef NNTPCHAN_MESSAGE_HPP #define NNTPCHAN_MESSAGE_HPP +#include #include #include -#include -#include namespace nntpchan { bool IsValidMessageID(const std::string & msgid); - typedef std::pair MessageHeader; + namespace mime + { + typedef std::function HeaderValueVisitor; - typedef std::map MIMEPartHeader; + struct PartHeader + { + std::string boundary; + std::map values; - typedef std::function MessageHeaderFilter; - - typedef std::function MIMEPartFilter; - - /** - read MIME message from i, - filter each header with h, - filter each part with p, - store result in o - - return true if we read the whole message, return false if there is remaining - */ - bool StoreMIMEMessage(std::istream & i, MessageHeaderFilter h, MIMEPartHeader p, std::ostream & o); + }; + } } diff --git a/contrib/backends/nntpchan-daemon/src/nntp_filter.hpp b/contrib/backends/nntpchan-daemon/src/nntp_filter.hpp new file mode 100644 index 0000000..fb0a389 --- /dev/null +++ b/contrib/backends/nntpchan-daemon/src/nntp_filter.hpp @@ -0,0 +1,26 @@ +#ifndef NNTP_FILTER_HPP +#define NNTP_FILTER_HPP + +#include +#include + +namespace nntpchan +{ + + template + struct MessageFilter : public std::basic_ostream + { + using Base = std::basic_streambuf; + using char_type = Base::char_type; + using int_type = Base::int_type; + + virtual int_type overflow(int_type ch); + protected: + virtual void xsputn(const char_type * data, std::streamsize sz); + + + + }; +} + +#endif diff --git a/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp b/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp index 327cd49..c86ccdb 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp @@ -1,5 +1,7 @@ #include "nntp_handler.hpp" +#include "io.hpp" #include "message.hpp" + #include #include #include @@ -125,7 +127,9 @@ namespace nntpchan const std::string & msgid = command[1]; if(m_store.Accept(msgid)) { - m_article = m_store.OpenWrite(msgid); + std::ostream * file = m_store.OpenWrite(msgid); + m_filter = new MessageFilter(msgid); + m_article = nntpchan::io::multiWriter({file, m_filter}); } m_articleName = msgid; EnterState(eStateStoreArticle); diff --git a/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp b/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp index 64d708d..0a109e1 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp @@ -4,6 +4,7 @@ #include #include "line.hpp" #include "nntp_auth.hpp" +#include "nntp_filter.hpp" #include "storage.hpp" namespace nntpchan @@ -50,6 +51,7 @@ namespace nntpchan private: std::string m_articleName; std::fstream * m_article; + MessageFilter * m_filter; NNTPCredentialDB * m_auth; ArticleStorage m_store; std::string m_mode;