Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builds/msvc/vs2022/libbitcoin-system.import.props
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<!-- WITH_ICU always defined in Visual Studio builds. -->
<!-- NOMINMAX enables use of std::min/max without conflict. -->
<!-- WIN32_LEAN_AND_MEAN avoids inclusion of certain headers, winsock.h conflicts with boost and protocol use of winsock2.h. -->
<PreprocessorDefinitions>WITH_ICU;WIN32_LEAN_AND_MEAN;NOMINMAX;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WITH_ICU;WIN32_LEAN_AND_MEAN;NOMINMAX;_WIN32_WINNT=0x0602;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- Disable auto-linking for all boost-json and its dependency boost-container so they can be header only. -->
<PreprocessorDefinitions>BOOST_JSON_NO_LIB;BOOST_CONTAINER_NO_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(Linkage-libbitcoin-system)' == 'static' Or '$(Linkage-libbitcoin-system)' == 'ltcg'">BC_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
Expand Down
21 changes: 6 additions & 15 deletions console/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,17 @@ BC_USE_LIBBITCOIN_MAIN
int bc::system::main(int argc, char* argv[])
{
using namespace bc;
using namespace bc::node;
using namespace bc::system;
using namespace bc::network;
using namespace bc::node;
using namespace bc::server;

// en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio
std::ios_base::sync_with_stdio(false);
set_utf8_stdio();

const server::web_pages web_server{};
const server::explore_pages block_explorer{};
const web_pages web_server{};
const explore_pages block_explorer{};
parser metadata(chain::selection::mainnet, block_explorer, web_server);

const auto& args = const_cast<const char**>(argv);
Expand All @@ -99,18 +101,7 @@ int bc::system::main(int argc, char* argv[])
symbols_path = metadata.configured.log.symbols;
#endif

// Requires _WIN32_WINNT set to 0x0602 (defaults 0x0602 in vc++ 2022).
#if defined(HAVE_MSC) && (_WIN32_WINNT >= _WIN32_WINNT_WIN8)

// Set low memory priority on the current process (testing).
MEMORY_PRIORITY_INFORMATION priority{ MEMORY_PRIORITY_LOW };
SetProcessInformation(
GetCurrentProcess(),
ProcessMemoryPriority,
&priority,
sizeof(priority));

#endif
set_memory_priority(metadata.configured.node.memory_priority_());

executor host(metadata, cin, cout, cerr);
return host.dispatch() ? 0 : -1;
Expand Down
8 changes: 2 additions & 6 deletions include/bitcoin/node/protocols/protocol_explore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,9 @@ class BCN_API protocol_explore
}

protected:
/// Receivers.
void handle_receive_get(const code& ec,
const network::http::method::get& request) NOEXCEPT override;

/// Dispatch.
virtual bool dispatch_object(
const network::http::request& request) NOEXCEPT;
bool try_dispatch_object(
const network::http::request& request) NOEXCEPT override;
};

} // namespace node
Expand Down
6 changes: 5 additions & 1 deletion include/bitcoin/node/protocols/protocol_html.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ class BCN_API protocol_html
const network::http::method::get& request) NOEXCEPT override;

