Cross-platform, efficient, customizable, and robust asynchronous HTTP/WebSocket server C++14 library with the right balance between performance and ease of use

Overview

What Is RESTinio?

RESTinio is a header-only C++14 library that gives you an embedded HTTP/Websocket server. It is based on standalone version of ASIO and targeted primarily for asynchronous processing of HTTP-requests. Since v.0.4.1 Boost::ASIO (1.66 or higher) is also supported (see notes on building with Boost::ASIO).

A Very Basic Example Of RESTinio

Consider the task of writing a C++ application that must support some REST API, RESTinio represents our solution for that task. Currently it is in stable beta state. Lets see how it feels like in the simplest case:

#include <restinio/all.hpp>
int main()
{
    restinio::run(
        restinio::on_this_thread()
        .port(8080)
        .address("localhost")
        .request_handler([](auto req) {
            return req->create_response().set_body("Hello, World!").done();
        }));
    return 0;
}

Server runs on the main thread, and respond to all requests with hello-world message. Of course you've got an access to the structure of a given HTTP request, so you can apply a complex logic for handling requests.

Features

  • Async request handling. Cannot get the response data immediately? That's ok, store request handle somewhere and/or pass it to another execution context and get back to it when the data is ready.
  • HTTP pipelining. Works well with async request handling. It might increase your server throughput dramatically.
  • Timeout control. RESTinio can take care of bad connection that are like: send "GET /" and then just stuck.
  • Response builders. Need chunked-encoded body - then RESTinio has a special response builder for you (obviously it is not the only builder).
  • ExpressJS-like request routing (see an example below).
  • An experimental typesafe request router that allows avoiding problems of ExpressJS-like router with help of static checks from C++ compiler.
  • A possibility to chain several request-handlers (somewhat similar to ExpressJS's middleware).
  • Working with query string parameters.
  • Several ready-to-use helpers for working with HTTP headers (for example, the support for HTTP headers related to file uploading).
  • Supports sending files and its parts (with sendfile on linux/unix and TransmitFile on windows).
  • Supports compression (deflate, gzip).
  • Supports TLS (HTTPS).
  • Basic websocket support. Simply restinio::websocket::basic::upgrade() the request handle and start websocket session on a corresponding connection.
  • Can run on external asio::io_context. RESTinio is separated from execution context.
  • Some tune options. One can set acceptor and socket options. When running RESTinio on a pool of threads connections can be accepted in parallel.

Enhanced Example With Express Router

#include <restinio/all.hpp>

using namespace restinio;

template<typename T>
std::ostream & operator<<(std::ostream & to, const optional_t<T> & v) {
    if(v) to << *v;
    return to;
}

int main() {
    // Create express router for our service.
    auto router = std::make_unique<router::express_router_t<>>();
    router->http_get(
            R"(/data/meter/:meter_id(\d+))",
            [](auto req, auto params) {
                const auto qp = parse_query(req->header().query());
                return req->create_response()
                        .set_body(
                                fmt::format("meter_id={} (year={}/mon={}/day={})",
                                        cast_to<int>(params["meter_id"]),
                                        opt_value<int>(qp, "year"),
                                        opt_value<int>(qp, "mon"),
                                        opt_value<int>(qp, "day")))
                        .done();
            });

    router->non_matched_request_handler(
            [](auto req){
                return req->create_response(restinio::status_not_found()).connection_close().done();
            });

    // Launching a server with custom traits.
    struct my_server_traits : public default_single_thread_traits_t {
        using request_handler_t = restinio::router::express_router_t<>;
    };

    restinio::run(
            restinio::on_this_thread<my_server_traits>()
                    .address("localhost")
                    .request_handler(std::move(router)));

    return 0;
}

License

RESTinio is distributed under BSD-3-CLAUSE license.

How To Use It?

The full documentation for RESTinio can be found here.

More

Comments
  • acceptor.h seems to block

    acceptor.h seems to block

    Hi,

    I am using restinio on a server receiving a lot of connections. I saw that sometimes, the server is hanging and doesn't accepts any new connections (but current connections continue to work without issues).

    Just before hanging, this is what I see in the logs:

    an exception in 'accept_current_connection': remote_endpoint: Transport endpoint is not connected
    

    So, my assumption is that https://github.com/Stiffstream/restinio/blob/bd4382c2fd355efa8ee2f1fffe62f0134b472e30/dev/restinio/impl/acceptor.hpp#L308 is not recovering after that exception. (This line is throwing the exception: https://github.com/Stiffstream/restinio/blob/bd4382c2fd355efa8ee2f1fffe62f0134b472e30/dev/restinio/impl/acceptor.hpp#L372)

    I'm currently investigating, but if you have any clue, it will be appreciated :)

    opened by AmarOk1412 35
  • user_controlled_output_t closes the connection on .flush()

    user_controlled_output_t closes the connection on .flush()

    Hi Stiffstream,

    I'm trying to implement a user_controlled_output_t as a response inside my get handler. However, the connection is getting closed on a flush() as seen in this simple:

    request_status Server::get(restinio::request_handle_t request,
                             restinio::router::route_params_t params)
    {
        printf("connection_id: %lu\n", request->connection_id());
    
        using output_t = restinio::user_controlled_output_t;
        auto response = this->init_http_resp(request->create_response<output_t>(
    
        ));
        //response.set_content_length(request->body().size());
        response.flush();
        std::this_thread::sleep_for(std::chrono::seconds(2));
    
        std::string part1 = "i like";
        response.set_body(part1);
        response.set_content_length(part1.size());
        response.flush();
        std::this_thread::sleep_for(std::chrono::seconds(2));
    
        std::string part2 = " waffles!";
        response.set_body(part2);
        response.set_content_length(part2.size());
        response.flush();
        std::this_thread::sleep_for(std::chrono::seconds(2));
    
        return response.done();
    }
    

    I'm implementing your amazing RESTinio server into OpenDHT project that needs to be able to send get responses by parts i.e. head first then, once a callback is fired for a value found on a node, another one and so forth until done callback.

    I also went into debugging your code base with gdb and the flags are properly set:

    gdb$ b /usr/local/include/restinio/impl/connection.hpp:794
    Breakpoint 1 at 0xb10b1: file /usr/local/include/restinio/impl/connection.hpp, line 794.
    ...
    gdb$ p response_output_flags
    $1 = {m_response_parts = restinio::response_parts_attr_t::not_final_parts, m_response_connection = restinio::response_connection_attr_t::connection_keepalive}
    

    But it seems that the connection is getting closed on a flush() which is strange to me because the definition of a flush would be considered a different one from done() in terms of not closing the connection with response_parts_attr_t::not_finals_parts whereas a done() is sending response_parts_attr_t::final_parts flag.

    The goal is to be able to perform an async yield like this part that I am removing.

    Thank you for your time!

    Sincerely, Seva

    opened by binarytrails 23
  • Getting the connection state/status

    Getting the connection state/status

    Hi devs,

    We have one last operation on the server called LISTEN which keeps a connection open at the maximum defined delay in the settings handle_request_timeout. Everything is good and I can send chunks and close it using the response with response.connection_close(). I can find its ID with request->connection_id() which returns a connection_id_t.

    However, we need to be able to check the connection state (open, closed) using the connection_id_t or any other object in a different thread to close the connections gracefully in case we shutdown the server as well as use this observer thread to close the active listeners on the OpenDHT thread.

    Thank you for the heads up! :rocket: Seva

    opened by binarytrails 19
  • LGTM pass by value

    LGTM pass by value

    Hello i followed the example from the markdown for creating a request, but now i got this warning from LGTM security services:

    Capture d’écran 2019-08-07 à 19 10 53

    Can we pass the router as const reference, or it's always as copy (like your example)

    opened by Milerius 17
  • Why is http_header_fields_t::find() private?

    Why is http_header_fields_t::find() private?

    Is there a specific reason that all find methods in http_header_fields_t are private? If I want to check for the existence of a field and get its value if it exists, I have to either use has_field and get_field doing the lookup twice, or I could use the public begin and end methods with std::find_if duplicating what find already does.

    opened by rcane 17
  • Error compiling tls_socket_t under MSVC

    Error compiling tls_socket_t under MSVC

    When trying to create a tls-enabled server the MSVC compiler complains about this:

    ...restinio/impl/tls_socket.hpp(93): error C3779: 'restinio::impl::tls_socket_t::lowest_layer': a function that returns 'auto' cannot be used before it is defined
    ...restinio/impl/tls_socket.hpp(60): note: see declaration of 'restinio::impl::tls_socket_t::lowest_layer'
    ...restinio/impl/tls_socket.hpp(93): note: This diagnostic occurred in the compiler generated function 'void restinio::impl::tls_socket_t::cancel(Args &&...)'
    ...
    

    Simply not using lowest_layer() inside tls_socket_t's methods and instead replacing it with m_socket->lowest_layer() fixes the problem.

    opened by rcane 16
  • How best to return a 405 response from express router

    How best to return a 405 response from express router

    I am looking for suggestion, to create example for how someone can return 405 on endpoint.

    For instance for any given route...

    auto router = std::make_unique<router_t>();
    router->http_post("/author/:author", [](auto req, auto param) {
        if(req->header().method() != http_method_post()) {
            return req->create_response(status_method_not_allowed())
                .connection_close().done();
        }
        // Happily process the request
    }
    

    What I would like to avoid is creating routes for every single method for each path and handling all the "bad methods" that I need to block.

    opened by prince-chrismc 13
  • restinio unable to regonize `*!` in url

    restinio unable to regonize `*!` in url

    when request /foo?bar=*, restinio will raise exception:

    restinio error while handling request: invalid non-escaped char with code 0X2A
    

    Also for url /foo?bar=!.

    *! will be not encoded in url in Chrome. One can check the result of encodeURIComponent("!*") in Chrome console.

    opened by zhangzq 12
  • Sendfile works faster for larger files?

    Sendfile works faster for larger files?

    I've been doing benchmarks for multiple web-servers/REST frameworks inlcuding rwasa, asmttpd, C++ REST SDK, Spring MVC, Spring Webflux and Restinio. The performance for sending files with Restinio was among the best. Especially that it didn't have the deadlocking problem serving files with multiple requests that the C++ REST SDK had. However, I've noticed a strange behavior with Restinio: I make 4 comparative benchmarks with Gatling: 2 with 300 simultaneous users and 2 with 3000 users, each one is done with 70 bytes and 700kb files respectively. The smaller file is an HTTP file and the larger one is a binary file. For the larger file the response time has been like this: image

    and for the smaller file like this: image

    As you can see, the smaller file has a larger average time for some reason! I've done that multiple times and always had the same results. Any explanation for that? All the tests were done on the sendfile sample on Linux

    opened by ahmedyarub 12
  • error: exception specification of explicitly defaulted move constructor... in buffers.hpp

    error: exception specification of explicitly defaulted move constructor... in buffers.hpp

    This code was introduced in #53.

    I was trying to compile the example from the README to check whether I am including RESTinio appropriately in my project, but I get this error:

    /Users/Koji/performous/3rdparty/restinio/dev/restinio/buffers.hpp:215:3: error: exception specification of explicitly defaulted move constructor
          does not match the calculated one
                    datasizeable_buf_t( datasizeable_buf_t && ) noexcept = default; // allow only explicit move.
                    ^
    /Users/Koji/performous/3rdparty/restinio/dev/restinio/buffers.hpp:381:3: note: in instantiation of template class
          'restinio::impl::datasizeable_buf_t<fmt::v6::basic_memory_buffer<char, 1, std::__1::allocator<char> > >' requested here
                    alignof( fmt_minimal_memory_buffer_buf_t ) } );
                    ^
    

    I am using XCode's Clang on macOS 10.14.6

    opened by Lord-Kamina 11
  • Empty response with the sendfile operation

    Empty response with the sendfile operation

    Hi,

    I am trying to use the sendfile operation to send a text file, but I get an empty response. This is a minimal example of what I am doing:

    restinio::run(
            restinio::on_this_thread()
              .port(8080)
              .address("localhost")
              .request_handler([](auto req) {
                return req->create_response().append_header(restinio::http_field::content_type, "text/plain; charset=utf-8").set_body(restinio::sendfile("C:/Workspace/test.txt")).done();
              }));
    

    Any help would be much appreciated. Thanks! :)

    opened by govinddanil 10
  • test suite fails in isolated build container

    test suite fails in isolated build container

    Hello,

    When attempting to run the test suite of 0.6.15 on GNU Guix, it fails like so:

    starting phase `check'
    Running tests...
    /gnu/store/j65q3aw414010gdfvmsynwpzfb2jyyd3-cmake-minimal-3.21.4/bin/ctest --force-new-ctest-process 
    Test project /tmp/guix-build-restinio-0.6.15.drv-0/source/build
          Start  1: _unit.test.metaprogramming
     1/59 Test  #1: _unit.test.metaprogramming ...........................   Passed    0.00 sec
          Start  2: _unit.test.tuple_algorithms
     2/59 Test  #2: _unit.test.tuple_algorithms ..........................   Passed    0.00 sec
          Start  3: _unit.test.http_field_parser
     3/59 Test  #3: _unit.test.http_field_parser .........................   Passed    0.00 sec
          Start  4: _unit.test.try_parse_field
     4/59 Test  #4: _unit.test.try_parse_field ...........................   Passed    0.00 sec
          Start  5: _unit.test.multipart_body
     5/59 Test  #5: _unit.test.multipart_body ............................   Passed    0.00 sec
          Start  6: _unit.test.default_constructed_settings
     6/59 Test  #6: _unit.test.default_constructed_settings ..............   Passed    0.00 sec
          Start  7: _unit.test.ref_qualifiers_settings
     7/59 Test  #7: _unit.test.ref_qualifiers_settings ...................   Passed    0.00 sec
          Start  8: _unit.test.header
     8/59 Test  #8: _unit.test.header ....................................   Passed    0.00 sec
          Start  9: _unit.test.buffers
     9/59 Test  #9: _unit.test.buffers ...................................   Passed    0.00 sec
          Start 10: _unit.test.response_coordinator
    10/59 Test #10: _unit.test.response_coordinator ......................   Passed    0.00 sec
          Start 11: _unit.test.write_group_output_ctx
    11/59 Test #11: _unit.test.write_group_output_ctx ....................   Passed    0.00 sec
          Start 12: _unit.test.uri_helpers
    12/59 Test #12: _unit.test.uri_helpers ...............................   Passed    0.00 sec
          Start 13: _unit.test.socket_options
    13/59 Test #13: _unit.test.socket_options ............................***Failed    0.00 sec
    [2022-11-04 17:55:26.400] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.400]  INFO: init accept #0
    [2022-11-04 17:55:26.400]  INFO: server started on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.socket_options is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    Socket options
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/socket_options/main.cpp:16
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/socket_options/main.cpp:73: FAILED:
      REQUIRE_NOTHROW( response = do_request( create_request( body ) ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    [...]
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    fixed_size_chain_with_rejection (no_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:175
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:165: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    fixed_size_chain_with_rejection (test_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:181
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:165: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    fixed_size_chain_accept_in_middle (no_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:255
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:246: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    fixed_size_chain_accept_in_middle (test_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:261
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:246: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain (no_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:344
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:335: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.450] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.450] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.450]  INFO: init accept #0
    [2022-11-04 17:55:26.450]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain (test_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:350
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:335: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.451] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.451] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: init accept #0
    [2022-11-04 17:55:26.451]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain_with_rejection (no_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:434
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:424: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.451] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.451] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: init accept #0
    [2022-11-04 17:55:26.451]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain_with_rejection (test_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:440
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:424: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.451] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.451] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: init accept #0
    [2022-11-04 17:55:26.451]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain_accept_in_middle (no_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:523
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:514: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.451] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:26.451] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: init accept #0
    [2022-11-04 17:55:26.451]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    growable_size_chain_accept_in_middle (test_user_data)
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:529
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/handle_requests/chained_handlers/main.cpp:514: FAILED:
      REQUIRE_NOTHROW( response = do_request( request_str ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:26.451] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:26.451]  INFO: server closed on 127.0.0.1:8085
    ===============================================================================
    test cases: 12 | 12 failed
    assertions: 12 | 12 failed
    
    
          Start 34: _unit.test.run_on_thread_pool
    34/59 Test #34: _unit.test.run_on_thread_pool ........................Subprocess aborted***Exception:   1.01 sec
    [2022-11-04 17:55:26.453] TRACE: starting server on 127.0.0.1:8085
    Attempt 0 failed: resolve: Host not found (authoritative)
    [2022-11-04 17:55:26.453]  INFO: init accept #0
    [2022-11-04 17:55:26.453]  INFO: server started on 127.0.0.1:8085
    Attempt 1 failed: resolve: Host not found (authoritative)
    Attempt 2 failed: resolve: Host not found (authoritative)
    Attempt 3 failed: resolve: Host not found (authoritative)
    Attempt 4 failed: resolve: Host not found (authoritative)
    Attempt 5 failed: resolve: Host not found (authoritative)
    Attempt 6 failed: resolve: Host not found (authoritative)
    Attempt 7 failed: resolve: Host not found (authoritative)
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.run_on_thread_pool is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    on thread pool with break signals
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/run_on_thread_pool/main.cpp:47
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/run_on_thread_pool/main.cpp:102: FAILED:
      REQUIRE_NOTHROW( response = repeat_request( request_str ) )
    due to unexpected exception with message:
      Unable to get response after 8 attempts
    
    terminate called without an active exception
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/run_on_thread_pool/main.cpp:102: FAILED:
      {Unknown expression after the reported line}
    due to a fatal error condition:
      SIGABRT - Abort (abnormal termination) signal
    
    ===============================================================================
    test cases: 1 | 1 failed
    assertions: 2 | 2 failed
    
    
          Start 35: _unit.test.http_pipelining.sequence
    35/59 Test #35: _unit.test.http_pipelining.sequence ..................***Failed    0.00 sec
    [2022-11-04 17:55:27.460] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.460]  INFO: init accept #0
    [2022-11-04 17:55:27.460]  INFO: server started on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.http_pipelining.sequence is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    Simple HTTP piplining 
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:115
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:150: FAILED:
      REQUIRE_NOTHROW( response = do_request( pipelinedrequests ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.460] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.460]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:27.460] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.460]  INFO: init accept #0
    [2022-11-04 17:55:27.460]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Long sequesnces HTTP piplining
      simple order
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:240
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:251: FAILED:
      REQUIRE_NOTHROW( response = do_request( sout.str() ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.460] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.460]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:27.460] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: init accept #0
    [2022-11-04 17:55:27.461]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Long sequesnces HTTP piplining
      not direct order
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:262
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:280: FAILED:
      REQUIRE_NOTHROW( response = do_request( sout.str() ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.461] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:27.461] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: init accept #0
    [2022-11-04 17:55:27.461]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:27.461] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:27.461] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: init accept #0
    [2022-11-04 17:55:27.461]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Interrupt sequesnces HTTP piplining
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:294
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/sequence/main.cpp:333: FAILED:
      REQUIRE_NOTHROW( response = do_request( sout.str() ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.461] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.461]  INFO: server closed on 127.0.0.1:8085
    ===============================================================================
    test cases: 3 | 3 failed
    assertions: 4 | 4 failed
    
    
          Start 36: _unit.test.http_pipelining.timeouts
    36/59 Test #36: _unit.test.http_pipelining.timeouts ..................***Failed    0.00 sec
    [2022-11-04 17:55:27.463] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.463]  INFO: init accept #0
    [2022-11-04 17:55:27.463]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:27.463] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.463]  INFO: server closed on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.http_pipelining.timeouts is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    HTTP piplining timout
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/timeouts/main.cpp:50
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/http_pipelining/timeouts/main.cpp:50: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    ===============================================================================
    test cases: 1 | 1 failed
    assertions: 1 | 1 failed
    
    
          Start 37: _unit.test.sendfile
    37/59 Test #37: _unit.test.sendfile ..................................***Failed    0.00 sec
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.sendfile is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    simple sendfile
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:27
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:72: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.466] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.466]  INFO: init accept #0
    [2022-11-04 17:55:27.466]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    sendfile the same file several times
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:84
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:132: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.466] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.466]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    sendfile 2 files
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:144
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:219: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    -------------------------------------------------------------------------------
    sendfile offsets_and_size
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:279
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:353: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    -------------------------------------------------------------------------------
    sendfile chunks
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:392
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:446: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:27.468] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:27.468]  INFO: init accept #0
    [2022-11-04 17:55:27.468]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:27.468] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:27.468]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    sendfile with partially-read response
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:643
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/sendfile/main.cpp:643: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    ===============================================================================
    test cases: 10 |  4 passed | 6 failed
    assertions: 16 | 10 passed | 6 failed
    
    
          Start 38: _unit.test.router.easy_parser_router_dsl
    38/59 Test #38: _unit.test.router.easy_parser_router_dsl .............   Passed    0.00 sec
          Start 39: _unit.test.router.easy_parser_path_to_tuple
    39/59 Test #39: _unit.test.router.easy_parser_path_to_tuple ..........   Passed    0.00 sec
          Start 40: _unit.test.router.easy_parser_path_to_params
    40/59 Test #40: _unit.test.router.easy_parser_path_to_params .........   Passed    0.00 sec
          Start 41: _unit.test.router.express
    41/59 Test #41: _unit.test.router.express ............................   Passed    0.02 sec
          Start 42: _unit.test.router.express_router
    42/59 Test #42: _unit.test.router.express_router .....................   Passed    0.01 sec
          Start 43: _unit.test.router.express_router_user_data_simple
    43/59 Test #43: _unit.test.router.express_router_user_data_simple ....   Passed    0.01 sec
          Start 44: _unit.test.router.express_pcre
    44/59 Test #44: _unit.test.router.express_pcre .......................   Passed    0.01 sec
          Start 45: _unit.test.router.express_router_pcre
    45/59 Test #45: _unit.test.router.express_router_pcre ................   Passed    0.01 sec
          Start 46: _unit.test.router.express_pcre2
    46/59 Test #46: _unit.test.router.express_pcre2 ......................   Passed    0.01 sec
          Start 47: _unit.test.router.express_router_pcre2
    47/59 Test #47: _unit.test.router.express_router_pcre2 ...............   Passed    0.01 sec
          Start 48: _unit.test.transforms.zlib
    48/59 Test #48: _unit.test.transforms.zlib ...........................   Passed    2.59 sec
          Start 49: _unit.test.transforms.zlib_body_appender
    49/59 Test #49: _unit.test.transforms.zlib_body_appender .............***Failed    0.01 sec
    [2022-11-04 17:55:30.145] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.145]  INFO: init accept #0
    [2022-11-04 17:55:30.145]  INFO: server started on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.transforms.zlib_body_appender is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    restinio_controlled_output
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:19
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:118: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.145] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.145]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:30.146] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.146]  INFO: init accept #0
    [2022-11-04 17:55:30.146]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    user_controlled_output
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:235
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:367: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.146] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.146]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:30.147] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.147]  INFO: init accept #0
    [2022-11-04 17:55:30.147]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    chunked_output
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:522
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_appender/main.cpp:663: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.147] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.147]  INFO: server closed on 127.0.0.1:8085
    ===============================================================================
    test cases: 3 | 3 failed
    assertions: 3 | 3 failed
    
    
          Start 50: _unit.test.transforms.zlib_body_handler
    50/59 Test #50: _unit.test.transforms.zlib_body_handler ..............***Failed    0.00 sec
    [2022-11-04 17:55:30.149] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.149]  INFO: init accept #0
    [2022-11-04 17:55:30.149]  INFO: server started on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.transforms.zlib_body_handler is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    body_handler
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_handler/main.cpp:19
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_handler/main.cpp:88: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.150] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.150]  INFO: server closed on 127.0.0.1:8085
    [2022-11-04 17:55:30.150] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.150]  INFO: init accept #0
    [2022-11-04 17:55:30.150]  INFO: server started on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    body_handler void return
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_handler/main.cpp:129
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/transforms/zlib_body_handler/main.cpp:195: FAILED:
      REQUIRE_NOTHROW( response = do_request( request ) )
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.151] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.151]  INFO: server closed on 127.0.0.1:8085
    ===============================================================================
    test cases: 2 | 2 failed
    assertions: 2 | 2 failed
    
    
          Start 51: _unit.test.encoders
    51/59 Test #51: _unit.test.encoders ..................................   Passed    0.01 sec
          Start 52: _unit.test.from_string
    52/59 Test #52: _unit.test.from_string ...............................   Passed    0.04 sec
          Start 53: _unit.test.websocket.parser
    53/59 Test #53: _unit.test.websocket.parser ..........................   Passed    0.00 sec
          Start 54: _unit.test.websocket.validators
    54/59 Test #54: _unit.test.websocket.validators ......................   Passed    0.00 sec
          Start 55: _unit.test.ws_connection
    55/59 Test #55: _unit.test.ws_connection .............................***Failed    0.01 sec
    [2022-11-04 17:55:30.204] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.204]  INFO: init accept #0
    [2022-11-04 17:55:30.204]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.204] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.204]  INFO: server closed on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.ws_connection is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    Simple echo
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:267
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:267: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.204] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.204]  INFO: init accept #0
    [2022-11-04 17:55:30.204]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.204] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.204]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Ping
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:343
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:343: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.205] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.205]  INFO: init accept #0
    [2022-11-04 17:55:30.205]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.205] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.205]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Close
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:418
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:418: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.205] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.205]  INFO: init accept #0
    [2022-11-04 17:55:30.205]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.205] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.205]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Shutdown
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:485
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:485: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.206] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: init accept #0
    [2022-11-04 17:55:30.206]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.206] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Kill
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:552
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:552: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.206] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: init accept #0
    [2022-11-04 17:55:30.206]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.206] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid header
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:599
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:599: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.206] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: init accept #0
    [2022-11-04 17:55:30.206]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.206] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.206]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid payload
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:666
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:666: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.207] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.207]  INFO: init accept #0
    [2022-11-04 17:55:30.207]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.207] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.207]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Connection lost
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:732
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:732: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.207] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.207]  INFO: init accept #0
    [2022-11-04 17:55:30.207]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.207] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.207]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid opcode
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:803
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:803: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.207] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.207]  INFO: init accept #0
    [2022-11-04 17:55:30.207]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.208] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.208]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid payload, close on first err 1
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:908
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:908: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.208] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.208]  INFO: init accept #0
    [2022-11-04 17:55:30.208]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.208] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.208]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid payload, close on first err 2
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:1001
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:1001: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    [2022-11-04 17:55:30.208] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.208]  INFO: init accept #0
    [2022-11-04 17:55:30.208]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.208] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.208]  INFO: server closed on 127.0.0.1:8085
    -------------------------------------------------------------------------------
    Invalid payload, close on first err 3
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:1100
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/websocket/ws_connection/main.cpp:1100: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    ===============================================================================
    test cases: 12 | 12 failed
    assertions: 12 | 12 failed
    
    
          Start 56: _unit.test.file_upload
    56/59 Test #56: _unit.test.file_upload ...............................   Passed    0.00 sec
          Start 57: _unit.test.basic_auth
    57/59 Test #57: _unit.test.basic_auth ................................   Passed    0.00 sec
          Start 58: _unit.test.bearer_auth
    58/59 Test #58: _unit.test.bearer_auth ...............................   Passed    0.00 sec
          Start 59: _unit.test.socket_options_tls
    59/59 Test #59: _unit.test.socket_options_tls ........................***Failed    0.01 sec
    [2022-11-04 17:55:30.228] TRACE: starting server on 127.0.0.1:8085
    [2022-11-04 17:55:30.228]  INFO: init accept #0
    [2022-11-04 17:55:30.228]  INFO: server started on 127.0.0.1:8085
    [2022-11-04 17:55:30.228] TRACE: closing server on 127.0.0.1:8085
    [2022-11-04 17:55:30.228]  INFO: server closed on 127.0.0.1:8085
    
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    _unit.test.socket_options_tls is a Catch v2.13.8 host application.
    Run with -? for options
    
    -------------------------------------------------------------------------------
    Socket_options TLS
    -------------------------------------------------------------------------------
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/socket_options_tls/main.cpp:18
    ...............................................................................
    
    /tmp/guix-build-restinio-0.6.15.drv-0/source/dev/test/socket_options_tls/main.cpp:18: FAILED:
    due to unexpected exception with message:
      resolve: Host not found (authoritative)
    
    ===============================================================================
    test cases: 2 | 1 passed | 1 failed
    assertions: 2 | 1 passed | 1 failed
    
    
    
    53% tests passed, 28 tests failed out of 59
    
    Total Test time (real) =   3.86 sec
    
    The following tests FAILED:
             13 - _unit.test.socket_options (Failed)
             15 - _unit.test.handle_requests.method (Failed)
             16 - _unit.test.handle_requests.echo_body (Failed)
             17 - _unit.test.handle_requests.timeouts (Failed)
             18 - _unit.test.handle_requests.throw_exception (Failed)
             19 - _unit.test.handle_requests.slow_transmit (Failed)
             20 - _unit.test.handle_requests.user_controlled_output (Subprocess aborted)
             21 - _unit.test.handle_requests.chunked_output (Subprocess aborted)
             22 - _unit.test.handle_requests.output_and_buffers (Failed)
             23 - _unit.test.handle_requests.notificators (Failed)
             24 - _unit.test.handle_requests.remote_endpoint (Failed)
             25 - _unit.test.handle_requests.connection_state (Failed)
             26 - _unit.test.handle_requests.ip_blocker (Failed)
             27 - _unit.test.handle_requests.upgrade (Failed)
             28 - _unit.test.handle_requests.chunked_input (Failed)
             29 - _unit.test.handle_requests.acceptor_post_bind_hook (Failed)
             30 - _unit.test.handle_requests.incoming_msg_limits (Failed)
             31 - _unit.test.handle_requests.connection_count_limit (Subprocess aborted)
             32 - _unit.test.handle_requests.user_data_simple (Failed)
             33 - _unit.test.handle_requests.chained_handlers (Failed)
             34 - _unit.test.run_on_thread_pool (Subprocess aborted)
             35 - _unit.test.http_pipelining.sequence (Failed)
             36 - _unit.test.http_pipelining.timeouts (Failed)
             37 - _unit.test.sendfile (Failed)
             49 - _unit.test.transforms.zlib_body_appender (Failed)
             50 - _unit.test.transforms.zlib_body_handler (Failed)
             55 - _unit.test.ws_connection (Failed)
             59 - _unit.test.socket_options_tls (Failed)
    Errors while running CTest
    make: *** [Makefile:139: test] Error 8
    
    Test suite failed, dumping logs.
    error: in phase 'check': uncaught exception:
    %exception #<&invoke-error program: "make" arguments: ("test" "-j" "24") exit-status: 2 term-signal: #f stop-signal: #f> 
    phase `check' failed after 3.9 seconds
    command "make" "test" "-j" "24" failed with status 2
    

    It seems most test fails due to failing to resolve the host name, although I only see localhost (127.0.0.1) being used, so it should work (there is networking support for the loopback interface in the Guix build environment).

    Would you have any idea on how to make it work?

    Thanks!

    opened by Apteryks 19
  • RESTinio CMake issues

    RESTinio CMake issues

    This is an offshoot from #166. I normally use a modified version of RESTinio to suit my main project. Obviously, for a test case I am trying to set-up vanilla RESTinio to see if the error persists.

    However, the CMakeLists contains several errors that make it pretty hard to use. The whole IF (RESTINIO_MASTER_PROJECT) means RESTinio cannot be used properly via add_subfolder. I generally always prefer to use find_package, and I know that RESTinio provides CMake config files, but given that it's not a library commonly available in many package managers, add_subdirectory would be a pretty common way to include it in a project.

    The issue is, when included like that, RESTINIO_MASTER_PROJECT is not defined. When that happens, RESTinio does not even try to look for FMT, so then restinio/CMakeLists.txt produces an error because it's trying to link against a non-existent target, and similar errors will likely occur for most other dependencies.

    If one just removes that check, http_parser is still a problem. If RESTINIO_FIND_DEPS is on but USE_EXTERNAL_HTTP_PARSER isn't, RESTinio tries to use find_package to find a library that hasn't been installed anywhere because it's included in RESTinio. The correct behavior would be to use add_subdirectory(nodejs/http_parser) as is being done when RESTINIO_FIND_DEPS is off. It might also be a good idea to have USE_EXTERNAL_HTTP_PARSER be the default.

    opened by Lord-Kamina 6
  • Problem with string literals in router.

    Problem with string literals in router.

    I was previously using the express router, configured something like this:

    	router->http_get(u8R"--(/:path(.*))--", [this](auto request, auto params){
    		do stuff
    	});
    

    Since updating to 0.6.17 (using libfmt9), I'm getting the following error: "non-escaped bracket ')' at pos 9: may be unmatched group finish"

    If I disregard the fact that this is a raw string and thus nothing should need to be escaped, the error goes away but my rules don't match any request and they all end unhandled.

    opened by Lord-Kamina 16
  • [idea] Deprecation of RESTINIO_FIND_DEPS in favor of RESTINIO_EXTERNAL_FMT, RESTINIO_EXTERNAL_CATCH2 and so on

    [idea] Deprecation of RESTINIO_FIND_DEPS in favor of RESTINIO_EXTERNAL_FMT, RESTINIO_EXTERNAL_CATCH2 and so on

    Dependency management in CMake scripts started from very simple things but evolved to rather complex scheme that I don't understand fully. Now we have RESTINIO_FIND_DEPS with additional case RESTINIO_USE_EXTERNAL_HTTP_PARSER (and I don't get an idea of RESTINIO_FIND_DEPS=ON and RESTINIO_USE_EXTERNAL_HTTP_PARSER=OFF case) plus RESTINIO_USE_EXTERNAL_*_LITE options.

    Maybe it's better to remove RESTINIO_FIND_DEPS and use new options like RESTINIO_USE_EXTERNAL_FMT, RESTINIO_USE_EXTERNAL_HTTP_PARSER (+RESTINIO_USE_EXTERNAL_UNOFFICIAL_HTTP_PARSER), RESTINIO_USE_EXTERNAL_CATCH2 and other.

    I think that change should lead to change a version number, e.g. 0.7.0 instead of 0.6.15. And that version change can be done during adopting to Catch2 v3.

    v3 of Catch2 is no more single-header header-only library and switching to v3 may require some refactoring of RESTinio's test. It's a significant change to be reflected in RESTinio's version bump.

    opened by eao197 0
  • Upgrade Catch2 to v3

    Upgrade Catch2 to v3

    Catch2 library is used as unit-test framework in the RESTinio development.

    Since v3 Catch2 is no more header-only library: https://github.com/catchorg/Catch2/releases/tag/v3.0.1

    RESTinio have to be updated to Catch2 after Catch2-v3 will be stabilized and got a few correcting releases.

    opened by eao197 0
