mirror of
https://github.com/GOSTSec/poolserver
synced 2025-02-06 12:04:29 +00:00
Added JSON Library (ALPHA), Added JSONRPC Library (ALPHA), Base64 Encode/Decode
This commit is contained in:
parent
57c65a4ba2
commit
519cfec904
@ -15,6 +15,8 @@ include_directories(
|
|||||||
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
${CMAKE_SOURCE_DIR}/src/server/shared/Configuration
|
||||||
${CMAKE_SOURCE_DIR}/src/server/shared/Database
|
${CMAKE_SOURCE_DIR}/src/server/shared/Database
|
||||||
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
|
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
|
||||||
|
${CMAKE_SOURCE_DIR}/src/server/shared/JSON
|
||||||
|
${CMAKE_SOURCE_DIR}/src/server/shared/JSONRPC
|
||||||
${CMAKE_SOURCE_DIR}/src/server/poolserver/Server
|
${CMAKE_SOURCE_DIR}/src/server/poolserver/Server
|
||||||
${CMAKE_SOURCE_DIR}/src/server/poolserver/Database
|
${CMAKE_SOURCE_DIR}/src/server/poolserver/Database
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
#include "Server.h"
|
#include "Server.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include "JSON.h"
|
||||||
|
#include "JSONRPC.h"
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
bool InitConfig(int argc, char *argv[])
|
bool InitConfig(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -78,7 +83,7 @@ bool InitConfig(int argc, char *argv[])
|
|||||||
|
|
||||||
if (!ifs.is_open()) {
|
if (!ifs.is_open()) {
|
||||||
sLog.Error(LOG_GENERAL, "Failed opening config file: %s", sConfig.Get<std::string>("config").c_str());
|
sLog.Error(LOG_GENERAL, "Failed opening config file: %s", sConfig.Get<std::string>("config").c_str());
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
store(parse_config_file(ifs, fileOptions), sConfig.vm);
|
store(parse_config_file(ifs, fileOptions), sConfig.vm);
|
||||||
|
@ -4,6 +4,8 @@ add_subdirectory(Database)
|
|||||||
file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
|
file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
|
||||||
file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
|
file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
|
||||||
file(GLOB_RECURSE sources_Stratum Stratum/*.cpp Stratum/*.h)
|
file(GLOB_RECURSE sources_Stratum Stratum/*.cpp Stratum/*.h)
|
||||||
|
file(GLOB_RECURSE sources_JSON JSON/*.cpp JSON/*.h)
|
||||||
|
file(GLOB_RECURSE sources_JSONRPC JSONRPC/*.cpp JSONRPC/*.h)
|
||||||
|
|
||||||
file(GLOB sources_localdir *.cpp *.h)
|
file(GLOB sources_localdir *.cpp *.h)
|
||||||
|
|
||||||
@ -12,6 +14,8 @@ set(sources_Shared
|
|||||||
${sources_Database}
|
${sources_Database}
|
||||||
${sources_Logging}
|
${sources_Logging}
|
||||||
${sources_Stratum}
|
${sources_Stratum}
|
||||||
|
${sources_JSON}
|
||||||
|
${sources_JSONRPC}
|
||||||
${sources_localdir}
|
${sources_localdir}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,6 +24,8 @@ include_directories(
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/Configuration
|
${CMAKE_CURRENT_SOURCE_DIR}/Configuration
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Database
|
${CMAKE_CURRENT_SOURCE_DIR}/Database
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/Logging
|
${CMAKE_CURRENT_SOURCE_DIR}/Logging
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/JSON
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/JSONRPC
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
${MYSQL_INCLUDE_DIR}
|
${MYSQL_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
22
src/server/shared/JSON/JSON.cpp
Normal file
22
src/server/shared/JSON/JSON.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "JSON.h"
|
||||||
|
#include <sstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
JSON JSON::FromString(std::string jsonstring)
|
||||||
|
{
|
||||||
|
JSON json;
|
||||||
|
json.pt = new boost::property_tree::ptree();
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.str(jsonstring);
|
||||||
|
boost::property_tree::json_parser::read_json(ss, *json.pt);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string JSON::ToString()
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
boost::property_tree::json_parser::write_json(ss, *pt);
|
||||||
|
return ss.str();
|
||||||
|
}
|
80
src/server/shared/JSON/JSON.h
Normal file
80
src/server/shared/JSON/JSON.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef JSON_H_
|
||||||
|
#define JSON_H_
|
||||||
|
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
class JSON
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static JSON FromString(std::string jsonstring);
|
||||||
|
|
||||||
|
JSON(bool base = true) : _base(base), pt(NULL)
|
||||||
|
{
|
||||||
|
if (base)
|
||||||
|
pt = new boost::property_tree::ptree();
|
||||||
|
}
|
||||||
|
|
||||||
|
~JSON()
|
||||||
|
{
|
||||||
|
//if (_base && pt)
|
||||||
|
// delete pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
T Get(std::string key)
|
||||||
|
{
|
||||||
|
return pt->get<T>(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON operator[] (std::string key)
|
||||||
|
{
|
||||||
|
JSON json(false);
|
||||||
|
json.pt = &pt->get_child(key);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON operator[] (int index)
|
||||||
|
{
|
||||||
|
JSON json(false);
|
||||||
|
boost::property_tree::ptree::iterator it = pt->begin();
|
||||||
|
for (int i = 0; i < index; ++i)
|
||||||
|
++it;
|
||||||
|
boost::property_tree::ptree::value_type& kv = *it;
|
||||||
|
json.pt = &kv.second;
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void Set(std::string key, T value)
|
||||||
|
{
|
||||||
|
pt->put<T>(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void Add(T value)
|
||||||
|
{
|
||||||
|
pt->push_back(std::make_pair("", value));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Size()
|
||||||
|
{
|
||||||
|
return pt->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString();
|
||||||
|
|
||||||
|
boost::property_tree::ptree* pt;
|
||||||
|
bool _base;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
inline void JSON::Set<JSON>(std::string key, JSON value)
|
||||||
|
{
|
||||||
|
pt->put_child(key, *value.pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
127
src/server/shared/JSONRPC/JSONRPC.cpp
Normal file
127
src/server/shared/JSONRPC/JSONRPC.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include "JSONRPC.h"
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <boost/exception/all.hpp>
|
||||||
|
#include "Util.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
bool JSONRPC::Connect(JSONRPCConnectionInfo connInfo)
|
||||||
|
{
|
||||||
|
_connInfo = connInfo;
|
||||||
|
|
||||||
|
if (_connInfo.B64Auth.empty())
|
||||||
|
_connInfo.B64Auth = Util::ToBase64(_connInfo.User + ":" + _connInfo.Pass, false);
|
||||||
|
|
||||||
|
sLog.Debug(LOG_JSONRPC, "JSONRPC::Connect(): B64Auth: %s", _connInfo.B64Auth.c_str());
|
||||||
|
|
||||||
|
boost::asio::ip::tcp::resolver resolver(_ios);
|
||||||
|
boost::asio::ip::tcp::resolver::query q(_connInfo.Host, _connInfo.Port);
|
||||||
|
boost::asio::ip::tcp::resolver::iterator epi = resolver.resolve(q);
|
||||||
|
boost::asio::ip::tcp::resolver::iterator end;
|
||||||
|
|
||||||
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
|
|
||||||
|
while (error && epi != end)
|
||||||
|
{
|
||||||
|
_sock.close();
|
||||||
|
_sock.connect(*epi, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
sLog.Error(LOG_JSONRPC, "JSONRPC::Connect(): Error connecting to '%s': %s", _connInfo.Host.c_str(), boost::system::system_error(error).what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ep = *epi;
|
||||||
|
|
||||||
|
_sock.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON JSONRPC::Query(std::string method, JSON params)
|
||||||
|
{
|
||||||
|
JSON request(true);
|
||||||
|
request.Set("jsonrpc", "1.0");
|
||||||
|
request.Set("id", 1);
|
||||||
|
request.Set("method", method);
|
||||||
|
if (params.Size() > 0)
|
||||||
|
request.Set("params", params);
|
||||||
|
std::string jsonstring = request.ToString();
|
||||||
|
|
||||||
|
sLog.Debug(LOG_JSONRPC, "JSONRPC::Query(): JSONString: %s", jsonstring.c_str());
|
||||||
|
|
||||||
|
boost::system::error_code error;
|
||||||
|
|
||||||
|
_sock.close();
|
||||||
|
_sock.connect(_ep, error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Error connecting to '%s': %s", _connInfo.Host.c_str(), boost::system::system_error(error).what());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::streambuf request_buf;
|
||||||
|
std::ostream request_info(&request_buf);
|
||||||
|
request_info << "POST / HTTP/1.1\n";
|
||||||
|
request_info << "Host: 127.0.0.1\n";
|
||||||
|
request_info << "Content-Type: application/json-rpc\n";
|
||||||
|
request_info << "Authorization: Basic " << _connInfo.B64Auth << "\n";
|
||||||
|
request_info << "Content-Length: " << jsonstring.size() << "\n\n";
|
||||||
|
request_info << jsonstring;
|
||||||
|
|
||||||
|
boost::asio::write(_sock, request_buf);
|
||||||
|
|
||||||
|
boost::asio::streambuf response;
|
||||||
|
boost::asio::read_until(_sock, response, "\n");
|
||||||
|
|
||||||
|
std::istream response_stream(&response);
|
||||||
|
|
||||||
|
std::string http_version;
|
||||||
|
uint32_t status_code;
|
||||||
|
std::string status_message;
|
||||||
|
|
||||||
|
response_stream >> http_version >> status_code;
|
||||||
|
std::getline(response_stream, status_message);
|
||||||
|
|
||||||
|
|
||||||
|
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
|
||||||
|
{
|
||||||
|
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Malformed HTTP Response");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status_code != 200)
|
||||||
|
{
|
||||||
|
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Returned status code: %u", status_code);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> headers;
|
||||||
|
std::string header;
|
||||||
|
while (std::getline(response_stream, header) && header != "\r")
|
||||||
|
headers.push_back(header);
|
||||||
|
|
||||||
|
std::string jsonresponse = "";
|
||||||
|
|
||||||
|
if (response.size() > 0) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << &response;
|
||||||
|
jsonresponse += oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read until EOF, writing data to output as we go.
|
||||||
|
while(boost::asio::read(_sock, response, boost::asio::transfer_at_least(1), error)){
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << &response;
|
||||||
|
jsonresponse += oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
_sock.close();
|
||||||
|
|
||||||
|
sLog.Debug(LOG_JSONRPC, "JSONRPC::Query(): JSON Response: %s", jsonresponse.c_str());
|
||||||
|
|
||||||
|
return JSON::FromString(jsonresponse);
|
||||||
|
}
|
34
src/server/shared/JSONRPC/JSONRPC.h
Normal file
34
src/server/shared/JSONRPC/JSONRPC.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef JSONRPC_H_
|
||||||
|
#define JSONRPC_H_
|
||||||
|
|
||||||
|
// Some of the JSON RPC code was written by https://github.com/bytemaster/cpp_bitcoin_rpc
|
||||||
|
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include "JSON.h"
|
||||||
|
|
||||||
|
struct JSONRPCConnectionInfo
|
||||||
|
{
|
||||||
|
std::string Host;
|
||||||
|
std::string Port;
|
||||||
|
std::string User;
|
||||||
|
std::string Pass;
|
||||||
|
std::string B64Auth;
|
||||||
|
};
|
||||||
|
|
||||||
|
class JSONRPC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JSONRPC(): _sock(_ios) {}
|
||||||
|
bool Connect(JSONRPCConnectionInfo conninfo);
|
||||||
|
JSON Query(std::string method, JSON params = JSON::FromString("[]"));
|
||||||
|
|
||||||
|
private:
|
||||||
|
JSONRPCConnectionInfo _connInfo;
|
||||||
|
boost::asio::io_service _ios;
|
||||||
|
boost::asio::ip::tcp::socket _sock;
|
||||||
|
boost::asio::ip::tcp::endpoint _ep;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -16,7 +16,9 @@ enum LogType
|
|||||||
{
|
{
|
||||||
LOG_GENERAL = 0,
|
LOG_GENERAL = 0,
|
||||||
LOG_SERVER = 1,
|
LOG_SERVER = 1,
|
||||||
LOG_DATABASE = 2
|
LOG_DATABASE = 2,
|
||||||
|
LOG_JSON = 3,
|
||||||
|
LOG_JSONRPC = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LogLevel
|
enum LogLevel
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
std::string Util::Date(const char* format, bool utc)
|
std::string Util::Date(const char* format, bool utc)
|
||||||
{
|
{
|
||||||
boost::posix_time::ptime now;
|
boost::posix_time::ptime now;
|
||||||
@ -15,3 +17,28 @@ std::string Util::Date(const char* format, bool utc)
|
|||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Util::ToBase64(std::string input, bool linebreaks)
|
||||||
|
{
|
||||||
|
uint32_t writePaddChars = (3 - input.length() % 3) % 3;
|
||||||
|
|
||||||
|
if (linebreaks) {
|
||||||
|
std::string base64(it_base64_lb_t(input.begin()), it_base64_lb_t(input.end()));
|
||||||
|
base64.append(writePaddChars, '=');
|
||||||
|
return base64;
|
||||||
|
} else {
|
||||||
|
std::string base64(it_base64_t(input.begin()), it_base64_t(input.end()));
|
||||||
|
base64.append(writePaddChars, '=');
|
||||||
|
return base64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Util::FromBase64(std::string input)
|
||||||
|
{
|
||||||
|
boost::algorithm::trim(input);
|
||||||
|
uint32_t paddChars = count(input.begin(), input.end(), '=');
|
||||||
|
std::replace(input.begin(), input.end(), '=', 'A'); // replace '=' by base64 encoding of '\0'
|
||||||
|
std::string result(it_binary_t(input.begin()), it_binary_t(input.end())); // decode
|
||||||
|
result.erase(result.end() - paddChars, result.end()); // erase padding '\0' characters
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -4,9 +4,15 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <string>
|
||||||
#include <boost/date_time.hpp>
|
#include <boost/date_time.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/archive/iterators/base64_from_binary.hpp>
|
||||||
|
#include <boost/archive/iterators/binary_from_base64.hpp>
|
||||||
|
#include <boost/archive/iterators/transform_width.hpp>
|
||||||
|
#include <boost/archive/iterators/insert_linebreaks.hpp>
|
||||||
|
#include <boost/archive/iterators/remove_whitespace.hpp>
|
||||||
|
|
||||||
namespace Util
|
namespace Util
|
||||||
{
|
{
|
||||||
@ -73,6 +79,29 @@ namespace Util
|
|||||||
virtual void Work() = 0;
|
virtual void Work() = 0;
|
||||||
boost::thread* _thread;
|
boost::thread* _thread;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Base64 encode/decode functions by http://stackoverflow.com/users/1132850/piquer
|
||||||
|
|
||||||
|
typedef boost::archive::iterators::insert_linebreaks
|
||||||
|
<
|
||||||
|
boost::archive::iterators::base64_from_binary
|
||||||
|
<
|
||||||
|
boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8>
|
||||||
|
>, 72
|
||||||
|
> it_base64_lb_t;
|
||||||
|
|
||||||
|
typedef boost::archive::iterators::base64_from_binary
|
||||||
|
<
|
||||||
|
boost::archive::iterators::transform_width<std::string::const_iterator, 6, 8>
|
||||||
|
> it_base64_t;
|
||||||
|
|
||||||
|
typedef boost::archive::iterators::transform_width
|
||||||
|
<
|
||||||
|
boost::archive::iterators::binary_from_base64<std::string::const_iterator>, 8, 6
|
||||||
|
> it_binary_t;
|
||||||
|
|
||||||
|
std::string ToBase64(std::string input, bool linebreaks = true);
|
||||||
|
std::string FromBase64(std::string input);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user