#include "conn.h"
#include "radlog.h"
+#include "stgpair.h"
#include "stg/json_parser.h"
#include "stg/json_generator.h"
std::map<std::string, Packet> packetCodes;
std::map<std::string, bool> resultCodes;
+std::map<std::string, int> returnCodes;
class PacketParser : public EnumParser<Packet>
{
}
};
+class ReturnCodeParser : public EnumParser<int>
+{
+ public:
+ ReturnCodeParser(NodeParser* next, int& returnCode, std::string& returnCodeStr)
+ : EnumParser(next, returnCode, returnCodeStr, returnCodes)
+ {
+ if (!returnCodes.empty())
+ return;
+ returnCodes["reject"] = STG_REJECT;
+ returnCodes["fail"] = STG_FAIL;
+ returnCodes["ok"] = STG_OK;
+ returnCodes["handled"] = STG_HANDLED;
+ returnCodes["invalid"] = STG_INVALID;
+ returnCodes["userlock"] = STG_USERLOCK;
+ returnCodes["notfound"] = STG_NOTFOUND;
+ returnCodes["noop"] = STG_NOOP;
+ returnCodes["updated"] = STG_UPDATED;
+ }
+};
+
class TopParser : public NodeParser
{
public:
TopParser(Callback callback, void* data)
: m_packet(PING),
m_result(false),
+ m_returnCode(STG_REJECT),
m_packetParser(this, m_packet, m_packetStr),
m_resultParser(this, m_result, m_resultStr),
+ m_returnCodeParser(this, m_returnCode, m_returnCodeStr),
m_replyParser(this, m_reply),
m_modifyParser(this, m_modify),
m_callback(callback), m_data(data)
return &m_replyParser;
else if (key == "modify")
return &m_modifyParser;
+ else if (key == "return_code")
+ return &m_returnCodeParser;
return this;
}
Packet packet() const { return m_packet; }
const std::string& resultStr() const { return m_resultStr; }
bool result() const { return m_result; }
+ const std::string& returnCodeStr() const { return m_returnCodeStr; }
+ int returnCode() const { return m_returnCode; }
const PairsParser::Pairs& reply() const { return m_reply; }
const PairsParser::Pairs& modify() const { return m_modify; }
Packet m_packet;
std::string m_resultStr;
bool m_result;
+ std::string m_returnCodeStr;
+ int m_returnCode;
PairsParser::Pairs m_reply;
PairsParser::Pairs m_modify;
PacketParser m_packetParser;
ResultParser m_resultParser;
+ ReturnCodeParser m_returnCodeParser;
PairsParser m_replyParser;
PairsParser m_modifyParser;
Packet packet() const { return m_topParser.packet(); }
const std::string& resultStr() const { return m_topParser.resultStr(); }
bool result() const { return m_topParser.result(); }
+ const std::string& returnCodeStr() const { return m_topParser.returnCodeStr(); }
+ int returnCode() const { return m_topParser.returnCode(); }
const PairsParser::Pairs& reply() const { return m_topParser.reply(); }
const PairsParser::Pairs& modify() const { return m_topParser.modify(); }
void runImpl();
+ bool start();
+
int connect();
int connectTCP();
int connectUNIX();
m_parser(&Conn::Impl::process, this),
m_connected(true)
{
- RadLog("Created connection.");
pthread_mutex_init(&m_mutex, NULL);
- int res = pthread_create(&m_thread, NULL, &Conn::Impl::run, this);
- if (res != 0)
- throw Error("Failed to create thread: " + std::string(strerror(errno)));
}
Conn::Impl::~Impl()
shutdown(m_sock, SHUT_RDWR);
close(m_sock);
pthread_mutex_destroy(&m_mutex);
- RadLog("Deleted connection.");
}
bool Conn::Impl::stop()
bool Conn::Impl::request(REQUEST_TYPE type, const std::string& userName, const std::string& password, const PAIRS& pairs)
{
+ if (!m_running)
+ if (!start())
+ return false;
MapGen map;
for (PAIRS::const_iterator it = pairs.begin(); it != pairs.end(); ++it)
map.add(it->first, new StringGen(it->second));
{
m_running = true;
- RadLog("Run connection.");
-
while (m_running) {
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 500000;
- RadLog("Starting 'select'.");
int res = select(m_sock + 1, &fds, NULL, NULL, &tv);
- RadLog("'select' result: %d.", res);
if (res < 0)
{
if (errno == EINTR)
if (res > 0)
{
- RadLog("Got %d fds.", res);
if (FD_ISSET(m_sock, &fds))
m_running = read();
- RadLog("Read complete.");
}
else
m_running = tick();
}
- RadLog("End running connection.");
-
m_connected = false;
m_stopped = true;
}
+bool Conn::Impl::start()
+{
+ int res = pthread_create(&m_thread, NULL, &Conn::Impl::run, this);
+ if (res != 0)
+ return false;
+ return true;
+}
+
int Conn::Impl::connect()
{
if (m_config.transport == "tcp")
void Conn::Impl::processPing()
{
- RadLog("Got ping, sending pong.");
sendPong();
}
void Conn::Impl::processPong()
{
- RadLog("Got pong.");
m_lastActivity = time(NULL);
}
void Conn::Impl::processData()
{
RESULT data;
- RadLog("Got data.");
- for (PairsParser::Pairs::const_iterator it = m_parser.reply().begin(); it != m_parser.reply().end(); ++it)
- data.reply.push_back(std::make_pair(it->first, it->second));
- for (PairsParser::Pairs::const_iterator it = m_parser.modify().begin(); it != m_parser.modify().end(); ++it)
- data.modify.push_back(std::make_pair(it->first, it->second));
- m_callback(m_data, data, m_parser.result());
+ if (m_parser.result())
+ {
+ for (PairsParser::Pairs::const_iterator it = m_parser.reply().begin(); it != m_parser.reply().end(); ++it)
+ data.reply.push_back(std::make_pair(it->first, it->second));
+ for (PairsParser::Pairs::const_iterator it = m_parser.modify().begin(); it != m_parser.modify().end(); ++it)
+ data.modify.push_back(std::make_pair(it->first, it->second));
+ data.returnCode = STG_UPDATED;
+ }
+ else
+ data.returnCode = m_parser.returnCode();
+ m_callback(m_data, data);
}
bool Conn::Impl::sendPing()
bool Conn::Impl::write(void* data, const char* buf, size_t size)
{
- RadLog("Sending JSON:");
std::string json(buf, size);
- RadLog("%s", json.c_str());
+ RadLog("Sending JSON: %s", json.c_str());
Conn::Impl& impl = *static_cast<Conn::Impl*>(data);
while (size > 0)
{
RadLog("Failed to write data: %s.", strerror(errno));
return false;
}
- RadLog("Send %d bytes.", res);
size -= res;
}
return true;