/// Dispatch.
virtual bool dispatch_embedded(
virtual bool try_dispatch_object(
const network::http::request& request) NOEXCEPT;
virtual void dispatch_file(
const network::http::request& request) NOEXCEPT;
virtual void dispatch_embedded(
const network::http::request& request) NOEXCEPT;

/// Senders.
Expand Down
6 changes: 4 additions & 2 deletions include/bitcoin/node/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ class BCN_API settings
settings(system::chain::selection context) NOEXCEPT;

/// Properties.
bool priority;
bool delay_inbound;
bool headers_first;
bool thread_priority;
bool memory_priority;
float allowed_deviation;
uint16_t announcement_cache;
uint16_t allocation_multiple;
Expand All @@ -91,7 +92,8 @@ class BCN_API settings
virtual size_t maximum_concurrency_() const NOEXCEPT;
virtual network::steady_clock::duration sample_period() const NOEXCEPT;
virtual network::wall_clock::duration currency_window() const NOEXCEPT;
virtual network::thread_priority priority_() const NOEXCEPT;
virtual network::processing_priority thread_priority_() const NOEXCEPT;
virtual network::memory_priority memory_priority_() const NOEXCEPT;
};

} // namespace node
Expand Down
3 changes: 2 additions & 1 deletion src/chasers/chaser_validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
// Independent threadpool and strand (base class strand uses network pool).
chaser_validate::chaser_validate(full_node& node) NOEXCEPT
: chaser(node),
threadpool_(node.config().node.threads_(), node.config().node.priority_()),
threadpool_(node.config().node.threads_(),
node.config().node.thread_priority_()),
independent_strand_(threadpool_.service().get_executor()),
subsidy_interval_(node.config().bitcoin.subsidy_interval_blocks),
initial_subsidy_(node.config().bitcoin.initial_subsidy()),
Expand Down
11 changes: 8 additions & 3 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,9 +1004,14 @@ options_metadata parser::load_settings() THROWS
"The number of threads in the validation threadpool, defaults to '32'."
)
(
"node.priority",
value<bool>(&configured.node.priority),
"Set the validation threadpool to high priority, defaults to 'true'."
"node.thread_priority",
value<bool>(&configured.node.thread_priority),
"Set validation threads to high processing priority, defaults to 'true'."
)
(
"node.memory_priority",
value<bool>(&configured.node.memory_priority),
"Set the process to high memory priority, defaults to 'true'."
)
(
"node.delay_inbound",
Expand Down
84 changes: 4 additions & 80 deletions src/protocols/protocol_explore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,95 +24,19 @@ namespace libbitcoin {
namespace node {

#define CLASS protocol_explore

using namespace boost::json;
using namespace std::placeholders;
using namespace network::http;

using namespace system;
using namespace network::http;

BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)

// Handle get method.
// ----------------------------------------------------------------------------

void protocol_explore::handle_receive_get(const code& ec,
const method::get& request) NOEXCEPT
{
BC_ASSERT(stranded());

if (stopped(ec))
return;

// Enforce http origin policy (requires configured hosts).
if (!is_allowed_origin(*request, request->version()))
{
send_forbidden(*request);
return;
}

// Enforce http host header (if any hosts are configured).
if (!is_allowed_host(*request, request->version()))
{
send_bad_host(*request);
return;
}

// Dispatch object with specified encoding.
if (dispatch_object(*request))
return;

// Embedded page site.
if (dispatch_embedded(*request))
return;

// Empty path implies malformed target (terminal).
auto path = to_local_path(request->target());
if (path.empty())
{
send_bad_target(*request);
return;
}

// If no file extension it's REST on the single/default html page.
if (!path.has_extension())
{
path = to_local_path();

// Default html page (e.g. index.html) is not configured.
if (path.empty())
{
send_not_implemented(*request);
return;
}
}

// Get the single/default or explicitly requested page.
auto file = get_file_body(path);
if (!file.is_open())
{
send_not_found(*request);
return;
}

send_file(*request, std::move(file),
file_mime_type(path, mime_type::application_octet_stream));
}

// Dispatch.
// ----------------------------------------------------------------------------

bool protocol_explore::dispatch_object(
const network::http::request& request) NOEXCEPT
bool protocol_explore::try_dispatch_object(const request& request) NOEXCEPT
{
const auto target = request.target();
if (!is_origin_form(target))
{
send_bad_target(request);
return true;
}

wallet::uri uri{};
if (!uri.decode(target))
if (!uri.decode(request.target()))
{
send_bad_target(request);
return true;
Expand Down
89 changes: 64 additions & 25 deletions src/protocols/protocol_html.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,14 @@ void protocol_html::handle_receive_get(const code& ec,
if (stopped(ec))
return;

// Enforce http origin policy (requires configured hosts).
// Enforce http origin form for get.
if (!is_origin_form(request->target()))
{
send_bad_target(*request);
return;
}

// Enforce http origin policy (if any origins are configured).
if (!is_allowed_origin(*request, request->version()))
{
send_forbidden(*request);
Expand All @@ -55,67 +62,99 @@ void protocol_html::handle_receive_get(const code& ec,
return;
}

// Embedded page site.
if (dispatch_embedded(*request))
// Always try API dispatch, false if unhandled.
if (try_dispatch_object(*request))
return;

// Empty path implies malformed target (terminal).
const auto path = to_local_path(request->target());
if (path.empty())
// Require file system dispatch if path is configured (always handles).
if (!options_.path.empty())
{
// TODO: split out sanitize from canonicalize so that this can return
// send_not_found() when the request is sanitary but not found.
send_bad_target(*request);
dispatch_file(*request);
return;
}

// Not open implies file not found (non-terminal).
auto file = get_file_body(path);
if (!file.is_open())
// Require embedded dispatch if site is configured (always handles).
if (options_.pages.enabled())
{
send_not_found(*request);
dispatch_embedded(*request);
return;
}

send_file(*request, std::move(file),
file_mime_type(path, mime_type::application_octet_stream));
// Neither site is enabled and object dispatch doesn't support.
send_not_implemented(*request);
}

// Dispatch.
// ----------------------------------------------------------------------------

bool protocol_html::dispatch_embedded(const request& request) NOEXCEPT
bool protocol_html::try_dispatch_object(const request&) NOEXCEPT
{
// False only if not enabled, otherwise handled below.
if (!options_.pages.enabled())
return false;
return false;
}

void protocol_html::dispatch_embedded(const request& request) NOEXCEPT
{
const auto& pages = config().server.explore.pages;
switch (const auto mime = file_mime_type(to_path(request.target())))
{
case mime_type::text_css:
send_span(request, pages.css(), mime);
return true;
break;
case mime_type::text_html:
send_span(request, pages.html(), mime);
return true;
break;
case mime_type::application_javascript:
send_span(request, pages.ecma(), mime);
return true;
break;
case mime_type::font_woff:
case mime_type::font_woff2:
send_span(request, pages.font(), mime);
return true;
break;
case mime_type::image_png:
case mime_type::image_gif:
case mime_type::image_jpeg:
send_span(request, pages.icon(), mime);
return true;
break;
default:
return false;
send_not_found(request);
}
}

void protocol_html::dispatch_file(const request& request) NOEXCEPT
{
// Empty path implies malformed target (terminal).
auto path = to_local_path(request.target());
if (path.empty())
{
send_bad_target(request);
return;
}

// If no file extension it's REST on the single/default html page.
if (!path.has_extension())
{
path = to_local_path();

// Default html page (e.g. index.html) is not configured.
if (path.empty())
{
send_not_implemented(request);
return;
}
}

// Get the single/default or explicitly requested page.
auto file = get_file_body(path);
if (!file.is_open())
{
send_not_found(request);
return;
}

const auto octet_stream = mime_type::application_octet_stream;
send_file(request, std::move(file), file_mime_type(path, octet_stream));
}

// Senders.
// ----------------------------------------------------------------------------

Expand Down
Loading
Loading