Skip to content

Commit

Permalink
Add option to use Boost.Asio
Browse files Browse the repository at this point in the history
  • Loading branch information
bugdea1er committed Apr 4, 2024
1 parent ad337a8 commit d178be3
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 46 deletions.
21 changes: 15 additions & 6 deletions CMakeLists.txt
Expand Up @@ -46,6 +46,7 @@ option(CROW_BUILD_EXAMPLES "Build the examples in the project" ${CROW_I
option(CROW_BUILD_TESTS "Build the tests in the project" ${CROW_IS_MAIN_PROJECT})
option(CROW_AMALGAMATE "Combine all headers into one" OFF)
option(CROW_INSTALL "Add install step for Crow" ON )
option(CROW_USE_BOOST "Use Boost.Asio for Crow" OFF)

# Possible values: ssl, compression
option(CROW_FEATURES "Enable features extending Crow's abilities" "")
Expand All @@ -62,12 +63,20 @@ target_include_directories(Crow
$<INSTALL_INTERFACE:include>
)

find_package(asio REQUIRED)

target_link_libraries(Crow
INTERFACE
asio::asio
)
if(CROW_USE_BOOST)
find_package(Boost 1.64 COMPONENTS system date_time REQUIRED)
target_link_libraries(Crow
INTERFACE
Boost::boost Boost::system Boost::date_time
)
target_compile_definitions(Crow INTERFACE CROW_USE_BOOST)
else()
find_package(asio REQUIRED)
target_link_libraries(Crow
INTERFACE
asio::asio
)
endif()

target_compile_definitions(Crow INTERFACE "")

Expand Down
33 changes: 22 additions & 11 deletions include/crow/http_connection.h
@@ -1,32 +1,43 @@
#pragma once

#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#endif

#include <algorithm>
#include <atomic>
#include <chrono>
#include <vector>
#include <memory>
#include <vector>

#include "crow/http_parser_merged.h"
#include "crow/common.h"
#include "crow/parser.h"
#include "crow/compression.h"
#include "crow/http_response.h"
#include "crow/logging.h"
#include "crow/settings.h"
#include "crow/task_timer.h"
#include "crow/middleware_context.h"
#include "crow/middleware.h"
#include "crow/middleware_context.h"
#include "crow/parser.h"
#include "crow/settings.h"
#include "crow/socket_adaptors.h"
#include "crow/compression.h"
#include "crow/task_timer.h"
#include "crow/utility.h"

namespace crow
{
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;


#ifdef CROW_ENABLE_DEBUG
static std::atomic<int> connectionCount;
#endif
Expand Down Expand Up @@ -81,7 +92,7 @@ namespace crow
void start()
{
auto self = this->shared_from_this();
adaptor_.start([self](const asio::error_code& ec) {
adaptor_.start([self](const error_code& ec) {
if (!ec)
{
self->start_deadline();
Expand Down Expand Up @@ -473,7 +484,7 @@ namespace crow
auto self = this->shared_from_this();
adaptor_.socket().async_read_some(
asio::buffer(buffer_),
[self](const asio::error_code& ec, std::size_t bytes_transferred) {
[self](const error_code& ec, std::size_t bytes_transferred) {
bool error_while_reading = true;
if (!ec)
{
Expand Down Expand Up @@ -516,7 +527,7 @@ namespace crow
auto self = this->shared_from_this();
asio::async_write(
adaptor_.socket(), buffers_,
[self](const asio::error_code& ec, std::size_t /*bytes_transferred*/) {
[self](const error_code& ec, std::size_t /*bytes_transferred*/) {
self->res.clear();
self->res_body_copy_.clear();
if (!self->continue_requested)
Expand Down Expand Up @@ -547,7 +558,7 @@ namespace crow
inline void do_write_sync(std::vector<asio::const_buffer>& buffers)
{

asio::write(adaptor_.socket(), buffers, [&](asio::error_code ec, std::size_t) {
asio::write(adaptor_.socket(), buffers, [&](error_code ec, std::size_t) {
if (!ec)
{
return false;
Expand Down
8 changes: 8 additions & 0 deletions include/crow/http_request.h
@@ -1,16 +1,24 @@
#pragma once

#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#endif

#include "crow/common.h"
#include "crow/ci_map.h"
#include "crow/query_string.h"

namespace crow
{
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
#endif

/// Find and return the value associated with the key. (returns an empty string if nothing is found)
template<typename T>
inline const std::string& get_header_value(const T& headers, const std::string& key)
Expand Down
28 changes: 21 additions & 7 deletions include/crow/http_server.h
@@ -1,18 +1,26 @@
#pragma once

#include <chrono>
#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#ifdef CROW_ENABLE_SSL
#include <boost/asio/ssl.hpp>
#endif
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#ifdef CROW_ENABLE_SSL
#include <asio/ssl.hpp>
#endif
#include <cstdint>
#endif

#include <atomic>
#include <chrono>
#include <cstdint>
#include <future>
#include <vector>
#include <memory>
#include <vector>

#include "crow/version.h"
#include "crow/http_connection.h"
Expand All @@ -21,6 +29,12 @@

namespace crow
{
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;

template<typename Handler, typename Adaptor = SocketAdaptor, typename... Middlewares>
Expand Down Expand Up @@ -52,7 +66,7 @@ namespace crow
{
tick_function_();
tick_timer_.expires_after(std::chrono::milliseconds(tick_interval_.count()));
tick_timer_.async_wait([this](const asio::error_code& ec) {
tick_timer_.async_wait([this](const error_code& ec) {
if (ec)
return;
on_tick();
Expand Down Expand Up @@ -128,7 +142,7 @@ namespace crow
{
tick_timer_.expires_after(std::chrono::milliseconds(tick_interval_.count()));
tick_timer_.async_wait(
[this](const asio::error_code& ec) {
[this](const error_code& ec) {
if (ec)
return;
on_tick();
Expand All @@ -143,7 +157,7 @@ namespace crow
CROW_LOG_INFO << "Call `app.loglevel(crow::LogLevel::Warning)` to hide Info level logs.";

signals_.async_wait(
[&](const asio::error_code& /*error*/, int /*signal_number*/) {
[&](const error_code& /*error*/, int /*signal_number*/) {
stop();
});

Expand Down Expand Up @@ -227,7 +241,7 @@ namespace crow

acceptor_.async_accept(
p->socket(),
[this, p, &is, service_idx](asio::error_code ec) {
[this, p, &is, service_idx](error_code ec) {
if (!ec)
{
is.post(
Expand Down
45 changes: 33 additions & 12 deletions include/crow/socket_adaptors.h
@@ -1,20 +1,41 @@
#pragma once

#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#include <boost/asio/version.hpp>
#ifdef CROW_ENABLE_SSL
#include <boost/asio/ssl.hpp>
#endif
#if BOOST_VERSION >= 107000
#define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context())
#else
#define GET_IO_SERVICE(s) ((s).get_io_service())
#endif
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#include <asio/version.hpp>
#ifdef CROW_ENABLE_SSL
#include <asio/ssl.hpp>
#endif
#include "crow/settings.h"
#include <asio/version.hpp>
#if ASIO_VERSION >= 101300 // 1.13.0
#define GET_IO_SERVICE(s) ((asio::io_context&)(s).get_executor().context())
#else
#define GET_IO_SERVICE(s) ((s).get_io_service())
#endif
#endif
#include "crow/settings.h"

namespace crow
{
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;

/// A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
Expand Down Expand Up @@ -54,32 +75,32 @@ namespace crow

void close()
{
asio::error_code ec;
error_code ec;
socket_.close(ec);
}

void shutdown_readwrite()
{
asio::error_code ec;
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
}

void shutdown_write()
{
asio::error_code ec;
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
}

void shutdown_read()
{
asio::error_code ec;
error_code ec;
socket_.shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
}

template<typename F>
void start(F f)
{
f(asio::error_code());
f(error_code());
}

tcp::socket socket_;
Expand Down Expand Up @@ -119,7 +140,7 @@ namespace crow
{
if (is_open())
{
asio::error_code ec;
error_code ec;
raw_socket().close(ec);
}
}
Expand All @@ -128,7 +149,7 @@ namespace crow
{
if (is_open())
{
asio::error_code ec;
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_both, ec);
}
}
Expand All @@ -137,7 +158,7 @@ namespace crow
{
if (is_open())
{
asio::error_code ec;
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_send, ec);
}
}
Expand All @@ -146,7 +167,7 @@ namespace crow
{
if (is_open())
{
asio::error_code ec;
error_code ec;
raw_socket().shutdown(asio::socket_base::shutdown_type::shutdown_receive, ec);
}
}
Expand All @@ -160,7 +181,7 @@ namespace crow
void start(F f)
{
ssl_socket_->async_handshake(asio::ssl::stream_base::server,
[f](const asio::error_code& ec) {
[f](const error_code& ec) {
f(ec);
});
}
Expand Down
13 changes: 12 additions & 1 deletion include/crow/task_timer.h
@@ -1,10 +1,15 @@
#pragma once

#ifdef CROW_USE_BOOST
#include <boost/asio.hpp>
#include <boost/asio/basic_waitable_timer.hpp>
#else
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>
#include <asio/basic_waitable_timer.hpp>
#endif

#include <chrono>
#include <functional>
Expand All @@ -15,6 +20,12 @@

namespace crow
{
#ifdef CROW_USE_BOOST
namespace asio = boost::asio;
using error_code = boost::system::error_code;
#else
using error_code = asio::error_code;
#endif
namespace detail
{

Expand Down Expand Up @@ -112,7 +123,7 @@ namespace crow
if (tasks_.empty()) highest_id_ = 0;
}

void tick_handler(const asio::error_code& ec)
void tick_handler(const error_code& ec)
{
if (ec) return;

Expand Down

0 comments on commit d178be3

Please sign in to comment.