by 0xdead4ead

0xdead4ead / BeastHttp

Provides helper tools for creating RESTful services using Boost.Beast

217 Stars 26 Forks Last release: about 2 years ago (1.0.4) BSD 2-Clause "Simplified" License 380 Commits 4 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

SYNOPSIS license build badge.cpp

Easy HTTP (Header-only) library implemented using minimum C++11 and Boost.Beast. Allows you to get or provide REST resources available from an application in C ++. Use all the features of the Boost.Beast when constructing queries and answers.


  • HTTP 1.0 / 1.1
  • Pipeline request
  • Used I/O multiplexing model (Asio library implementation)
  • Timer manage (default action: Closing connection)
  • Server-Sent Events
  • Simple way to dynamic add REST resources using regex for path, and anonymous functions
  • Support accepted plain and SSL session on the same port



More examples is

The following notes show the standard syntax for setting up routes and starting a server!

Alias's represent instances of default classes for reactive (select/epool) design.

    using namespace _0xdead4ead;
    namespace beast = boost::beast;

using http_session = http::reactor::_default::session_type;
using http_listener = http::reactor::_default::listener_type;

Creating a new callback functions storage and route path for GET request with "/" resource:

    static const std::regex::flag_type regex_flags = std::regex::ECMAScript;

http::basic_router<http_session> router{regex_flags};

router.get("^/$", [](auto beast_http_request, auto context) {
    context.send(make_200<:http::string_body>(beast_http_request, "Main page\n", "text/html"));

router.all("^.*$", [](auto beast_http_request, auto context) {
    context.send(make_404<:http::string_body>(beast_http_request, "Resource is not found\n", "text/html"));

// or so ...

using http::literals::operator""_get;

"^/$"_get.advance(router, [](auto beast_http_request, auto context) {
    // as above...

"^.*$"_all.advance(router, [](auto beast_http_request, auto context) {
    // as above...


It is possible to add multiple handlers for one route. For movement on them

is used:
       [](auto /*beast_http_request*/, auto /*context*/, auto iterator){
        // process /a
    }, [](auto /*beast_http_request*/, auto /*context*/){
        // process /b

Getting a parameter from a URI. Request send example

curl localhost --request 'GET' --request-target '/user/param?y=1992'
    using pack = http::param::pack;

   [](auto /*beast_http_request*/, auto /*context*/, auto args){
    assert(std::get&lt;0&gt;(args) == 1992);

// or

   [](auto /*beast_http_request*/, auto /*context*/, auto iterator, auto /*args*/){
    // process /user
}, [](auto /*beast_http_request*/, auto /*context*/, auto args){
    // process /param
    assert(std::get&lt;0&gt;(args) == 1992);

Getting a parameter using a string literal (as above) :

    // For value f'n is required c++14
    using http::literals::value;
    using http::literals::operator""_c;

auto param = router.param<pack>();

   [](auto /*beast_http_request*/, auto /*context*/, auto args){
    assert(value(args, 0_c) == 1992);

Create modular, mounted route handlers:

    http::basic_router animals{regex_flags};

animals.get("^/cat$", [](auto beast_http_request, auto context){ // '/animals/cat'
    context.send(make_200<:http::string_body>(beast_http_request, "me-ow\n", "text/html"));

animals.get("^/dog$", [](auto beast_http_request, auto context){ // '/animals/dog'
    context.send(make_200<:http::string_body>(beast_http_request, "aw! aw! Rrrrr\n", "text/html"));

animals.get("^/mouse$", [](auto beast_http_request, auto context){ // '/animals/mouse'
    context.send(make_200<:http::string_body>(beast_http_request, "...\n", "text/html"));

animals.get("^[/]??$", [](auto beast_http_request, auto context){ // '/animals' or '/animals/'
    context.send(make_200<:http::string_body>(beast_http_request, "animals home page\n", "text/html"));

router.use("^/animals$", animals);


Create handlers routes, forming a chain, for the route path:

    http::chain_router books{regex_flags};

        .get([](auto beast_http_request, auto context) {
    context.send(make_200<:http::string_body>(beast_http_request, "get a random book\n", "text/html"));
        .post([](auto beast_http_request, auto context) {
    context.send(make_200<:http::string_body>(beast_http_request, "add a book\n", "text/html"));
        .put([](auto beast_http_request, auto context) {
    context.send(make_200<:http::string_body>(beast_http_request, "update the book\n", "text/html"));

router.use("^/books$", books);


Start listening on

    // global namespace
    static boost::asio::io_context ioc;
    static boost::asio::posix::stream_descriptor out{ioc, ::dup(STDERR_FILENO)};

const auto&amp; onError = [](auto system_error_code, auto from){
                out, "From:", from, "Info:", system_error_code.message());

const auto&amp; onAccept = [&amp;](auto asio_socket){
    auto endpoint = asio_socket.remote_endpoint();

                out, endpoint.address().to_string() + ':' + std::to_string(endpoint.port()), "connected!");

    http_session::recv(std::move(asio_socket), router, onError);

auto const address = boost::asio::ip::address_v4::any();
auto const port = static_cast<unsigned short>(8080);

http_listener::launch(ioc, {address, port}, onAccept, onError);


Run the I/O service on the requested number of threads:

    std::thread t{[](){;

// do other work...


We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.