From dba185c6aab70370b5f31a0470697e6d98d5c7b0 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Wed, 3 May 2017 09:15:06 -0400 Subject: [PATCH] compiles --- contrib/backends/nntpchan-daemon/src/line.hpp | 2 +- .../nntpchan-daemon/src/nntp_handler.cpp | 7 +- .../nntpchan-daemon/src/nntp_handler.hpp | 14 ++- .../nntpchan-daemon/src/nntp_server.cpp | 112 ++++-------------- .../nntpchan-daemon/src/nntp_server.hpp | 63 ++++------ .../backends/nntpchan-daemon/src/server.cpp | 78 ++++++++++++ .../backends/nntpchan-daemon/src/server.hpp | 16 ++- 7 files changed, 145 insertions(+), 147 deletions(-) diff --git a/contrib/backends/nntpchan-daemon/src/line.hpp b/contrib/backends/nntpchan-daemon/src/line.hpp index 1592280..825deac 100644 --- a/contrib/backends/nntpchan-daemon/src/line.hpp +++ b/contrib/backends/nntpchan-daemon/src/line.hpp @@ -6,7 +6,7 @@ namespace nntpchan { /** @brief a buffered line reader */ - class LineReader : public IConnHandler + class LineReader { public: diff --git a/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp b/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp index a53bbeb..d49a7a1 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_handler.cpp @@ -21,6 +21,11 @@ namespace nntpchan if(m_auth) delete m_auth; } + void NNTPServerHandler::OnData(const char * data, ssize_t sz) + { + LineReader::OnData(data, sz); + } + void NNTPServerHandler::HandleLine(const std::string &line) { if(m_state == eStateReadCommand) { @@ -92,7 +97,7 @@ namespace nntpchan QueueLine("205 quitting"); } - bool NNTPServerHandler::Done() + bool NNTPServerHandler::ShouldClose() { return m_state == eStateQuit; } diff --git a/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp b/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp index 69e277a..edfa68e 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_handler.hpp @@ -8,23 +8,25 @@ namespace nntpchan { - class NNTPServerHandler : public LineReader + class NNTPServerHandler : public LineReader, public IConnHandler { public: NNTPServerHandler(const std::string & storage); ~NNTPServerHandler(); - - bool Done(); + + virtual bool ShouldClose(); + + virtual void OnData(const char * data, ssize_t sz); void SetAuth(NNTPCredentialDB * creds); void Greet(); - + protected: void HandleLine(const std::string & line); void HandleCommand(const std::deque & command); private: - + enum State { eStateReadCommand, eStateStoreArticle, @@ -39,7 +41,7 @@ namespace nntpchan void SwitchMode(const std::string & mode); bool PostingAllowed(); - + private: NNTPCredentialDB * m_auth; ArticleStorage m_store; diff --git a/contrib/backends/nntpchan-daemon/src/nntp_server.cpp b/contrib/backends/nntpchan-daemon/src/nntp_server.cpp index d3d29b2..86e4d1e 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_server.cpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_server.cpp @@ -1,6 +1,7 @@ -#include "buffer.hpp" + #include "nntp_server.hpp" #include "nntp_auth.hpp" +#include "nntp_handler.hpp" #include "net.hpp" #include #include @@ -8,56 +9,29 @@ namespace nntpchan { - NNTPServer::NNTPServer(uv_loop_t * loop) - { - uv_tcp_init(loop, &m_server); - m_loop = loop; - m_server.data = this; - } + + NNTPServer::NNTPServer(uv_loop_t * loop) : Server(loop), m_frontend(nullptr) {} NNTPServer::~NNTPServer() { if (m_frontend) delete m_frontend; } - void NNTPServer::Close() + IServerConn * NNTPServer::CreateConn(uv_stream_t * s) { - uv_close((uv_handle_t*)&m_server, [](uv_handle_t * s) { - NNTPServer * self = (NNTPServer*)s->data; - if (self) delete self; - s->data = nullptr; - }); - } - - void NNTPServer::Bind(const std::string & addr) - { - auto saddr = ParseAddr(addr); - assert(uv_tcp_bind(*this, saddr, 0) == 0); - std::cerr << "nntp server bound to " << saddr.to_string() << std::endl; - auto cb = [] (uv_stream_t * s, int status) { - NNTPServer * self = (NNTPServer *) s->data; - self->OnAccept(s, status); - }; - - assert(uv_listen(*this, 5, cb) == 0); - } - - void NNTPServer::OnAccept(uv_stream_t * s, int status) - { - if(status < 0) { - std::cerr << "nntp server OnAccept fail: " << uv_strerror(status) << std::endl; - return; - } NNTPCredentialDB * creds = nullptr; std::ifstream i; i.open(m_logindbpath); if(i.is_open()) creds = new HashedFileDB(m_logindbpath); - NNTPServerConn * conn = new NNTPServerConn(m_loop, s, m_storagePath, creds); - conn->Greet(); - } + NNTPServerHandler * handler = new NNTPServerHandler(m_storagePath); + if(creds) + handler->SetAuth(creds); + NNTPServerConn * conn = new NNTPServerConn(GetLoop(), s, this, handler); + return conn; + } void NNTPServer::SetLoginDB(const std::string path) { @@ -76,74 +50,28 @@ namespace nntpchan m_frontend = f; } - NNTPServerConn::NNTPServerConn(uv_loop_t * l, uv_stream_t * s, const std::string & storage, NNTPCredentialDB * creds) : - m_handler(storage) + void NNTPServer::OnAcceptError(int status) { - m_handler.SetAuth(creds); - uv_tcp_init(l, &m_conn); - m_conn.data = this; - uv_accept(s, (uv_stream_t*) &m_conn); - uv_read_start((uv_stream_t*) &m_conn, [] (uv_handle_t * h, size_t s, uv_buf_t * b) { - NNTPServerConn * self = (NNTPServerConn*) h->data; - if(self == nullptr) return; - b->base = self->m_readbuff; - if (s > sizeof(self->m_readbuff)) - b->len = sizeof(self->m_readbuff); - else - b->len = s; - }, [] (uv_stream_t * s, ssize_t nread, const uv_buf_t * b) { - NNTPServerConn * self = (NNTPServerConn*) s->data; - if(self == nullptr) return; - if(nread > 0) { - self->m_handler.OnData(b->base, nread); - self->SendNextReply(); - if(self->m_handler.Done()) - self->Close(); - } else { - if (nread != UV_EOF) { - std::cerr << "error in nntp server conn alloc: "; - std::cerr << uv_strerror(nread); - std::cerr << std::endl; - } - // got eof or error - self->Close(); - } - }); + std::cerr << "nntpserver::accept() " << uv_strerror(status) << std::endl; } void NNTPServerConn::SendNextReply() { - if(m_handler.HasNextLine()) { - auto line = m_handler.GetNextLine(); - SendString(line+"\n"); + IConnHandler * handler = GetHandler(); + if(handler->HasNextLine()) { + auto line = handler->GetNextLine(); + SendString(line + "\n"); } } void NNTPServerConn::Greet() { - m_handler.Greet(); + IConnHandler * handler = GetHandler(); + handler->Greet(); SendNextReply(); } - void NNTPServerConn::SendString(const std::string & str) - { - WriteBuffer * b = new WriteBuffer(str); - uv_write(&b->w, *this, &b->b, 1, [](uv_write_t * w, int status) { - (void) status; - WriteBuffer * wb = (WriteBuffer *) w->data; - if(wb) - delete wb; - }); - } - void NNTPServerConn::Close() - { - uv_close((uv_handle_t*)&m_conn, [] (uv_handle_t * s) { - NNTPServerConn * self = (NNTPServerConn*) s->data; - if(self) - delete self; - s->data = nullptr; - }); - } + } diff --git a/contrib/backends/nntpchan-daemon/src/nntp_server.hpp b/contrib/backends/nntpchan-daemon/src/nntp_server.hpp index 5c36ff7..cc8973c 100644 --- a/contrib/backends/nntpchan-daemon/src/nntp_server.hpp +++ b/contrib/backends/nntpchan-daemon/src/nntp_server.hpp @@ -3,25 +3,19 @@ #include #include #include -#include "storage.hpp" #include "frontend.hpp" -#include "nntp_auth.hpp" -#include "nntp_handler.hpp" +#include "server.hpp" namespace nntpchan { - - class NNTPServerConn; - - class NNTPServer + + class NNTPServer : public Server { public: + NNTPServer(uv_loop_t * loop); - ~NNTPServer(); - void Bind(const std::string & addr); - - void OnAccept(uv_stream_t * s, int status); + virtual ~NNTPServer(); void SetStoragePath(const std::string & path); @@ -30,50 +24,33 @@ namespace nntpchan void SetFrontend(Frontend * f); void Close(); - + + virtual IServerConn * CreateConn(uv_stream_t * s); + + virtual void OnAcceptError(int status); + 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; } - - uv_tcp_t m_server; - uv_loop_t * m_loop; - - std::deque m_conns; std::string m_logindbpath; std::string m_storagePath; Frontend * m_frontend; - + }; - - class NNTPServerConn + + class NNTPServerConn : public IServerConn { public: - NNTPServerConn(uv_loop_t * l, uv_stream_t * s, const std::string & storage, NNTPCredentialDB * creds); - /** @brief close connection, this connection cannot be used after calling this */ - void Close(); - + + 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 */ - void SendNextReply(); + virtual void SendNextReply(); - void Greet(); - - private: + virtual void Greet(); - void SendString(const std::string & line); - - - operator uv_stream_t * () { return (uv_stream_t *) &m_conn; } - - uv_tcp_t m_conn; - - NNTPServerHandler m_handler; - - char m_readbuff[1028]; - }; } diff --git a/contrib/backends/nntpchan-daemon/src/server.cpp b/contrib/backends/nntpchan-daemon/src/server.cpp index ef43935..0c55d5f 100644 --- a/contrib/backends/nntpchan-daemon/src/server.cpp +++ b/contrib/backends/nntpchan-daemon/src/server.cpp @@ -1,6 +1,8 @@ +#include "buffer.hpp" #include "server.hpp" #include "net.hpp" #include +#include namespace nntpchan { @@ -42,6 +44,18 @@ namespace nntpchan conn->Greet(); } + void Server::RemoveConn(IServerConn * conn) + { + auto itr = m_conns.begin(); + while(itr != m_conns.end()) + { + if(*itr == conn) + itr = m_conns.erase(itr); + else + ++itr; + } + } + void IConnHandler::QueueLine(const std::string & line) { m_sendlines.push_back(line); @@ -58,4 +72,68 @@ namespace nntpchan m_sendlines.pop_front(); return line; } + + IServerConn::IServerConn(uv_loop_t * l, uv_stream_t * s, Server * parent, IConnHandler * h) + { + m_loop = l; + m_stream = s; + m_parent = parent; + m_handler = h; + uv_tcp_init(l, &m_conn); + m_conn.data = this; + uv_accept(s, (uv_stream_t*) &m_conn); + uv_read_start((uv_stream_t*) &m_conn, [] (uv_handle_t * h, size_t s, uv_buf_t * b) { + IServerConn * self = (IServerConn*) h->data; + if(self == nullptr) return; + b->base = self->m_readbuff; + if (s > sizeof(self->m_readbuff)) + b->len = sizeof(self->m_readbuff); + else + b->len = s; + }, [] (uv_stream_t * s, ssize_t nread, const uv_buf_t * b) { + IServerConn * self = (IServerConn*) s->data; + if(self == nullptr) return; + if(nread > 0) { + self->m_handler->OnData(b->base, nread); + self->SendNextReply(); + if(self->m_handler->ShouldClose()) + self->Close(); + } else { + if (nread != UV_EOF) { + std::cerr << "error in nntp server conn alloc: "; + std::cerr << uv_strerror(nread); + std::cerr << std::endl; + } + // got eof or error + self->Close(); + } + }); + } + + IServerConn::~IServerConn() + { + delete m_handler; + } + + void IServerConn::SendString(const std::string & str) + { + WriteBuffer * b = new WriteBuffer(str); + uv_write(&b->w, *this, &b->b, 1, [](uv_write_t * w, int status) { + (void) status; + WriteBuffer * wb = (WriteBuffer *) w->data; + if(wb) + delete wb; + }); + } + + void IServerConn::Close() + { + m_parent->RemoveConn(this); + uv_close((uv_handle_t*)&m_conn, [] (uv_handle_t * s) { + IServerConn * self = (IServerConn*) s->data; + if(self) + delete self; + s->data = nullptr; + }); + } } diff --git a/contrib/backends/nntpchan-daemon/src/server.hpp b/contrib/backends/nntpchan-daemon/src/server.hpp index d68d980..8bb3c1b 100644 --- a/contrib/backends/nntpchan-daemon/src/server.hpp +++ b/contrib/backends/nntpchan-daemon/src/server.hpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace nntpchan { @@ -14,6 +13,9 @@ namespace nntpchan struct IConnHandler { + + virtual ~IConnHandler() {}; + /** got inbound data */ virtual void OnData(const char * data, ssize_t s) = 0; @@ -29,6 +31,9 @@ namespace nntpchan /** queue a data send */ void QueueLine(const std::string & line); + virtual void Greet() = 0; + + private: std::deque m_sendlines; }; @@ -37,20 +42,23 @@ namespace nntpchan struct IServerConn { IServerConn(uv_loop_t * l, uv_stream_t * s, Server * parent, IConnHandler * h); - virtual ~IServerConn() = 0; - virtual void Close() = 0; + 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; }; operator uv_stream_t * () { return m_stream; }; uv_loop_t * GetLoop() { return m_loop; }; private: + uv_tcp_t m_conn; uv_stream_t * m_stream; uv_loop_t * m_loop; Server * m_parent; IConnHandler * m_handler; + char m_readbuff[4096]; }; class Server @@ -83,7 +91,7 @@ namespace nntpchan operator uv_stream_t * () { return (uv_stream_t *) &m_server; } void OnAccept(uv_stream_t * s, int status); - std::vector m_conns; + std::deque m_conns; uv_tcp_t m_server; uv_loop_t * m_loop; };