it complies and crow updated
This commit is contained in:
parent
9b3a27baa9
commit
f9925d6c3b
|
@ -31,11 +31,11 @@ find_package(Boost COMPONENTS
|
|||
|
||||
# set location of monero static libraries
|
||||
set(MONERO_LIBS_DIR
|
||||
/opt/bitmonero-dev/libs)
|
||||
/opt/monero-dev/libs)
|
||||
|
||||
# set location of moneroheaders
|
||||
set(MONERO_HEADERS_DIR
|
||||
/opt/bitmonero-dev/headers)
|
||||
/opt/monero-dev/headers)
|
||||
|
||||
# include monero headers
|
||||
include_directories(
|
||||
|
@ -50,21 +50,17 @@ include_directories(
|
|||
add_library(common STATIC IMPORTED)
|
||||
set_property(TARGET common PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libcommon.a)
|
||||
|
||||
|
||||
add_library(blocks STATIC IMPORTED)
|
||||
set_property(TARGET blocks PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libblocks.a)
|
||||
|
||||
|
||||
add_library(crypto STATIC IMPORTED)
|
||||
set_property(TARGET crypto
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libcrypto.a)
|
||||
|
||||
|
||||
add_library(cryptonote_core STATIC IMPORTED)
|
||||
set_property(TARGET cryptonote_core
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libcryptonote_core.a)
|
||||
|
||||
|
||||
add_library(blockchain_db STATIC IMPORTED)
|
||||
set_property(TARGET blockchain_db
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libblockchain_db.a)
|
||||
|
@ -73,6 +69,9 @@ add_library(lmdb STATIC IMPORTED)
|
|||
set_property(TARGET lmdb
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/liblmdb.a)
|
||||
|
||||
add_library(ringct STATIC IMPORTED)
|
||||
set_property(TARGET ringct
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_LIBS_DIR}/libringct.a)
|
||||
|
||||
# include boost headers
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
@ -125,6 +124,7 @@ target_link_libraries(${PROJECT_NAME}
|
|||
blocks
|
||||
common
|
||||
lmdb
|
||||
ringct
|
||||
${Boost_LIBRARIES}
|
||||
pthread
|
||||
unbound
|
||||
|
|
|
@ -10,7 +10,8 @@ namespace crow
|
|||
{
|
||||
enum class HTTPMethod
|
||||
{
|
||||
DELETE,
|
||||
#ifndef DELETE
|
||||
DELETE = 0,
|
||||
GET,
|
||||
HEAD,
|
||||
POST,
|
||||
|
@ -18,27 +19,37 @@ namespace crow
|
|||
CONNECT,
|
||||
OPTIONS,
|
||||
TRACE,
|
||||
#endif
|
||||
|
||||
Delete = 0,
|
||||
Get,
|
||||
Head,
|
||||
Post,
|
||||
Put,
|
||||
Connect,
|
||||
Options,
|
||||
Trace,
|
||||
};
|
||||
|
||||
inline std::string method_name(HTTPMethod method)
|
||||
{
|
||||
switch(method)
|
||||
{
|
||||
case HTTPMethod::DELETE:
|
||||
case HTTPMethod::Delete:
|
||||
return "DELETE";
|
||||
case HTTPMethod::GET:
|
||||
case HTTPMethod::Get:
|
||||
return "GET";
|
||||
case HTTPMethod::HEAD:
|
||||
case HTTPMethod::Head:
|
||||
return "HEAD";
|
||||
case HTTPMethod::POST:
|
||||
case HTTPMethod::Post:
|
||||
return "POST";
|
||||
case HTTPMethod::PUT:
|
||||
case HTTPMethod::Put:
|
||||
return "PUT";
|
||||
case HTTPMethod::CONNECT:
|
||||
case HTTPMethod::Connect:
|
||||
return "CONNECT";
|
||||
case HTTPMethod::OPTIONS:
|
||||
case HTTPMethod::Options:
|
||||
return "OPTIONS";
|
||||
case HTTPMethod::TRACE:
|
||||
case HTTPMethod::Trace:
|
||||
return "TRACE";
|
||||
}
|
||||
return "invalid";
|
||||
|
@ -110,17 +121,17 @@ namespace crow
|
|||
}
|
||||
|
||||
#ifndef CROW_MSVC_WORKAROUND
|
||||
constexpr crow::HTTPMethod operator "" _method(const char* str, size_t len)
|
||||
constexpr crow::HTTPMethod operator "" _method(const char* str, size_t /*len*/)
|
||||
{
|
||||
return
|
||||
crow::black_magic::is_equ_p(str, "GET", 3) ? crow::HTTPMethod::GET :
|
||||
crow::black_magic::is_equ_p(str, "DELETE", 6) ? crow::HTTPMethod::DELETE :
|
||||
crow::black_magic::is_equ_p(str, "HEAD", 4) ? crow::HTTPMethod::HEAD :
|
||||
crow::black_magic::is_equ_p(str, "POST", 4) ? crow::HTTPMethod::POST :
|
||||
crow::black_magic::is_equ_p(str, "PUT", 3) ? crow::HTTPMethod::PUT :
|
||||
crow::black_magic::is_equ_p(str, "OPTIONS", 7) ? crow::HTTPMethod::OPTIONS :
|
||||
crow::black_magic::is_equ_p(str, "CONNECT", 7) ? crow::HTTPMethod::CONNECT :
|
||||
crow::black_magic::is_equ_p(str, "TRACE", 5) ? crow::HTTPMethod::TRACE :
|
||||
crow::black_magic::is_equ_p(str, "GET", 3) ? crow::HTTPMethod::Get :
|
||||
crow::black_magic::is_equ_p(str, "DELETE", 6) ? crow::HTTPMethod::Delete :
|
||||
crow::black_magic::is_equ_p(str, "HEAD", 4) ? crow::HTTPMethod::Head :
|
||||
crow::black_magic::is_equ_p(str, "POST", 4) ? crow::HTTPMethod::Post :
|
||||
crow::black_magic::is_equ_p(str, "PUT", 3) ? crow::HTTPMethod::Put :
|
||||
crow::black_magic::is_equ_p(str, "OPTIONS", 7) ? crow::HTTPMethod::Options :
|
||||
crow::black_magic::is_equ_p(str, "CONNECT", 7) ? crow::HTTPMethod::Connect :
|
||||
crow::black_magic::is_equ_p(str, "TRACE", 5) ? crow::HTTPMethod::Trace :
|
||||
throw std::runtime_error("invalid http method");
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <thread>
|
||||
|
||||
#include "settings.h"
|
||||
#include "logging.h"
|
||||
#include "logging.h"
|
||||
#include "utility.h"
|
||||
#include "routing.h"
|
||||
#include "middleware_context.h"
|
||||
|
@ -41,6 +41,12 @@ namespace crow
|
|||
{
|
||||
}
|
||||
|
||||
template <typename Adaptor>
|
||||
void handle_upgrade(const request& req, response& res, Adaptor&& adaptor)
|
||||
{
|
||||
router_.handle_upgrade(req, res, adaptor);
|
||||
}
|
||||
|
||||
void handle(const request& req, response& res)
|
||||
{
|
||||
router_.handle(req, res);
|
||||
|
@ -64,6 +70,12 @@ namespace crow
|
|||
return *this;
|
||||
}
|
||||
|
||||
self_t& bindaddr(std::string bindaddr)
|
||||
{
|
||||
bindaddr_ = bindaddr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
self_t& multithreaded()
|
||||
{
|
||||
return concurrency(std::thread::hardware_concurrency());
|
||||
|
@ -88,14 +100,28 @@ namespace crow
|
|||
#ifdef CROW_ENABLE_SSL
|
||||
if (use_ssl_)
|
||||
{
|
||||
ssl_server_t server(this, port_, &middlewares_, concurrency_, &ssl_context_);
|
||||
server.run();
|
||||
ssl_server_ = std::move(std::unique_ptr<ssl_server_t>(new ssl_server_t(this, bindaddr_, port_, &middlewares_, concurrency_, &ssl_context_)));
|
||||
ssl_server_->run();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
server_t server(this, port_, &middlewares_, concurrency_, nullptr);
|
||||
server.run();
|
||||
server_ = std::move(std::unique_ptr<server_t>(new server_t(this, bindaddr_, port_, &middlewares_, concurrency_, nullptr)));
|
||||
server_->run();
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
if (use_ssl_)
|
||||
{
|
||||
ssl_server_->stop();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
server_->stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,23 +172,23 @@ namespace crow
|
|||
|
||||
#else
|
||||
template <typename T, typename ... Remain>
|
||||
self_t& ssl_file(T&& t, Remain&&...)
|
||||
self_t& ssl_file(T&&, Remain&&...)
|
||||
{
|
||||
// We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
|
||||
static_assert(
|
||||
// make static_assert dependent to T; always false
|
||||
std::is_base_of<T, void>::value,
|
||||
std::is_base_of<T, void>::value,
|
||||
"Define CROW_ENABLE_SSL to enable ssl support.");
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
self_t& ssl(T&& ctx)
|
||||
self_t& ssl(T&&)
|
||||
{
|
||||
// We can't call .ssl() member function unless CROW_ENABLE_SSL is defined.
|
||||
static_assert(
|
||||
// make static_assert dependent to T; always false
|
||||
std::is_base_of<T, void>::value,
|
||||
std::is_base_of<T, void>::value,
|
||||
"Define CROW_ENABLE_SSL to enable ssl support.");
|
||||
return *this;
|
||||
}
|
||||
|
@ -187,13 +213,17 @@ namespace crow
|
|||
private:
|
||||
uint16_t port_ = 80;
|
||||
uint16_t concurrency_ = 1;
|
||||
|
||||
std::string bindaddr_ = "0.0.0.0";
|
||||
Router router_;
|
||||
|
||||
std::tuple<Middlewares...> middlewares_;
|
||||
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
std::unique_ptr<ssl_server_t> ssl_server_;
|
||||
#endif
|
||||
std::unique_ptr<server_t> server_;
|
||||
};
|
||||
template <typename ... Middlewares>
|
||||
using App = Crow<Middlewares...>;
|
||||
using SimpleApp = Crow<>;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -98,28 +98,28 @@ namespace crow
|
|||
|
||||
template <typename MW, typename Context, typename ParentContext>
|
||||
typename std::enable_if<!is_before_handle_arity_3_impl<MW>::value>::type
|
||||
before_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& parent_ctx)
|
||||
before_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& /*parent_ctx*/)
|
||||
{
|
||||
mw.before_handle(req, res, ctx.template get<MW>(), ctx);
|
||||
}
|
||||
|
||||
template <typename MW, typename Context, typename ParentContext>
|
||||
typename std::enable_if<is_before_handle_arity_3_impl<MW>::value>::type
|
||||
before_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& parent_ctx)
|
||||
before_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& /*parent_ctx*/)
|
||||
{
|
||||
mw.before_handle(req, res, ctx.template get<MW>());
|
||||
}
|
||||
|
||||
template <typename MW, typename Context, typename ParentContext>
|
||||
typename std::enable_if<!is_after_handle_arity_3_impl<MW>::value>::type
|
||||
after_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& parent_ctx)
|
||||
after_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& /*parent_ctx*/)
|
||||
{
|
||||
mw.after_handle(req, res, ctx.template get<MW>(), ctx);
|
||||
}
|
||||
|
||||
template <typename MW, typename Context, typename ParentContext>
|
||||
typename std::enable_if<is_after_handle_arity_3_impl<MW>::value>::type
|
||||
after_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& parent_ctx)
|
||||
after_handler_call(MW& mw, request& req, response& res, Context& ctx, ParentContext& /*parent_ctx*/)
|
||||
{
|
||||
mw.after_handle(req, res, ctx.template get<MW>());
|
||||
}
|
||||
|
@ -146,14 +146,14 @@ namespace crow
|
|||
}
|
||||
|
||||
template <int N, typename Context, typename Container>
|
||||
bool middleware_call_helper(Container& middlewares, request& req, response& res, Context& ctx)
|
||||
bool middleware_call_helper(Container& /*middlewares*/, request& /*req*/, response& /*res*/, Context& /*ctx*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <int N, typename Context, typename Container>
|
||||
typename std::enable_if<(N<0)>::type
|
||||
after_handlers_call_helper(Container& middlewares, Context& context, request& req, response& res)
|
||||
after_handlers_call_helper(Container& /*middlewares*/, Context& /*context*/, request& /*req*/, response& /*res*/)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -256,6 +256,7 @@ namespace crow
|
|||
|
||||
req_ = std::move(parser_.to_request());
|
||||
request& req = req_;
|
||||
|
||||
if (parser_.check_version(1, 0))
|
||||
{
|
||||
// HTTP/1.0
|
||||
|
@ -282,6 +283,20 @@ namespace crow
|
|||
is_invalid_request = true;
|
||||
res = response(400);
|
||||
}
|
||||
if (parser_.is_upgrade())
|
||||
{
|
||||
if (req.get_header_value("upgrade") == "h2c")
|
||||
{
|
||||
// TODO HTTP/2
|
||||
// currently, ignore upgrade header
|
||||
}
|
||||
else
|
||||
{
|
||||
close_connection_ = true;
|
||||
handler_->handle_upgrade(req, res, std::move(adaptor_));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CROW_LOG_INFO << "Request: " << boost::lexical_cast<std::string>(adaptor_.remote_endpoint()) << " " << this << " HTTP/" << parser_.http_major << "." << parser_.http_minor << ' '
|
||||
|
@ -296,6 +311,7 @@ namespace crow
|
|||
|
||||
ctx_ = detail::context<Middlewares...>();
|
||||
req.middleware_context = (void*)&ctx_;
|
||||
req.io_service = &adaptor_.get_io_service();
|
||||
detail::middleware_call_helper<0, decltype(ctx_), decltype(*middlewares_), Middlewares...>(*middlewares_, req, res, ctx_);
|
||||
|
||||
if (!res.completed_)
|
||||
|
@ -484,7 +500,7 @@ namespace crow
|
|||
//auto self = this->shared_from_this();
|
||||
is_writing = true;
|
||||
boost::asio::async_write(adaptor_.socket(), buffers_,
|
||||
[&](const boost::system::error_code& ec, std::size_t bytes_transferred)
|
||||
[&](const boost::system::error_code& ec, std::size_t /*bytes_transferred*/)
|
||||
{
|
||||
is_writing = false;
|
||||
res.clear();
|
||||
|
@ -522,7 +538,7 @@ namespace crow
|
|||
timer_queue.cancel(timer_cancel_key_);
|
||||
}
|
||||
|
||||
void start_deadline(int timeout = 5)
|
||||
void start_deadline(/*int timeout = 5*/)
|
||||
{
|
||||
cancel_deadline_timer();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,7 @@
|
|||
#include "common.h"
|
||||
#include "ci_map.h"
|
||||
#include "query_string.h"
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace crow
|
||||
{
|
||||
|
@ -17,6 +18,8 @@ namespace crow
|
|||
return empty;
|
||||
}
|
||||
|
||||
struct DetachHelper;
|
||||
|
||||
struct request
|
||||
{
|
||||
HTTPMethod method;
|
||||
|
@ -27,9 +30,10 @@ namespace crow
|
|||
std::string body;
|
||||
|
||||
void* middleware_context{};
|
||||
boost::asio::io_service* io_service{};
|
||||
|
||||
request()
|
||||
: method(HTTPMethod::GET)
|
||||
: method(HTTPMethod::Get)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,5 +52,17 @@ namespace crow
|
|||
return crow::get_header_value(headers, key);
|
||||
}
|
||||
|
||||
template<typename CompletionHandler>
|
||||
void post(CompletionHandler handler)
|
||||
{
|
||||
io_service->post(handler);
|
||||
}
|
||||
|
||||
template<typename CompletionHandler>
|
||||
void dispatch(CompletionHandler handler)
|
||||
{
|
||||
io_service->dispatch(handler);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ namespace crow
|
|||
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
||||
friend class crow::Connection;
|
||||
|
||||
int code{200};
|
||||
std::string body;
|
||||
json::wvalue json_value;
|
||||
int code{200};
|
||||
|
||||
// `headers' stores HTTP headers.
|
||||
ci_map headers;
|
||||
|
@ -40,12 +40,12 @@ namespace crow
|
|||
response() {}
|
||||
explicit response(int code) : code(code) {}
|
||||
response(std::string body) : body(std::move(body)) {}
|
||||
response(json::wvalue&& json_value) : json_value(std::move(json_value))
|
||||
response(json::wvalue&& json_value) : json_value(std::move(json_value))
|
||||
{
|
||||
json_mode();
|
||||
json_mode();
|
||||
}
|
||||
response(int code, std::string body) : body(std::move(body)), code(code) {}
|
||||
response(const json::wvalue& json_value) : body(json::dump(json_value))
|
||||
response(int code, std::string body) : code(code), body(std::move(body)) {}
|
||||
response(const json::wvalue& json_value) : body(json::dump(json_value))
|
||||
{
|
||||
json_mode();
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ namespace crow
|
|||
if (!completed_)
|
||||
{
|
||||
completed_ = true;
|
||||
|
||||
|
||||
if (complete_request_handler_)
|
||||
{
|
||||
complete_request_handler_();
|
||||
|
@ -118,7 +118,7 @@ namespace crow
|
|||
bool completed_{};
|
||||
std::function<void()> complete_request_handler_;
|
||||
std::function<bool()> is_alive_helper_;
|
||||
|
||||
|
||||
//In case of a JSON object, set the Content-Type header
|
||||
void json_mode()
|
||||
{
|
||||
|
|
|
@ -20,17 +20,18 @@ namespace crow
|
|||
{
|
||||
using namespace boost;
|
||||
using tcp = asio::ip::tcp;
|
||||
|
||||
|
||||
template <typename Handler, typename Adaptor = SocketAdaptor, typename ... Middlewares>
|
||||
class Server
|
||||
{
|
||||
public:
|
||||
Server(Handler* handler, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
|
||||
: acceptor_(io_service_, tcp::endpoint(asio::ip::address(), port)),
|
||||
Server(Handler* handler, std::string bindaddr, uint16_t port, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, typename Adaptor::context* adaptor_ctx = nullptr)
|
||||
: acceptor_(io_service_, tcp::endpoint(boost::asio::ip::address::from_string(bindaddr), port)),
|
||||
signals_(io_service_, SIGINT, SIGTERM),
|
||||
handler_(handler),
|
||||
handler_(handler),
|
||||
concurrency_(concurrency),
|
||||
port_(port),
|
||||
bindaddr_(bindaddr),
|
||||
middlewares_(middlewares),
|
||||
adaptor_ctx_(adaptor_ctx)
|
||||
{
|
||||
|
@ -47,9 +48,10 @@ namespace crow
|
|||
timer_queue_pool_.resize(concurrency_);
|
||||
|
||||
std::vector<std::future<void>> v;
|
||||
std::atomic<int> init_count(0);
|
||||
for(uint16_t i = 0; i < concurrency_; i ++)
|
||||
v.push_back(
|
||||
std::async(std::launch::async, [this, i]{
|
||||
std::async(std::launch::async, [this, i, &init_count]{
|
||||
|
||||
// thread local date string get function
|
||||
auto last = std::chrono::steady_clock::now();
|
||||
|
@ -98,20 +100,24 @@ namespace crow
|
|||
};
|
||||
timer.async_wait(handler);
|
||||
|
||||
io_service_pool_[i]->run();
|
||||
init_count ++;
|
||||
try
|
||||
{
|
||||
io_service_pool_[i]->run();
|
||||
} catch(std::exception& e)
|
||||
{
|
||||
CROW_LOG_ERROR << "Worker Crash: An uncaught exception occurred: " << e.what();
|
||||
}
|
||||
}));
|
||||
CROW_LOG_INFO << server_name_ << " server is running, local port " << port_;
|
||||
|
||||
signals_.async_wait(
|
||||
[&](const boost::system::error_code& error, int signal_number){
|
||||
[&](const boost::system::error_code& /*error*/, int /*signal_number*/){
|
||||
stop();
|
||||
});
|
||||
|
||||
for (int i = 0; i < concurrency_; i++)
|
||||
{
|
||||
while (timer_queue_pool_[i] == nullptr)
|
||||
std::this_thread::yield();
|
||||
}
|
||||
while(concurrency_ != init_count)
|
||||
std::this_thread::yield();
|
||||
|
||||
do_accept();
|
||||
|
||||
|
@ -145,7 +151,7 @@ namespace crow
|
|||
is, handler_, server_name_, middlewares_,
|
||||
get_cached_date_str_pool_[roundrobin_index_], *timer_queue_pool_[roundrobin_index_],
|
||||
adaptor_ctx_);
|
||||
acceptor_.async_accept(p->socket(),
|
||||
acceptor_.async_accept(p->socket(),
|
||||
[this, p, &is](boost::system::error_code ec)
|
||||
{
|
||||
if (!ec)
|
||||
|
@ -171,6 +177,7 @@ namespace crow
|
|||
uint16_t concurrency_{1};
|
||||
std::string server_name_ = "Crow/0.1";
|
||||
uint16_t port_;
|
||||
std::string bindaddr_;
|
||||
unsigned int roundrobin_index_{};
|
||||
|
||||
std::tuple<Middlewares...>* middlewares_;
|
||||
|
|
|
@ -82,7 +82,7 @@ namespace crow
|
|||
Object,
|
||||
};
|
||||
|
||||
const char* get_type_str(type t) {
|
||||
inline const char* get_type_str(type t) {
|
||||
switch(t){
|
||||
case type::Number: return "Number";
|
||||
case type::False: return "False";
|
||||
|
@ -92,7 +92,7 @@ namespace crow
|
|||
case type::Object: return "Object";
|
||||
default: return "Unknown";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class rvalue;
|
||||
rvalue load(const char* data, size_t size);
|
||||
|
@ -131,6 +131,8 @@ namespace crow
|
|||
s_ = r.s_;
|
||||
e_ = r.e_;
|
||||
owned_ = r.owned_;
|
||||
if (r.owned_)
|
||||
r.owned_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -164,7 +166,7 @@ namespace crow
|
|||
return os;
|
||||
}
|
||||
private:
|
||||
void force(char* s, uint32_t length)
|
||||
void force(char* s, uint32_t /*length*/)
|
||||
{
|
||||
s_ = s;
|
||||
owned_ = 1;
|
||||
|
@ -262,6 +264,11 @@ namespace crow
|
|||
return i();
|
||||
}
|
||||
|
||||
explicit operator uint64_t() const
|
||||
{
|
||||
return u();
|
||||
}
|
||||
|
||||
explicit operator int() const
|
||||
{
|
||||
return (int)i();
|
||||
|
@ -286,14 +293,28 @@ namespace crow
|
|||
case type::String:
|
||||
return boost::lexical_cast<int64_t>(start_, end_-start_);
|
||||
default:
|
||||
throw std::runtime_error(
|
||||
"expected number, got: " + std::string(get_type_str(t()))
|
||||
);
|
||||
const std::string msg = "expected number, got: "
|
||||
+ std::string(get_type_str(t()));
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
#endif
|
||||
return boost::lexical_cast<int64_t>(start_, end_-start_);
|
||||
}
|
||||
|
||||
uint64_t u() const
|
||||
{
|
||||
#ifndef CROW_JSON_NO_ERROR_CHECK
|
||||
switch (t()) {
|
||||
case type::Number:
|
||||
case type::String:
|
||||
return boost::lexical_cast<uint64_t>(start_, end_-start_);
|
||||
default:
|
||||
throw std::runtime_error(std::string("expected number, got: ") + get_type_str(t()));
|
||||
}
|
||||
#endif
|
||||
return boost::lexical_cast<uint64_t>(start_, end_-start_);
|
||||
}
|
||||
|
||||
double d() const
|
||||
{
|
||||
#ifndef CROW_JSON_NO_ERROR_CHECK
|
||||
|
@ -671,7 +692,7 @@ namespace crow
|
|||
//static const char* escaped = "\"\\/\b\f\n\r\t";
|
||||
struct Parser
|
||||
{
|
||||
Parser(char* data, size_t size)
|
||||
Parser(char* data, size_t /*size*/)
|
||||
: data(data)
|
||||
{
|
||||
}
|
||||
|
@ -1093,17 +1114,16 @@ namespace crow
|
|||
s = r.s();
|
||||
return;
|
||||
case type::List:
|
||||
l = std::move(std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{}));
|
||||
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||
l->reserve(r.size());
|
||||
for(auto it = r.begin(); it != r.end(); ++it)
|
||||
l->emplace_back(*it);
|
||||
return;
|
||||
case type::Object:
|
||||
o = std::move(
|
||||
std::unique_ptr<
|
||||
o = std::unique_ptr<
|
||||
std::unordered_map<std::string, wvalue>
|
||||
>(
|
||||
new std::unordered_map<std::string, wvalue>{}));
|
||||
new std::unordered_map<std::string, wvalue>{});
|
||||
for(auto it = r.begin(); it != r.end(); ++it)
|
||||
o->emplace(it->key(), *it);
|
||||
return;
|
||||
|
@ -1249,7 +1269,7 @@ namespace crow
|
|||
reset();
|
||||
t_ = type::List;
|
||||
if (!l)
|
||||
l = std::move(std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{}));
|
||||
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||
l->clear();
|
||||
l->resize(v.size());
|
||||
size_t idx = 0;
|
||||
|
@ -1266,7 +1286,7 @@ namespace crow
|
|||
reset();
|
||||
t_ = type::List;
|
||||
if (!l)
|
||||
l = std::move(std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{}));
|
||||
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
|
||||
if (l->size() < index+1)
|
||||
l->resize(index+1);
|
||||
return (*l)[index];
|
||||
|
@ -1287,11 +1307,10 @@ namespace crow
|
|||
reset();
|
||||
t_ = type::Object;
|
||||
if (!o)
|
||||
o = std::move(
|
||||
std::unique_ptr<
|
||||
o = std::unique_ptr<
|
||||
std::unordered_map<std::string, wvalue>
|
||||
>(
|
||||
new std::unordered_map<std::string, wvalue>{}));
|
||||
new std::unordered_map<std::string, wvalue>{});
|
||||
return (*o)[str];
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,19 @@ namespace crow
|
|||
{
|
||||
enum class LogLevel
|
||||
{
|
||||
DEBUG,
|
||||
#ifndef ERROR
|
||||
DEBUG = 0,
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
CRITICAL,
|
||||
#endif
|
||||
|
||||
Debug = 0,
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
Critical,
|
||||
};
|
||||
|
||||
class ILogHandler {
|
||||
|
@ -27,7 +35,7 @@ namespace crow
|
|||
|
||||
class CerrLogHandler : public ILogHandler {
|
||||
public:
|
||||
void log(std::string message, LogLevel level) override {
|
||||
void log(std::string message, LogLevel /*level*/) override {
|
||||
std::cerr << message;
|
||||
}
|
||||
};
|
||||
|
@ -117,18 +125,18 @@ namespace crow
|
|||
}
|
||||
|
||||
#define CROW_LOG_CRITICAL \
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::CRITICAL) \
|
||||
crow::logger("CRITICAL", crow::LogLevel::CRITICAL)
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Critical) \
|
||||
crow::logger("CRITICAL", crow::LogLevel::Critical)
|
||||
#define CROW_LOG_ERROR \
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::ERROR) \
|
||||
crow::logger("ERROR ", crow::LogLevel::ERROR)
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Error) \
|
||||
crow::logger("ERROR ", crow::LogLevel::Error)
|
||||
#define CROW_LOG_WARNING \
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::WARNING) \
|
||||
crow::logger("WARNING ", crow::LogLevel::WARNING)
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Warning) \
|
||||
crow::logger("WARNING ", crow::LogLevel::Warning)
|
||||
#define CROW_LOG_INFO \
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::INFO) \
|
||||
crow::logger("INFO ", crow::LogLevel::INFO)
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Info) \
|
||||
crow::logger("INFO ", crow::LogLevel::Info)
|
||||
#define CROW_LOG_DEBUG \
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::DEBUG) \
|
||||
crow::logger("DEBUG ", crow::LogLevel::DEBUG)
|
||||
if (crow::logger::get_current_log_level() <= crow::LogLevel::Debug) \
|
||||
crow::logger("DEBUG ", crow::LogLevel::Debug)
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace crow
|
|||
}
|
||||
}
|
||||
|
||||
void after_handle(request& req, response& res, context& ctx)
|
||||
void after_handle(request& /*req*/, response& res, context& ctx)
|
||||
{
|
||||
for(auto& cookie:ctx.cookies_to_add)
|
||||
{
|
||||
|
|
|
@ -520,7 +520,11 @@ namespace crow
|
|||
|
||||
inline std::string default_loader(const std::string& filename)
|
||||
{
|
||||
std::ifstream inf(detail::get_template_base_directory_ref() + filename);
|
||||
std::string path = detail::get_template_base_directory_ref();
|
||||
if (!(path.back() == '/' || path.back() == '\\'))
|
||||
path += '/';
|
||||
path += filename;
|
||||
std::ifstream inf(path);
|
||||
if (!inf)
|
||||
return {};
|
||||
return {std::istreambuf_iterator<char>(inf), std::istreambuf_iterator<char>()};
|
||||
|
|
|
@ -143,6 +143,11 @@ namespace crow
|
|||
return request{(HTTPMethod)method, std::move(raw_url), std::move(url), std::move(url_params), std::move(headers), std::move(body)};
|
||||
}
|
||||
|
||||
bool is_upgrade() const
|
||||
{
|
||||
return upgrade;
|
||||
}
|
||||
|
||||
bool check_version(int major, int minor) const
|
||||
{
|
||||
return http_major == major && http_minor == minor;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "http_request.h"
|
||||
#include "utility.h"
|
||||
#include "logging.h"
|
||||
#include "websocket.h"
|
||||
|
||||
namespace crow
|
||||
{
|
||||
|
@ -29,8 +30,26 @@ namespace crow
|
|||
}
|
||||
|
||||
virtual void validate() = 0;
|
||||
std::unique_ptr<BaseRule> upgrade()
|
||||
{
|
||||
if (rule_to_upgrade_)
|
||||
return std::move(rule_to_upgrade_);
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual void handle(const request&, response&, const routing_params&) = 0;
|
||||
virtual void handle_upgrade(const request&, response& res, SocketAdaptor&&)
|
||||
{
|
||||
res = response(404);
|
||||
res.end();
|
||||
}
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
virtual void handle_upgrade(const request&, response& res, SSLAdaptor&&)
|
||||
{
|
||||
res = response(404);
|
||||
res.end();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t get_methods()
|
||||
{
|
||||
|
@ -38,10 +57,13 @@ namespace crow
|
|||
}
|
||||
|
||||
protected:
|
||||
uint32_t methods_{1<<(int)HTTPMethod::GET};
|
||||
uint32_t methods_{1<<(int)HTTPMethod::Get};
|
||||
|
||||
std::string rule_;
|
||||
std::string name_;
|
||||
|
||||
std::unique_ptr<BaseRule> rule_to_upgrade_;
|
||||
|
||||
friend class Router;
|
||||
template <typename T>
|
||||
friend struct RuleParameterTraits;
|
||||
|
@ -233,10 +255,82 @@ namespace crow
|
|||
}
|
||||
}
|
||||
|
||||
class WebSocketRule : public BaseRule
|
||||
{
|
||||
using self_t = WebSocketRule;
|
||||
public:
|
||||
WebSocketRule(std::string rule)
|
||||
: BaseRule(std::move(rule))
|
||||
{
|
||||
}
|
||||
|
||||
void validate() override
|
||||
{
|
||||
}
|
||||
|
||||
void handle(const request&, response& res, const routing_params&) override
|
||||
{
|
||||
res = response(404);
|
||||
res.end();
|
||||
}
|
||||
|
||||
void handle_upgrade(const request& req, response&, SocketAdaptor&& adaptor) override
|
||||
{
|
||||
new crow::websocket::Connection<SocketAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_);
|
||||
}
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
|
||||
{
|
||||
new crow::websocket::Connection<SSLAdaptor>(req, std::move(adaptor), open_handler_, message_handler_, close_handler_, error_handler_);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Func>
|
||||
self_t& onopen(Func f)
|
||||
{
|
||||
open_handler_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
self_t& onmessage(Func f)
|
||||
{
|
||||
message_handler_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
self_t& onclose(Func f)
|
||||
{
|
||||
close_handler_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
self_t& onerror(Func f)
|
||||
{
|
||||
error_handler_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::function<void(crow::websocket::connection&)> open_handler_;
|
||||
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
|
||||
std::function<void(crow::websocket::connection&, const std::string&)> close_handler_;
|
||||
std::function<void(crow::websocket::connection&)> error_handler_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct RuleParameterTraits
|
||||
{
|
||||
using self_t = T;
|
||||
WebSocketRule& websocket()
|
||||
{
|
||||
auto p =new WebSocketRule(((self_t*)this)->rule_);
|
||||
((self_t*)this)->rule_to_upgrade_.reset(p);
|
||||
return *p;
|
||||
}
|
||||
|
||||
self_t& name(std::string name) noexcept
|
||||
{
|
||||
((self_t*)this)->name_ = std::move(name);
|
||||
|
@ -256,6 +350,7 @@ namespace crow
|
|||
((self_t*)this)->methods_ |= 1 << (int)method;
|
||||
return (self_t&)*this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class DynamicRule : public BaseRule, public RuleParameterTraits<DynamicRule>
|
||||
|
@ -343,7 +438,7 @@ namespace crow
|
|||
{
|
||||
}
|
||||
|
||||
void validate()
|
||||
void validate() override
|
||||
{
|
||||
if (!handler_)
|
||||
{
|
||||
|
@ -809,10 +904,80 @@ public:
|
|||
for(auto& rule:rules_)
|
||||
{
|
||||
if (rule)
|
||||
{
|
||||
auto upgraded = rule->upgrade();
|
||||
if (upgraded)
|
||||
rule = std::move(upgraded);
|
||||
rule->validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Adaptor>
|
||||
void handle_upgrade(const request& req, response& res, Adaptor&& adaptor)
|
||||
{
|
||||
auto found = trie_.find(req.url);
|
||||
unsigned rule_index = found.first;
|
||||
if (!rule_index)
|
||||
{
|
||||
CROW_LOG_DEBUG << "Cannot match rules " << req.url;
|
||||
res = response(404);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if (rule_index >= rules_.size())
|
||||
throw std::runtime_error("Trie internal structure corrupted!");
|
||||
|
||||
if (rule_index == RULE_SPECIAL_REDIRECT_SLASH)
|
||||
{
|
||||
CROW_LOG_INFO << "Redirecting to a url with trailing slash: " << req.url;
|
||||
res = response(301);
|
||||
|
||||
// TODO absolute url building
|
||||
if (req.get_header_value("Host").empty())
|
||||
{
|
||||
res.add_header("Location", req.url + "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
res.add_header("Location", "http://" + req.get_header_value("Host") + req.url + "/");
|
||||
}
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rules_[rule_index]->get_methods() & (1<<(uint32_t)req.method)) == 0)
|
||||
{
|
||||
CROW_LOG_DEBUG << "Rule found but method mismatch: " << req.url << " with " << method_name(req.method) << "(" << (uint32_t)req.method << ") / " << rules_[rule_index]->get_methods();
|
||||
res = response(404);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
|
||||
CROW_LOG_DEBUG << "Matched rule (upgrade) '" << rules_[rule_index]->rule_ << "' " << (uint32_t)req.method << " / " << rules_[rule_index]->get_methods();
|
||||
|
||||
// any uncaught exceptions become 500s
|
||||
try
|
||||
{
|
||||
rules_[rule_index]->handle_upgrade(req, res, std::move(adaptor));
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
CROW_LOG_ERROR << "An uncaught exception occurred: " << e.what();
|
||||
res = response(500);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
CROW_LOG_ERROR << "An uncaught exception occurred. The type was unknown so no information was available.";
|
||||
res = response(500);
|
||||
res.end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void handle(const request& req, response& res)
|
||||
{
|
||||
auto found = trie_.find(req.url);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#pragma once
|
||||
#include <boost/asio.hpp>
|
||||
#ifdef CROW_ENABLE_SSL
|
||||
#include <boost/asio/ssl.hpp>
|
||||
#endif
|
||||
#include "settings.h"
|
||||
namespace crow
|
||||
{
|
||||
|
@ -14,6 +17,11 @@ namespace crow
|
|||
{
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return socket_.get_io_service();
|
||||
}
|
||||
|
||||
tcp::socket& raw_socket()
|
||||
{
|
||||
return socket_;
|
||||
|
@ -52,20 +60,21 @@ namespace crow
|
|||
struct SSLAdaptor
|
||||
{
|
||||
using context = boost::asio::ssl::context;
|
||||
using ssl_socket_t = boost::asio::ssl::stream<tcp::socket>;
|
||||
SSLAdaptor(boost::asio::io_service& io_service, context* ctx)
|
||||
: ssl_socket_(io_service, *ctx)
|
||||
: ssl_socket_(new ssl_socket_t(io_service, *ctx))
|
||||
{
|
||||
}
|
||||
|
||||
boost::asio::ssl::stream<tcp::socket>& socket()
|
||||
{
|
||||
return ssl_socket_;
|
||||
return *ssl_socket_;
|
||||
}
|
||||
|
||||
tcp::socket::lowest_layer_type&
|
||||
raw_socket()
|
||||
{
|
||||
return ssl_socket_.lowest_layer();
|
||||
return ssl_socket_->lowest_layer();
|
||||
}
|
||||
|
||||
tcp::endpoint remote_endpoint()
|
||||
|
@ -83,16 +92,21 @@ namespace crow
|
|||
raw_socket().close();
|
||||
}
|
||||
|
||||
boost::asio::io_service& get_io_service()
|
||||
{
|
||||
return raw_socket().get_io_service();
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
void start(F f)
|
||||
{
|
||||
ssl_socket_.async_handshake(boost::asio::ssl::stream_base::server,
|
||||
ssl_socket_->async_handshake(boost::asio::ssl::stream_base::server,
|
||||
[f](const boost::system::error_code& ec) {
|
||||
f(ec);
|
||||
});
|
||||
}
|
||||
|
||||
boost::asio::ssl::stream<tcp::socket> ssl_socket_;
|
||||
std::unique_ptr<boost::asio::ssl::stream<tcp::socket>> ssl_socket_;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <type_traits>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace crow
|
||||
{
|
||||
|
@ -14,7 +15,7 @@ namespace crow
|
|||
#ifndef CROW_MSVC_WORKAROUND
|
||||
struct OutOfRange
|
||||
{
|
||||
OutOfRange(unsigned pos, unsigned length) {}
|
||||
OutOfRange(unsigned /*pos*/, unsigned /*length*/) {}
|
||||
};
|
||||
constexpr unsigned requires_in_range( unsigned i, unsigned len )
|
||||
{
|
||||
|
@ -129,7 +130,7 @@ template <> \
|
|||
struct parameter_tag<t> \
|
||||
{ \
|
||||
static const int value = i; \
|
||||
};
|
||||
}
|
||||
CROW_INTERNAL_PARAMETER_TAG(int, 1);
|
||||
CROW_INTERNAL_PARAMETER_TAG(char, 1);
|
||||
CROW_INTERNAL_PARAMETER_TAG(short, 1);
|
||||
|
@ -499,5 +500,47 @@ template <typename F, typename Set>
|
|||
using arg = typename std::tuple_element<i, std::tuple<Args...>>::type;
|
||||
};
|
||||
|
||||
std::string base64encode(const char* data, size_t size, const char* key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
|
||||
{
|
||||
std::string ret;
|
||||
ret.resize((size+2) / 3 * 4);
|
||||
auto it = ret.begin();
|
||||
while(size >= 3)
|
||||
{
|
||||
*it++ = key[(((unsigned char)*data)&0xFC)>>2];
|
||||
unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
|
||||
*it++ = key[h|((((unsigned char)*data)&0xF0)>>4)];
|
||||
h = (((unsigned char)*data++) & 0x0F) << 2;
|
||||
*it++ = key[h|((((unsigned char)*data)&0xC0)>>6)];
|
||||
*it++ = key[((unsigned char)*data++)&0x3F];
|
||||
|
||||
size -= 3;
|
||||
}
|
||||
if (size == 1)
|
||||
{
|
||||
*it++ = key[(((unsigned char)*data)&0xFC)>>2];
|
||||
unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
|
||||
*it++ = key[h];
|
||||
*it++ = '=';
|
||||
*it++ = '=';
|
||||
}
|
||||
else if (size == 2)
|
||||
{
|
||||
*it++ = key[(((unsigned char)*data)&0xFC)>>2];
|
||||
unsigned char h = (((unsigned char)*data++) & 0x03) << 4;
|
||||
*it++ = key[h|((((unsigned char)*data)&0xF0)>>4)];
|
||||
h = (((unsigned char)*data++) & 0x0F) << 2;
|
||||
*it++ = key[h];
|
||||
*it++ = '=';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string base64encode_urlsafe(const char* data, size_t size)
|
||||
{
|
||||
return base64encode(data, size, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_");
|
||||
}
|
||||
|
||||
|
||||
} // namespace utility
|
||||
}
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -1,9 +1,11 @@
|
|||
|
||||
#include "ext/crow/crow.h"
|
||||
|
||||
#include "src/CmdLineOptions.h"
|
||||
#include "src/MicroCore.h"
|
||||
#include "src/page.h"
|
||||
|
||||
#include "ext/crow/crow.h"
|
||||
|
||||
#include "ext/member_checker.h"
|
||||
|
||||
#include <fstream>
|
||||
|
|
|
@ -4,6 +4,17 @@
|
|||
|
||||
#include "MicroCore.h"
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// NOTE: These values should match blockchain.cpp
|
||||
// TODO: Refactor
|
||||
const uint64_t mainnet_hard_fork_version_1_till = 1009826;
|
||||
const uint64_t testnet_hard_fork_version_1_till = 624633;
|
||||
}
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
/**
|
||||
|
@ -46,8 +57,16 @@ namespace xmreg
|
|||
|
||||
//db_flags = DEFAULT_FLAGS;
|
||||
|
||||
HardFork* m_hardfork = nullptr;
|
||||
|
||||
BlockchainDB* db = nullptr;
|
||||
db = new BlockchainLMDB();
|
||||
db = new BlockchainLMDB();
|
||||
|
||||
bool use_testnet {false};
|
||||
|
||||
uint64_t hard_fork_version_1_till = use_testnet ? testnet_hard_fork_version_1_till : mainnet_hard_fork_version_1_till;
|
||||
|
||||
m_hardfork = new HardFork(*db, 1, hard_fork_version_1_till);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -69,7 +88,7 @@ namespace xmreg
|
|||
|
||||
// initialize Blockchain object to manage
|
||||
// the database.
|
||||
return m_blockchain_storage.init(db, false);
|
||||
return m_blockchain_storage.init(db, m_hardfork, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "tx_details.h"
|
||||
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
using namespace cryptonote;
|
||||
|
|
|
@ -15,9 +15,8 @@
|
|||
#include "storages/http_abstract_invoke.h"
|
||||
|
||||
#include "cryptonote_core/cryptonote_basic.h"
|
||||
#include "cryptonote_core/blockchain_storage.h"
|
||||
#include "cryptonote_core/tx_pool.h"
|
||||
#include "cryptonote_core/blockchain.h"
|
||||
|
||||
#include "blockchain_db/lmdb/db_lmdb.h"
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue