Archived
1
0
This repository has been archived on 2023-08-12. You can view files and clone it, but cannot push or open issues or pull requests.
nntpchan/contrib/backends/nntpchan-daemon/libnntpchan/server.cpp

153 lines
2.6 KiB
C++
Raw Normal View History

2017-05-03 17:09:23 +05:00
#include <cassert>
2017-05-03 18:15:06 +05:00
#include <iostream>
2017-10-17 19:29:56 +05:00
#include <nntpchan/buffer.hpp>
#include <nntpchan/net.hpp>
#include <nntpchan/server.hpp>
2017-05-03 17:09:23 +05:00
namespace nntpchan
{
2018-05-03 20:47:20 +05:00
Server::Server(ev::Loop * loop) : ev::io(-1), m_Loop(loop)
2017-10-17 19:29:56 +05:00
{
}
2017-05-03 17:09:23 +05:00
2018-05-03 20:47:20 +05:00
void Server::close()
2017-10-17 19:29:56 +05:00
{
2018-05-03 20:47:20 +05:00
auto itr = m_conns.begin();
while(itr != m_conns.end())
{
itr = m_conns.erase(itr);
}
m_Loop->UntrackConn(this);
2018-05-03 20:47:20 +05:00
ev::io::close();
2017-10-17 19:29:56 +05:00
}
2018-05-03 20:47:20 +05:00
bool Server::Bind(const std::string &addr)
2017-10-17 19:29:56 +05:00
{
auto saddr = ParseAddr(addr);
return m_Loop->BindTCP(saddr, this);
2017-10-17 19:29:56 +05:00
}
2017-05-03 17:09:23 +05:00
2018-05-04 18:52:54 +05:00
void Server::OnAccept(int f)
2017-10-17 19:29:56 +05:00
{
2018-05-04 18:52:54 +05:00
IServerConn *conn = CreateConn(f);
if(!m_Loop->SetNonBlocking(conn))
2017-05-03 17:09:23 +05:00
{
2018-05-04 18:52:54 +05:00
conn->close();
delete conn;
2017-05-03 17:09:23 +05:00
}
2018-05-04 18:52:54 +05:00
else if(m_Loop->TrackConn(conn))
2018-05-03 20:47:20 +05:00
{
m_conns.push_back(conn);
conn->Greet();
conn->write();
}
else
{
conn->close();
delete conn;
}
}
int Server::accept()
{
2018-05-04 18:52:54 +05:00
int res = ::accept(fd, nullptr, nullptr);
2018-05-03 20:47:20 +05:00
if(res == -1) return res;
2018-05-04 18:52:54 +05:00
OnAccept(res);
2018-05-03 20:47:20 +05:00
return res;
2017-10-17 19:29:56 +05:00
}
2017-05-03 17:09:23 +05:00
2017-10-17 19:29:56 +05:00
void Server::RemoveConn(IServerConn *conn)
{
auto itr = m_conns.begin();
while (itr != m_conns.end())
2017-05-03 18:15:06 +05:00
{
2017-10-17 19:29:56 +05:00
if (*itr == conn)
itr = m_conns.erase(itr);
else
++itr;
2017-05-03 18:15:06 +05:00
}
m_Loop->UntrackConn(conn);
2017-10-17 19:29:56 +05:00
}
2017-05-03 18:15:06 +05:00
2018-05-03 20:47:20 +05:00
void IConnHandler::QueueLine(const std::string &line) { m_sendlines.push_back(line+"\r\n"); }
2017-05-03 17:09:23 +05:00
2017-10-17 19:29:56 +05:00
bool IConnHandler::HasNextLine() { return m_sendlines.size() > 0; }
2017-05-03 17:09:23 +05:00
2017-10-17 19:29:56 +05:00
std::string IConnHandler::GetNextLine()
{
std::string line = m_sendlines[0];
m_sendlines.pop_front();
return line;
}
2017-05-03 18:15:06 +05:00
2018-05-03 20:47:20 +05:00
IServerConn::IServerConn(int fd, Server *parent, IConnHandler *h) : ev::io(fd), m_parent(parent), m_handler(h)
2017-10-17 19:29:56 +05:00
{
}
2017-05-03 18:15:06 +05:00
2017-10-17 19:29:56 +05:00
IServerConn::~IServerConn() { delete m_handler; }
2017-05-03 18:15:06 +05:00
2018-05-03 20:47:20 +05:00
int IServerConn::read(char * buf, size_t sz)
{
ssize_t readsz = ::read(fd, buf, sz);
if(readsz > 0)
{
m_handler->OnData(buf, readsz);
}
return readsz;
}
bool IServerConn::keepalive()
{
return !m_handler->ShouldClose();
}
int IServerConn::write()
2017-10-17 19:29:56 +05:00
{
2018-05-03 20:47:20 +05:00
auto leftovers = m_writeLeftover.size();
ssize_t written;
if(leftovers)
{
if(leftovers > 1024)
{
leftovers = 1024;
}
written = ::write(fd, m_writeLeftover.c_str(), leftovers);
if(written > 0)
{
m_writeLeftover = m_writeLeftover.substr(written);
}
else
{
// too much leftovers
return -1;
}
}
do
{
if(!m_handler->HasNextLine())
{
return 0;
}
auto line = m_handler->GetNextLine();
written = ::write(fd, line.c_str(), line.size());
if(written > 0)
{
m_writeLeftover = line.substr(written);
}
else
{
m_writeLeftover = line;
return -1;
}
}
while(written > 0);
return 0;
2017-10-17 19:29:56 +05:00
}
2017-05-03 18:15:06 +05:00
2018-05-03 20:47:20 +05:00
void IServerConn::close()
2017-10-17 19:29:56 +05:00
{
m_parent->RemoveConn(this);
2018-05-03 20:47:20 +05:00
ev::io::close();
2017-10-17 19:29:56 +05:00
}
2017-05-03 17:09:23 +05:00
}