Releases(v.0.6.17)
  • v.0.6.17(Sep 6, 2022)

    Since v.0.6.17 RESTinio can be used with fmtlib in FMT_ENFORCE_COMPILE_STRING mode. In this mode FMT_STRING macro has to be used for format string in C++11/14/17 for compile-time checking of format string validity.

    Now RESTinio checks the presence of FMT_ENFORCE_COMPILE_STRING and uses FMT_STRING when it's required.

    NOTE. FMT_ENFORCE_COMPILE_STRING has to be defined before inclusion of any of RESTinio's headers.

    fmtlib-9.1.0 in now used inside RESTinio (and included in restinio-0.6.17-full.* archives).

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.17-full.tar.bz2(1.61 MB)
    restinio-0.6.17-full.zip(3.03 MB)
    restinio-0.6.17.tar.bz2(526.32 KB)
    restinio-0.6.17.zip(957.47 KB)
  • v.0.6.16(Jul 12, 2022)

    This release adapts RESTinio to fmtlib-9.0.0.

    Since v.0.6.16 RESTinio can be used with fmtlib-8 or fmtlib-9, but fmtlib-8 is still used in RESTinio development.

    NOTE: restinio-0.6.14-full.* archives contain asio-1-21-1, fmt-8.1.1 and catch-2.13.9. Versions of 3rd party libraries in restinio/third_party updated to the latest versions:

    expected-lite at commit 34524d46e538f1e6ed114d8f8409f7cd173d96e6. optional-lite at commit ea502a6472c85dbc0174764df218a0c3443c6772. string-view-lite at commit f7aca36f5caa05e451f6887aa707df89197e6de6. variant-lite at commit f1af3518e4c28f12b09839b9d2ee37984cbf137a.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.16-full.tar.bz2(1.60 MB)
    restinio-0.6.16-full.zip(3.02 MB)
    restinio-0.6.16.tar.bz2(526.10 KB)
    restinio-0.6.16.zip(951.02 KB)
  • v.0.6.15(May 26, 2022)

    This is a maintenance release.

    A fix for CMake script for case when RESTINIO_FIND_DEPS=ON and RESTINIO_FMT_HEADER_ONLY=OFF (#159).

    Usage of std::aligned_storage_t in implementation of writable_item_t has been removed (it's deprecated in C++23).

    In some places std::launder is used (if available) to avoid UB accessing a pointer after placement new.

    NOTE: restinio-0.6.14-full.* archives contain asio-1-21-1, fmt-8.1.1 and catch-2.13.9. Versions of 3rd party libraries in restinio/third_party weren't upgraded.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.15-full.tar.bz2(1.60 MB)
    restinio-0.6.15-full.zip(3.02 MB)
    restinio-0.6.15.tar.bz2(525.01 KB)
    restinio-0.6.15.zip(949.67 KB)
  • v.0.6.14(Nov 19, 2021)

  • v.0.6.13(Dec 28, 2020)

    This version introduces a couple of new big features and contains several changes some of that can affect existing code.


    A new value not_handled added to request_handling_status_t enumeration (+ new helper function request_not_handled()). This value should be returned if a request-handler doesn't accept nor reject the current request and some other request-handler should be tried (if such a handler exists). If all request-handlers called for request processing return not_handled then RESTinio treats that value as rejected.


    It's possible now to incorporate some additional (extra) data into a request-object. To do so a user has to perform the following steps:

    Define a type for holding such an extra data:

    struct per_request_data {
      user_indentity user_info_;
      ...
    };
    

    Define a extra-data-factory that should look like:

    struct my_extra_data_factory {
      using data_t = per_request_data;
      void make_within(restinio::extra_data_buffer_t<data_t> buf) {
        new(buf.get()) data_t{};
      }
    };
    

    Or, if extra-data-factory is a simple and stateless object as shown above:

    using my_extra_data_factory = restinio::simple_extra_data_factory_t<per_request_data>;
    

    Specify my_extra_data_factory in server's traits:

    struct my_traits : public restinio::default_traits_t {
      using extra_data_factory_t = my_extra_data_factory;
    };
    

    Change the format of request-handlers this way:

    restinio::request_handling_status_t request_handler(
      const restinio::generic_request_handle_t<per_request_data> & req);
    
    // or
    
    restinio::request_handling_status_t request_handler(
      const restinio::generic_request_handle_t<my_extra_data_factory::data_t> & req);
    

    Extra-data is available inside a request-handler via new method request_t::extra_data:

    restinio::request_handling_status_t request_handler(
      const restinio::generic_request_handle_t<per_request_data> & req)
    {
      auto & ed = req->extra_data();
      ...
    }
    

    See the documentation for more details.


    It's possible now to bind several synchronous request-handlers into a chain (somewhat similar to ExpressJS's middleware):

    #include <restinio/all.hpp>
    #include <restinio/sync_chain/fixed_size.hpp>
    
    auto incoming_req_logger(const restinio::request_handle_t & req)
    {
      ... // Perform logging.
      // Allow the passing of the request to the next handler.
      return restinio::request_not_handled();  
    }
    
    auto mandatory_fields_checker(const restinio::request_handle_t & req)
    {
      ... // Perform all necessary checks.
      if(!ok) {
        // Negative response has to be sent.
        return req->create_response(restinio::status_bad_request())
          ...
          .done();
      }
      // Allow the passing of the request to the next handler.
      return restinio::request_not_handled();  
    }
    
    auto permissions_checker(const restinio::request_handle_t & req)
    {
      ... // Check user credentials and permissions.
      if(!ok) {
        // Negative response has to be sent.
        return req->create_response(restinio::status_unauthorized())
          ...
          .done();
      }
      // Allow the passing of the request to the next handler.
      return restinio::request_not_handled();
    }
    
    auto actual_processor(const restinio::request_handle_t & req)
    {
      ... // Do actual request processing.
      return restinio::request_accepted();
    }
    
    struct my_traits : public restinio::default_traits_t {
      // Change the type of request handler.
      using request_handler_t = restinio::sync_chain::fixed_size_chain_t<4>;
    };
    
    restinio::run(restinio::on_this_thread<my_traits>()
      .port(...)
      .address(...)
      .request_handler(
        // Enumerate all handlers in the chain in the order of invocation.
        incoming_req_logger,
        mandatory_fields_checker,
        permissions_checker,
        actual_processor)
      ...
    );
    

    When a new incoming request will be parsed the RESTinio will call incoming_req_logger, then mandatory_req_logger, then (if necessary) permissions_checker, and only then (if necessary) actual_processor.

    See the documentation for more details.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.13-full.tar.bz2(1.49 MB)
    restinio-0.6.13-full.zip(2.78 MB)
    restinio-0.6.13.tar.bz2(524.53 KB)
    restinio-0.6.13.zip(947.75 KB)
  • v.0.6.12(Nov 10, 2020)

    A new method incoming_http_msg_limits added to restinio::server_settings_t. This method allows to set up limits for the maximum length of various parts of an incoming HTTP message (like URL, HTTP-field’s name and value):

    struct my_traits : public restinio::default_traits_t { ... };
    
    restinio::server_settings_t<my_traits> settings;
    settings.incoming_http_msg_limits(
       restinio::incoming_http_msg_limits_t{}
          .max_url_size(8000u)
          .max_field_name_size(2048u)
          .max_field_value_size(4096u)
    );
    ...
    auto server = restinio::run_async(
       restinio::own_io_context(),
       std::move(settings),
       std::thread::hardware_concurrency());
    

    A possibility to limit the number of parallel connection has been added:

    struct my_traits : public restinio::default_traits_t {
       // Force the usage of connection count limiter.
       static constexpr bool use_connection_count_limiter = true;
    };
    
    restinio::server_settings_t<my_traits> settings;
    settings.max_parallel_connections(1000u);
    ...
    auto server = restinio::run_async(
       restinio::own_io_context(),
       std::move(settings),
       std::thread::hardware_concurrency());
    

    A support for SObjectizer 5.6/5.7 has been added. Now RESTinio can be user either with SObjectizer 5.5 and SObjectizer 5.6/5.7. The version of SObjectizer is detected automatically. But if a user wants to use SObjectizer 5.6/5.7 he/she should set C++ standard to C++17 manually.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.12-full.tar.bz2(1.40 MB)
    restinio-0.6.12-full.zip(2.58 MB)
    restinio-0.6.12.tar.bz2(515.51 KB)
    restinio-0.6.12.zip(919.51 KB)
  • v.0.6.11(Oct 22, 2020)

    Conversion functions passed to restinio::easy_parser::convert can now return expected_t<T, error_reason_t> as well as just T. Returning expected_t<T, error_reason_t> allows to report conversion errors without throwing an exception. This is a fix for #99.

    A new overload for restinio::server_settings_t::address() method. The new overload accepts an instance of asio::ip::address (or boost::asio::ip::address). This is a fix for #100.

    A new optional post-bind hook added. This hook is called just after a succesful return from bind() for server’s acceptor. A reference to asio::ip::tcp::acceptor is passed to that hook. This new hook can be used for application-specific tuning of bound acceptor or to gathering some information about the acceptor. This is a fix for #126. For example, this code snippet shows how RESTinio server can be started on a random port assigned by the Operating System:

    std::promise<unsigned short> port_promise; // For getting the port.
    auto server = restinio::run_async(
          restinio::use_own_context(),
          restinio::server_settings_t{}
             .address("localhost")
             .port(0u) // Zero means that port will be assigned by the OS.
             .acceptor_post_bind_hook(
                [&port_promise](asio::ip::tcp::acceptor & acceptor) {
                   // Gathering the actual port number.
                   port_promise.set_value(acceptor.local_endpoint().port());
                })
             .request_handler(...),
          4u);
    // Now we can safely get the actual port number from the promise.
    const auto actual_port = port_promise.get_future().get();
    
    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.11-full.tar.bz2(1.39 MB)
    restinio-0.6.11-full.zip(2.56 MB)
    restinio-0.6.11.tar.bz2(509.22 KB)
    restinio-0.6.11.zip(902.35 KB)
  • v.0.6.10(Aug 20, 2020)

  • v.0.6.9(Aug 13, 2020)

    Now RESTinio works with Asio 1.17. Version 0.6.9 can be used with Asio 1.12, 1.14, 1.16, and 1.17.

    Support for incoming requests with chunked encoding has been added. Previous versions of RESTinio didn’t support such requests, HTTP 501 error was returned. Since v.0.6.9 RESTinio accepts such requests and glues all chunks together into the one body. Information about an individual chunk is preserved and is available via request_t::chunked_input_info.

    Since v.0.6.9 the value OFF for CMake-option RESTINIO_ALLOW_SOBJECTIZER is handled differently: all tests/examples/benchmarks those require SObjectizer as a dependency won't be compiled. All other tests/examples will be compiled as usual. There is also a new CMake-option RESTINIO_USE_EXTERNAL_SOBJECTIZER.

    New methods for http_header_fields_t class: remove_all_of and add_field.

    New helpers for parsing the following HTTP-fields: Connection, Host, Transfer-Encoding.

    New tools for easy_parser and HTTP-field parsers: expected_token_p, expected_caseless_token_p, symbol_from_range_p, caseless_exact, caseless_exact_p.

    There are also some thoughts about the future development of RESTinio.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.9-full.tar.bz2(1.38 MB)
    restinio-0.6.9-full.zip(2.54 MB)
    restinio-0.6.9.tar.bz2(504.94 KB)
    restinio-0.6.9.zip(888.40 KB)
  • v.0.6.8.1(Jun 24, 2020)

  • v.0.6.8(May 15, 2020)

    Implementation of extraction of Bearer authentification parameters fixed. Now it looks like:

    #include <restinio/all.hpp>
    #include <restinio/http_field_parser/bearer_auth.hpp>
    ...
    auto on_request(const restinio::request_handle_t & req) {
       using namespace restinio::http_field_parsers::bearer_auth;
       const auto auth_params = try_extract_params(*req,
             restinio::http_field::authorization);
       if(auth_params) { // Parameters successfully extracted.
          if(is_valid_user(auth_params->token)) {
             ...
          }
       }
       ...
    }
    

    New helper function try_parse_field for simplification of HTTP-fields parsing added:

    #include <restinio/all.hpp>
    #include <restinio/helpers/http_fields_parsers/try_parse_field.hpp>
    #include <restinio/helpers/http_fields_parsers/accept.hpp>
    ...
    auto on_request(const restinio::request_handle_t & req) {
       using namespace restinio::http_field_parsers;
       // Try to get and parse the value of `Accept` header.
       const auto parse_result = try_parse_field<accept_value_t>(
             req, restinio::http_field::accept);
       if(const auto * value =
             restinio::get_if<accept_value_t>(&parse_result)) {
          // Value of the field is successfully parsed.
          ... // Some usage of parsed value.
       }
    }
    

    Several new overloads for try_extract_params functions from restinio::http_field_parsers::basic_auth and restinio::http_field_parsers::bearer_auth namespaces. They allow to work with several authentication schemes after the parsing of Authorization (Proxy-Authorization) field:

    auto on_request(const restinio::request_handle_t & req) {
       using namespace restinio::http_field_parsers;
    
       const auto field = try_parse_field<authorization_value_t>(
             req, restinio::http_field::authorization);
       if(const auto * auth = restinio::get_if<authorization_value_t>(field)) {
          // We have valid Authorization field value.
          if("basic" == auth->auth_scheme) {
             // Basic authentification scheme should be used.
             using namespace restinio::http_field_parsers::basic_auth;
             const auto params = try_extract_params(auth->auth_params);
             if(params) { // Parameters successfully extracted.
                if(is_valid_user(params->username, params->password)) {
                   ...
                }
             }
             ...
          }
          else if("bearer" == auth->auth_scheme) {
             // Bearer authentification scheme should be used.
             using namespace restinio::http_field_parsers::bearer_auth;
             const auto params = try_extract_params(auth->auth_params);
             if(auth_params) { // Parameters successfully extracted.
                if(is_valid_user(auth_params->token)) {
                   ...
                }
             }
             ...
          }
          else {
             ... // Handling of different schemes.
          }
       }
    }
    
    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.8-full.tar.bz2(1.38 MB)
    restinio-0.6.8-full.zip(2.52 MB)
    restinio-0.6.8.tar.bz2(477.44 KB)
    restinio-0.6.8.zip(870.71 KB)
  • v.0.6.7.1(May 12, 2020)

    New helpers for extraction of parameters for Bearer authentication (thanks to @prince-chrismc):

    #include <restinio/all.hpp>
    #include <restinio/http_field_parser/bearer_auth.hpp>
    ...
    auto on_request(const restinio::request_handle_t & req) {
       using namespace restinio::http_field_parsers::bearer_auth;
       const auto auth_params = try_extract_params(*req,
             restinio::http_field::authorization);
       if(auth_params) { // Parameters successfully extracted.
          if(is_valid_user(auth_params->client_id, auth_params->client_secret)) {
             ...
          }
       }
       ...
    }
    
    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.7.1-full.tar.bz2(1.38 MB)
    restinio-0.6.7.1-full.zip(2.52 MB)
    restinio-0.6.7.1.tar.bz2(475.91 KB)
    restinio-0.6.7.1.zip(869.71 KB)
  • v.0.6.7(May 11, 2020)

    New configuration options for CMake-based builds: RESTINIO_USE_EXTERNAL_EXPECTED_LITE, RESTINIO_USE_EXTERNAL_OPTIONAL_LITE, RESTINIO_USE_EXTERNAL_STRING_VIEW_LITE, RESTINIO_USE_EXTERNAL_VARIANT_LITE.

    New helper function run_async that allows to run an instance of RESTinio's server on a separate thread-pool or thread:

    int main() {
       auto server = restinio::run_async(
          // Asio's io_context to be used.
          // HTTP-server will use own Asio's io_context object.
          restinio::own_io_context(),
          // The settings for the HTTP-server.
          restinio::server_settings_t{}
             .address("127.0.0.1")
             .port(8080)
             .request_handler(...),
          // The size of thread-pool for the HTTP-server.
          16);
       // If we are here and run_async doesn't throw then HTTP-server
       // is started.
    
       ... // Some other actions.
    
       // No need to stop HTTP-server manually. It will be automatically
       // stopped in the destructor of `server` object.
    }
    

    New helpers for working with HTTP-fields like Authorization and Proxy-Authorization, and helpers for the extraction of parameters for Basic authentication:

    #include <restinio/all.hpp>
    #include <restinio/http_field_parser/basic_auth.hpp>
    ...
    auto on_request(const restinio::request_handle_t & req) {
       using namespace restinio::http_field_parsers::basic_auth;
       const auto auth_params = try_extract_params(*req,
             restinio::http_field::authorization);
       if(auth_params) { // Parameters successfully extracted.
          if(is_valid_user(auth_params->username, auth_params->password)) {
             ...
          }
       }
       ...
    }
    

    Some bug fixes.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.7-full.tar.bz2(1.36 MB)
    restinio-0.6.7-full.zip(2.49 MB)
    restinio-0.6.7.tar.bz2(474.76 KB)
    restinio-0.6.7.zip(862.81 KB)
  • v.0.6.6(Apr 13, 2020)

    An experimental type-safe request-router that can be used as a type-safe alternative of express-like router with additional compile-time checking. That new easy_parser_router allows to write:

    namespace epr = restinio::router::easy_parser_router;
    router->http_get(
       epr::path_to_params("/api/v1/posts/",
          epr::non_negative_decimal_number_p<std::uint64_t>(),
          "/revisions/",
          epr::non_negative_decimal_number_p<std::int16_t>()),
       [](const auto & req, std::uint64_t post_id, std::int16_t rev_id) {...});
    

    instead of:

    router->http_get("/api/v1/posts/:post_id(\d{1,10})/revisions/:rev_id(\d{1,5})",
       [](const auto & req, const auto & params) {
          const auto post_id = restinio::cast_to<std::uint64_t>(params["post_id"]);
          const auto rev_id = restinio::cast_to<std::int16_t>(params["rev_id"]);
       });
    

    More information about the new router can be found here.


    An ability to specify a request handler for several HTTP-methods (see #82 for a motivation). It's possible now to write routes like:

    router->add_handler(
       restinio::router::any_of_methods(
          restinio::http_method_lock(), restinio::http_method_unlock()),
       "/api/v1/resources/:rid",
       [](const auto & req, const auto & params) {...});
    
    router->add_handler(
       restinio::router::none_of_methods(
          restinio::http_method_get(), restinio::http_method_post(), restinio::http_method_delete()),
       "/api/v1/users/:user",
       [](const auto & req, const auto & params) {...});
    

    Those new method matchers can be used for express-like or easy_parser-based routers.

    More information about method matchers is here.


    New RESTINIO_FMT_HEADER_ONLY CMake option added. It allows to use the compiled version of fmtlib with RESTinio. Thanks for @prince-chrismc for a patch.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.6-full.tar.bz2(1.35 MB)
    restinio-0.6.6-full.zip(2.48 MB)
    restinio-0.6.6.tar.bz2(468.81 KB)
    restinio-0.6.6.zip(850.11 KB)
  • v.0.6.5(Feb 25, 2020)

    Set of symbols supported by restinio::parse_query_traits::javascript_compatible is extended (#76).

    Addition of restinio::parse_query_traits::x_www_form_urlencoded, restinio::parse_query_traits::relaxed trais.

    Introduction of try_parse_query function.

    Some functions that work with query-string and URI (like parse_query, try_parse_query) now do basic control of the validity of UTF-8 sequences represented as percent-encoded characters.

    New RESTINIO_USE_EXTERNAL_HTTP_PARSER option for CMake-based builds.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.5-full.tar.bz2(1.32 MB)
    restinio-0.6.5-full.zip(2.45 MB)
    restinio-0.6.5.tar.bz2(455.82 KB)
    restinio-0.6.5.zip(816.15 KB)
  • v.0.6.3.1(Feb 7, 2020)

  • v.0.6.3(Jan 31, 2020)

  • v.0.6.2(Dec 12, 2019)

  • v.0.6.1(Nov 13, 2019)

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.1-full.tar.bz2(1.27 MB)
    restinio-0.6.1-full.zip(2.32 MB)
    restinio-0.6.1.tar.bz2(437.77 KB)
    restinio-0.6.1.zip(763.05 KB)
  • v.0.6.0(Aug 29, 2019)

    • API for connection state listeners changed. NOTE. This is a breaking change!
    • Connection state listener has access to TLS-related params for TLS-connections.
    • Some methods/functions now use [[nodiscard]] if it supported by C++ compiler.
    • Macros RESTINIO_VERSION, RESTINIO_VERSION_MAJOR, RESTINIO_VERSION_MINOR, RESTINIO_VERSION_PATCH, RESTINIO_VERSION_MAKE added.
    • Fresh version of externals: Asio 1.14.0 (Asio 1.12 is also supported), optional-lite 3.2.0, variant-lite 1.2.2. Support for fmt 6.0.0 (fmt 5.3.0 is still used by default).

    The documentation for RESTinio v.0.6 can be found here (Developer's Guide) and here (API Reference Manual).

    Please note that since Aug 2019 the development of RESTinio is moved to GitHub. Our old Hg-repositories on BitBucket are abandoned.

    Source code(tar.gz)
    Source code(zip)
    restinio-0.6.0-full.tar.bz2(1.23 MB)
    restinio-0.6.0-full.zip(2.25 MB)
    restinio-0.6.0.tar.bz2(396.28 KB)
    restinio-0.6.0.zip(691.05 KB)
Owner
Stiffstream
We create and support OpenSource-tools to make C++ development easier
Stiffstream
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 958 Jan 3, 2023
Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services.

Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services. The project is unique among realtime push solutions in that it is designed to address the needs of API creators. Pushpin is transparent to clients and integrates easily into an API stack.

Fanout 3.2k Jan 2, 2023
Small and fast cross-platform networking library, with support for messaging, IPv6, HTTP, SSL and WebSocket.

frnetlib Frnetlib, is a cross-platform, small and fast networking library written in C++. There are no library dependencies (unless you want to use SS

Fred Nicolson 23 Nov 25, 2022
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 9k Jan 1, 2023
cuehttp is a modern c++ middleware framework for http(http/https)/websocket(ws/wss).

cuehttp 简介 cuehttp是一个使用Modern C++(C++17)编写的跨平台、高性能、易用的HTTP/WebSocket框架。基于中间件模式可以方便、高效、优雅的增加功能。cuehttp基于boost.asio开发,使用picohttpparser进行HTTP协议解析。内部依赖了nl

xcyl 29 Dec 17, 2022
H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server

H2O - an optimized HTTP server with support for HTTP/1.x, HTTP/2 and HTTP/3 (experimental) Copyright (c) 2014-2019 DeNA Co., Ltd., Kazuho Oku, Tatsuhi

H2O 10.2k Dec 30, 2022
A cross-platform network learning demos. Like high-performance http server

Network-Learn A cross-platform network learning demos (toys). And I try not to use 3rd-party libraries. Welcome to try it out and leave your comments.

Ho 229 24 Sep 6, 2022
BingBing 60 Dec 15, 2022
websocket and http client and server library, coming with ws, a command line swiss army knife utility

Hello world IXWebSocket is a C++ library for WebSocket client and server development. It has minimal dependencies (no boost), is very simple to use an

Machine Zone, Inc. 369 Jan 5, 2023
A Lightweight and fully asynchronous WebSocket client library based on libev

libuwsc(中文) A Lightweight and fully asynchronous WebSocket client library based on libev for Embedded Linux. And provide Lua-binding. Why should I cho

Jianhui Zhao 285 Dec 24, 2022
A collection of C++ HTTP libraries including an easy to use HTTP server.

Proxygen: Facebook's C++ HTTP Libraries This project comprises the core C++ HTTP abstractions used at Facebook. Internally, it is used as the basis fo

Facebook 7.7k Jan 4, 2023
A C++ async HTTP client library to use in asynchronous applications while communicating with REST services.

libashttp An asynchronous HTTP library using Boost.ASIO as the backend. This project is licensed under: Usage Here is a example usage which is taken f

Tolga Hoşgör 53 Dec 17, 2022
A simple tcp tunnel on c using sockets Right now it only supports linux systems

A simple tcp tunnel on c using sockets Right now it only supports linux systems build BY MAKE mkdir build make cd build ./tunnel.o <localport> <rem

notaweeb 8 Sep 20, 2021
Cross-platform, single .h file HTTP server (Windows, Linux, Mac OS X)

EWS - Single .h File C Embeddable Web Server Latest Version: 1.1.4 released September 9, 2021 Supported platforms: Linux, Mac OS X, Windows License: B

Forrest Heller 84 Dec 19, 2022
Inter-process communication library to enable allocation between processes/threads and send/receive of allocated regions between producers/consumer processes or threads using this ipc buffer.

This is a relatively simple IPC buffer that allows multiple processes and threads to share a dynamic heap allocator, designate "channels" between processes, and share that memory between producer/consumer pairs on those channels.

RaftLib 8 Aug 20, 2022
modern c++(c++17), cross-platform, header-only, easy to use http framework

cinatra--一个高效易用的c++ http框架 English | 中文 目录 使用cinatra常见问题汇总(FAQ) cinatra简介 如何使用 快速示例 性能测试 注意事项 roadmap 联系方式 cinatra简介 cinatra是一个高性能易用的http框架,它是用modern

qicosmos 1.4k Dec 30, 2022
HTTP and WebSocket built on Boost.Asio in C++11

HTTP and WebSocket built on Boost.Asio in C++11 Branch Linux/OSX Windows Coverage Documentation Matrix master develop Contents Introduction Appearance

Boost.org 3.6k Jan 4, 2023
Simple embeddable C++11 async tcp,http and websocket serving.

net11 Simple embeddable C++11 async tcp,http and websocket serving. What is it? An easily embeddable C++11 networking library designed to make buildin

Jonas Lund 9 Mar 28, 2020
Gromox - Groupware server backend with MAPI/HTTP, RPC/HTTP, IMAP, POP3 and PHP-MAPI support for grommunio

Gromox is the central groupware server component of grommunio. It is capable of serving as a replacement for Microsoft Exchange and compatibles. Conne

grommunio 139 Dec 26, 2022