Modern C++ REST Client library

Overview

Introduction to the restc-cpp C++ library

The magic that takes the pain out of accessing JSON API's from C++

What it does:

  • It formulates a HTTP request to a REST API server. Then, it transforms the JSON formatted payload in the reply into a native C++ object (GET).
  • It Serialize a native C++ object or a container of C++ objects into a JSON payload and send it to the REST API server (POST, PUT).
  • It formulates a HTTP request to the REST API without serializing any data in either direction (typically DELETE).
  • It uploads a stream of data, like a file, to a HTTP server.
  • It downloads a stream of data, like a file or an array of JSON objects, from a HTTP server.

That's basically it. It does not solve world hunger. It make no attempts to be a C++ framework.

You can use it's single components, like the powerful C++ HTTP Client to send and receive non-JSON data as a native C++ replacement for libcurl. You can use the template code that transforms data between C++ and JSON for other purposes (for example in a REST API SERVER) - but the library is designed and implemented for the single purpose of using C++ to interact efficiently and effortless with external REST API servers.

The library is written by Jarle (jgaa) Aase, a senior freelance C++ developer with roughly 30 years of experience in software development.

Design Goals

The design goal of this project is to make external REST API's simple and safe to use in C++ projects, but still fast and memory efficient.

Another goal was to use coroutines for the application logic that sends data to or pulls data from the REST API servers. This makes the code easy to write and understand, and also simplifies debugging and investigation of core dumps. In short; the code executes asynchronously, but there are no visible callbacks or completion functions. It looks like crystal clear, old fashion, single threaded sequential code (using modern C++ language). You don't sacrifice code clearness to achieve massive parallelism and high performance. Coroutines was a strong motivation to write a new C++ HTTP Client from scratch. To see how this actually works, please see the modern async cpp example).

Finally, in a world where the Internet is getting increasingly dangerous, and all kind of malicious parties, from your own government to international Mafia (with Putin in Moscow and the Clown in the White House, the differences is blurring out), search for vulnerabilities in your software stack to snoop, ddos, intercept and blackmail you and your customers/users - I have a strong emphasis on security in all software projects I'm involved in. I have limited the dependencies on third party libraries as much as I could (I still use OpenSSL which is a snakes nest of of yet undisclosed vulnerabilities - but as of now there are no alternatives that works out of the box with boost::asio). I have also tried to imagine any possible way a malicious API server could try to attack you (by exploiting or exceeding local resources - like sending a malicious compressed package that expands to a petabyte of zeros) and designed to detect any potential problems and break out of it by throwing an exception as soon as possible.

Why?

In the spring of 2016 I was asked to implement a SDK for a REST API in several languages. For Python, Java and Ruby it was trivial to make a simple object oriented implementation. When I started planning the C++ implementation of the SDK, I found no suitable, free libraries. I could not even find a proper HTTP Client implementation(!). I could have solved the problem using QT - but i found it overkill to use a huge GUI framework for C++ code that are most likely to run in high performance servers - and that may end up in projects using some other C++ framework that can't coexist with QT.

Many years ago I designed and implemented a C++ REST Client for an early version of Amazon AWS using libcurl - and - well, I had no strong urge to repeat that experience. So I spent a few weeks creating my own HTTP Client library using boost::asio with JSON serialization/deserialization.

Dependencies

Restc-cpp depends on C++14 with its standard libraries and:

  • boost
  • rapidjson (mature, ultra-fast, json sax, header-only library)
  • lest (Unit test header only library) (If compiled with testing enabled)
  • openssl or libressl (If compiled with TLS support)
  • zlib (If compiled with compression support)

rapidjson and lest are included as CMake external dependencies.

License

MIT license. It is Free. Free as in speech. Free as in Free Air.

Examples

Fetch raw data

The following code demonstrates how to run a simple HTTP request asynchronously, using the co-routine support in boost::asio behind the scenes.

#include <iostream>
#include "restc-cpp/restc-cpp.h"

using namespace std;
using namespace restc_cpp;

void DoSomethingInteresting(Context& ctx) {
    // Here we are in a co-routine, running in a worker-thread.

    // Asynchronously connect to a server and fetch some data.
    auto reply = ctx.Get("http://jsonplaceholder.typicode.com/posts/1");

    // Asynchronously fetch the entire data-set and return it as a string.
    auto json = reply->GetBodyAsString();

    // Just dump the data.
    cout << "Received data: " << json << endl;
}

int main() {
    auto rest_client = RestClient::Create();

    // Call DoSomethingInteresting as a co-routine in a worker-thread.
    rest_client->Process(DoSomethingInteresting);

    // Wait for the coroutine to finish, then close the client.
    rest_client->CloseWhenReady(true);
}

And here is the output you could expect

Received data: {
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

Fetch a C++ object from a server that serialize to JSON

Here is a sightly more interesting example, using JSON serialization, and some modern C++ features.

#include <iostream>

#include <boost/lexical_cast.hpp>
#include <boost/fusion/adapted.hpp>

#include "restc-cpp/restc-cpp.h"
#include "restc-cpp/RequestBuilder.h"

using namespace std;
using namespace restc_cpp;

// C++ structure that match the JSON entries received
// from http://jsonplaceholder.typicode.com/posts/{id}
struct Post {
    int userId = 0;
    int id = 0;
    string title;
    string body;
};

// Since C++ does not (yet) offer reflection, we need to tell the library how
// to map json members to a type. We are doing this by declaring the
// structs/classes with BOOST_FUSION_ADAPT_STRUCT from the boost libraries.
// This allows us to convert the C++ classes to and from JSON.

BOOST_FUSION_ADAPT_STRUCT(
    Post,
    (int, userId)
    (int, id)
    (string, title)
    (string, body)
)

// The C++ main function - the place where any adventure starts
int main() {
    // Create an instance of the rest client
    auto rest_client = RestClient::Create();

    // Create and instantiate a Post from data received from the server.
    Post my_post = rest_client->ProcessWithPromiseT<Post>([&](Context& ctx) {
        // This is a co-routine, running in a worker-thread

        // Instantiate a Post structure.
        Post post;

        // Serialize it asynchronously. The asynchronously part does not really matter
        // here, but it may if you receive huge data structures.
        SerializeFromJson(post,

            // Construct a request to the server
            RequestBuilder(ctx)
                .Get("http://jsonplaceholder.typicode.com/posts/1")

                // Add some headers for good taste
                .Header("X-Client", "RESTC_CPP")
                .Header("X-Client-Purpose", "Testing")

                // Send the request
                .Execute());

        // Return the post instance trough a C++ future<>
        return post;
    })

    // Get the Post instance from the future<>, or any C++ exception thrown
    // within the lambda.
    .get();

    // Print the result for everyone to see.
    cout << "Received post# " << my_post.id << ", title: " << my_post.title;
}

The code above should return something like:

Received post# 1, title: sunt aut facere repellat provident occaecati excepturi optio reprehenderit

Please refer to the tutorial for more examples.

Features

  • High level Request Builder interface (similar to Java HTTP Clients) for convenience.
  • Low level interface to create requests.
  • All network IO operations are asynchronous trough boost::asio.
    • Use your own asio io-services
    • Let the library create and deal with the asio io-services
    • Use your own worker threads
    • Let the library create and deal with worker-threads
  • Uses C++ / boost coroutines for application logic.
  • HTTP Redirects.
  • HTTP Basic Authentication.
  • Logging trough boost::log, std::clog or trough your own log macros.
  • Log-level for the library can be set at compile time (none, error, warn, info, debug, trace)
  • Connection Pool for fast re-use of existing server connections.
  • Compression (gzip, deflate).
  • JSON serialization to and from native C++ objects.
    • Optional Mapping between C++ property names and JSON 'on the wire' names.
    • Option to tag property names as read-only to filter them out when the C++ object is serialized for transfer to the server.
    • Filters out empty C++ properties when the C++ object is serialized for transfer to the server (can be disabled).
    • Iterator interface to received JSON lists of objects.
    • Memory constraint on incoming objects (to limit damages from rouge or buggy REST servers).
    • Serialization directly from std::istream to C++ object.
  • Plain or chunked outgoing HTTP payloads.
  • Several strategies for lazy data fetching in outgoing requests.
    • Override RequestBody to let the library pull for data when required.
    • Write directly to the outgoing DataWriter when data is required.
    • Just provide a C++ object and let the library serialize it directly to the wire.

Current Status

The project has been in public BETA since April 11th 2017.

Supported operating systems

These are the operating systems where my Continues Integration (Jenkins) servers currently compiles the project and run all the tests:

  • Debian Buster (Stable)
  • Debian Stretch
  • Debian Testing
  • Windows 10 / Microsoft Visual Studio 2019, Community version using vcpkg for dependencies
  • Ubuntu Xenial (LTS)
  • Ubuntu Bionic (LTS)

Support for MacOS has been removed after Apples announcement that their love for privacy was just a marketing gimmic.

Fedora and Centos are currently disabled in my CI because of failures to start their Docker containers. (Work in progress)

The Jenkins setup is here.

This project does not use Travis CI, for two reasons. First, Travis CI is not suitable for modern C++ development. They use outdated versions of Ubuntu and old compilers. There are work-arounds for some of the issues, but I prefer to use services that tries to be helpful to whatever I am doing. Secondly, restc-cpp needs to be tested under Microsoft Windows. Travis CI does not offer that. So I have built my own CI infrastructure using my own hardware. I use Jenkins on a VM with Debian Buster, and three slaves for Docker on Linux VM's, one slave running on a VM with Microsoft Windows 10 Pro, and one slave on a MacBook Mini. Using Docker to build with different Linux distributions gives me flexibility. It also immediately catches mistakes that break the build or test(s) on a specific Linux distribution or platform.

Blog-posts about the project:

Similar projects

More information

Issues
  • Error 404 Fetching JSON data from Movie API

    Error 404 Fetching JSON data from Movie API

    Hi, I am trying to fetch movie information from a Movie API. However, I get

    libc++abi.dylib: terminating with uncaught exception of type restc_cpp::HttpNotFoundException: Request failed with HTTP error: 404 Not Found

    trying to do so and wish to know how do I change the struct to fit the API.

    E.g. screen shot 2018-03-11 at 3 42 57 pm

    #include <iostream>
    
    #include <boost/lexical_cast.hpp>
    #include <boost/fusion/adapted.hpp>
    
    #include "restc-cpp/restc-cpp.h"
    #include "restc-cpp/RequestBuilder.h"
    
    using namespace std;
    using namespace restc_cpp;
    
    struct Movie {
        int page = 0;
        int total_results = 0;
        int total_pages = 0;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(
            Movie,
            (int, page)
            (int, total_results)
            (int, total_pages)
    )
    
    int main() {
        auto rest_client = RestClient::Create();
        Movie found_movies = rest_client->ProcessWithPromiseT<Movie>([&](Context& ctx) {
                    
                    Movie movie;
    
                    SerializeFromJson(movie,
                                      RequestBuilder(ctx)
                                              .Get("https://api.themoviedb.org/3/search/movie?api_key=30ac911b5a4841e65d905a53b31396ae&query=Jack+Reacher")
                                              .Header("X-Client", "RESTC_CPP")
                                              .Header("X-Client-Purpose", "Testing")
                                              .Execute());
    
                    return movie;
                }).get();
    
        cout << "Number of Results " << found_movies.total_results << ", Page: " << found_movies.page << endl;
    }
    
    opened by thefiend 17
  • How to build on Windows

    How to build on Windows

    I am running into multiple problems:

    a) My depencies (boost, OpenSSL, zlib, etc.) are not installed under C:\devel... I install my dependencies using the conan package manager. I changed the paths in the CMake files you provided with the source code. I also included the conanbuildinfo.cmake file which is generated by conan.

    That way I could create a solution for Visual Studio 2015 using CMake. But I cannot build it. It complains about the libs from boost being missing: LNK1104 cannot open file 'libboost_log-vc140-mt-1_63.lib'

    In the Windows ecosystem, the boost libraries are build with these names following this file name pattern: "boost_log-vc140-mt-1_63.lib"

    I want to try your lib. Can you please help me getting my workspace to build?

    question 
    opened by CodingSpiderFox 14
  • Serializing a file with json data to a C++ object

    Serializing a file with json data to a C++ object

    Sir, Your restc-cpp is very very useful to us and we are using it in our project successfully for REST API from C++ on both Linux and Windows. I think this is the best available library for REST API in C++. We can serialize a c++ object with nested arrays inside it without problem while reading. But How to write a c++ object to a file in json format i.e. is there any way to write or create a JSON file from C++ object. Can you list me a example... Thanking You, Kranti.

    enhancement 
    opened by kranti-madineni 9
  • Cannot find path. Unable to use restc-cpp

    Cannot find path. Unable to use restc-cpp

    Using the example program `#include #include "restc-cpp/restc-cpp.h"

    using namespace std; using namespace restc_cpp;

    void DoSomethingInteresting(Context& ctx) { // Here we are in a co-routine, running in a worker-thread.

    // Asynchronously connect to a server and fetch some data.
    auto reply = ctx.Get("http://jsonplaceholder.typicode.com/posts/1");
    
    // Asynchronously fetch the entire data-set and return it as a string.
    auto json = reply->GetBodyAsString();
    
    // Just dump the data.
    cout << "Received data: " << json << endl;
    

    }

    int main() { auto rest_client = RestClient::Create();

    // Call DoSomethingInteresting as a co-routine in a worker-thread.
    rest_client->Process(DoSomethingInteresting);
    
    // Wait for the coroutine to finish, then close the client.
    rest_client->CloseWhenReady(true);
    

    } ` VSCode shows #include errors detected. Please update your includePath. IntelliSense features for this translation unit (/home/kiran/dave/src/rest-client.cpp) will be provided by the Tag Parser. cannot open source file "restc-cpp/restc-cpp.h"

    I have followed the build instructions for ubuntu to the letter. `sudo apt-get install zlib1g-dev g++ cmake doxygen graphviz libboost-all-dev libssl-dev

    git clone https://github.com/jgaa/restc-cpp.git cd restc-cpp/ mkdir dbuild cd dbuild cmake .. make`

    opened by privateOmega 8
  • ProtocolException unsupported HTTP version

    ProtocolException unsupported HTTP version

    Hello, I'm trying to connect to a remote server and my program fails with this exception:

    terminate called after throwing an instance of 'restc_cpp::ProtocolException'
      what():  ReadHeaders(): unsupported HTTP version: 0%0D%0A%0D%0AHTTP/1.1
    fish: './orotool' terminated by signal SIGABRT (Abort)
    

    Is the upstream server misconfigured, or should this library be able to clean up the extra characters before HTTP?

    bug 
    opened by KingDuckZ 7
  • issue in linking restc-cpp with a project on redhat 7

    issue in linking restc-cpp with a project on redhat 7

    Hello Sir, I am using your library in my project. I am able to use it on ubuntu. I have successfully compiled your library on redhat7. but when I am linking to my project I am getting following error

    restc-cpp.h:368: undefined reference to `restc_cpp::Context::Create(boost::asio::basic_yield_context<boost::asio::detail::wrapped_handler<boost::asio::io_service::strand, void (*)(), boost::asio::detail::is_continuation_if_running> >&, restc_cpp::RestClient&)'

    Need your help to resolve the problem Thank You

    opened by dheeraj12190 6
  • Problems building in Mac

    Problems building in Mac

    Hello

    Firstable thanks for a lot for all your work on this, I'm really looking forward to use it and play with it. I've been trying to build the project using instructions on: https://github.com/jgaa/restc-cpp/wiki/Building-under-macOS but when running make I'm getting a lot of errors.

    I wonder if you could point me out in what the problem could be? I'm doing this in my Mac running High Sierra and with this compiler version:

    -- The C compiler identification is AppleClang 9.0.0.9000039 -- The CXX compiler identification is AppleClang 9.0.0.9000039

    Thanks a lot Javier

    ..... errors from this point onward, before this is all building ok ... In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:23: /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/helper.h:39:19: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions] for(const auto& it : *src) { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/helper.h:39:28: warning: range-based for loop is a C++11 extension [-Wc++11-extensions] for(const auto& it : *src) { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/helper.h:54:5: error: expected member name or ';' after declaration specifiers { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/helper.h:53:11: error: expected '(' : buf_{stream.str()} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/helper.h:53:24: error: expected ';' after expression : buf_{stream.str()} ^ ; In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/tests/unit/AsyncSleepTests.cpp:13: In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:24: /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/Connection.h:15:19: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using ptr_t = std::shared_ptr; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/Connection.h:17:10: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions] enum class Type { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/Connection.h:22:29: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] virtual ~Connection() = default; ^ In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/tests/unit/AsyncSleepTests.cpp:13: /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:64:25: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using write_buffers_t = std::vectorboost::asio::const_buffer; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:70:17: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Arg() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:71:27: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Arg(const Arg&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:74:25: error: expected member name or ';' after declaration specifiers : name{use_name}, value{use_value} {} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:84:18: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Auth() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:85:29: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Auth(const Auth&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:86:18: warning: rvalue references are a C++11 extension [-Wc++11-extensions] Auth(Auth&&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:86:24: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Auth(Auth&&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:88:25: error: expected member name or ';' after declaration specifiers : name{authName}, passwd{authPasswd} {} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:96:31: warning: rvalue references are a C++11 extension [-Wc++11-extensions] Auth& operator = (Auth&&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:96:37: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] Auth& operator = (Auth&&) = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:103:14: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions] enum class Type { NONE, HTTP }; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:104:19: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] Type type = Type::NONE; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:108:23: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using headers_t = std::map<std::string, std::string, ciLessLibC>; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:109:20: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using args_t = std::deque; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:110:20: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using auth_t = Auth; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:112:10: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions] enum class Type { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:121:23: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using ptr_t = std::shared_ptr; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:123:26: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int maxRedirects = 3; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:124:30: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int connectTimeoutMs = (1000 * 12); ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:125:27: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int sendTimeoutMs = (1000 * 12); // For each IO operation ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:126:28: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int replyTimeoutMs = (1000 * 21); // For the reply header ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:127:25: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int recvTimeout = (1000 * 21); // For each IO operation ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:128:52: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] std::size_t cacheMaxConnectionsPerEndpoint = 16; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:129:41: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] std::size_t cacheMaxConnections = 128; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:130:29: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int cacheTtlSeconds = 60; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:131:41: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int cacheCleanupIntervalSeconds = 3; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:163:26: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] virtual ~Request() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:169:48: error: expected expression std::unique_ptr body = {}, ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:170:50: error: expected expression const boost::optional<args_t>& args = {}, ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:171:56: error: expected expression const boost::optional<headers_t>& headers = {}, ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:172:50: error: expected expression const boost::optional<auth_t>& auth = {}); ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:104:21: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions] Type type = Type::NONE; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:74:15: error: expected '(' : name{use_name}, value{use_value} {} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:74:24: error: expected ';' after expression : name{use_name}, value{use_value} {} ^ ; /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:74:16: warning: expression result unused [-Wunused-value] : name{use_name}, value{use_value} {} ^~~~~~~~ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:88:15: error: expected '(' : name{authName}, passwd{authPasswd} {} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:88:24: error: expected ';' after expression : name{authName}, passwd{authPasswd} {} ^ ; /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:88:16: warning: expression result unused [-Wunused-value] : name{authName}, passwd{authPasswd} {} ^~~~~~~~ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:179:14: warning: scoped enumerations are a C++11 extension [-Wc++11-extensions] enum class HttpVersion { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:182:34: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] HttpVersion http_version = HttpVersion::HTTP_1_1; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:183:25: warning: in-class initialization of non-static data member is a C++11 extension [-Wc++11-extensions] int status_code = 0; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:187:24: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] virtual ~Reply() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:182:36: warning: use of enumeration in a nested name specifier is a C++11 extension [-Wc++11-extensions] HttpVersion http_version = HttpVersion::HTTP_1_1; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:267:15: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions] const auto microseconds = ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:292:22: warning: alias declarations are a C++11 extension [-Wc++11-extensions] using prc_fn_t = std::function<void (Context& ctx)>; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:296:25: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] DoneHandler() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:297:34: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] virtual ~DoneHandler() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:303:29: warning: defaulted function definitions are a C++11 extension [-Wc++11-extensions] virtual ~RestClient() = default; ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:328:9: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions] auto prom = std::make_shared<std::promise>(); ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:328:52: error: a space is required between consecutive right angle brackets (use '> >') auto prom = std::make_shared<std::promise>(); ^~ > > /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:329:9: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions] auto future = prom->get_future(); ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/restc-cpp.h:332:28: error: expected expression [prom,fn,this](boost::asio::yield_context yield) { ^ In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/tests/unit/AsyncSleepTests.cpp:14: /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/error.h:22:5: error: expected member name or ';' after declaration specifiers { ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/error.h:21:20: error: expected '(' , http_response{response} ^ /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/error.h:21:29: error: expected ';' after expression , http_response{response} ^ ; /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/error.h:21:21: warning: expression result unused [-Wunused-value] , http_response{response} ^~~~~~~~ In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/tests/unit/AsyncSleepTests.cpp:15: In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/RequestBuilder.h:12: In file included from /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/SerializeJson.h:29: /Users/jdiaz/Development/cplusplus/restc-cpp/include/restc-cpp/RapidJsonReader.h:24:5: error: expected member name or ';' after declaration specifiers { ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 47 warnings and 20 errors generated. make[2]: *** [tests/unit/CMakeFiles/async_sleep_tests.dir/AsyncSleepTests.cpp.o] Error 1 make[1]: *** [tests/unit/CMakeFiles/async_sleep_tests.dir/all] Error 2 make: *** [all] Error 2

    opened by jdiaz4517 5
  • Building On m1 MacBook Pro

    Building On m1 MacBook Pro

    I've tried installing the x86 version of boost library and i'm still gettings errors, I also tried the arm64 version of boost which I installed through brew and im still getting errors. Then I also tried g++11 which I installed through homebrew which compiles but failes all the tests, and i also tried the built in apple gcc compiler, im able to pass half of the test, but the library wont work just wont work when I try to make something with.

    ::open_record<boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, boost::log::v2_mt_posix::trivial::severity_level const> > >(boost::parameter::aux::tagged_argument_list_of_1<boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::severity, boost::log::v2_mt_posix::trivial::severity_level const> > const&) in librestc-cpp.a(ReplyImpl.cpp.o) ld: symbol(s) not found for architecture arm64

    this is when I use the following setting I used for built in gcc: c817466b138d4b7763ab3faac551be58

    323156e9d3d4c5daeec8e36062922697

    then this is the settings for gcc using openssl3 I installed through homebrew in rosetta mode:

    cmake -DCMAKE_BUILD_TYPE=Release -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] -DOPENSSL_LIBRARIES=/usr/local/opt/[email protected]/lib -DZLIB_INCLUDE_DIRS=/usr/local/opt/zlib/include/ -DZLIB_LIBRARIES=/usr/local/opt/zlib/lib -DBoost_NO_BOOST_CMAKE=TRUE -DBoost_NO_SYSTEM_PATHS=TRUE -DBOOST_LIBRARIES=/usr/local/opt/boost/lib -DBOOSTL_ROOT_DIR=/usr/local/opt/boost -DBOOST_ROOT=/usr/local/opt/boost -DCMAKE_C_COMPILER=/usr/local/bin/gcc-11 -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-11 ..

    946040bd6deb220b5d4e9451c28dadbb
    opened by AlNotAlbert 4
  • How to disable log?

    How to disable log?

    https://github.com/jgaa/restc-cpp/blob/0c9feea11d00c68174d03c0d4b1db3a98e496452/include/restc-cpp/logging.h#L30-L31

    I use a static build of boost and can't get rid of linking error:

    .../external-projects/installed/lib/librestc-cpp.a(RestClientImpl.cpp.o): In function `boost::log::v2_mt_posix::record::reset()':
    RestClientImpl.cpp:(.text._ZN5boost3log11v2_mt_posix6record5resetEv[_ZN5boost3log11v2_mt_posix6record5resetEv]+0x23): undefined reference to `boost::log::v2_mt_posix::record_view::public_data::destroy(boost::log::v2_mt_posix::record_view::public_data const*)'
    

    Here is a snippet of my cmake script

    ExternalProject_Add(external_boost
        URL "https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.gz"
        URL_HASH SHA256=8aa4e330c870ef50a896634c931adf468b21f8a69b77007e45c444151229f665
        BUILD_IN_SOURCE ON
        UPDATE_COMMAND ""
        CONFIGURE_COMMAND ./bootstrap.sh --prefix=${EXTERNAL_PROJECTS_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
        BUILD_COMMAND ./b2 link=static cxxflags=-fPIC install --prefix=${EXTERNAL_PROJECTS_INSTALL_PREFIX} -j 2
        INSTALL_COMMAND ""
        )
    set_target_properties(external_boost PROPERTIES EXCLUDE_FROM_ALL TRUE)
    add_dependencies(external_all external_boost)
    
    ExternalProject_Add(external_restc_cpp
        PREFIX "${EXTERNAL_PROJECTS_PREFIX}"
        GIT_REPOSITORY "https://github.com/jgaa/restc-cpp.git"
        GIT_TAG "5fafdbdccf369b198b4a2a0c863bd52188ed3530"
        CMAKE_ARGS
            -DCMAKE_INSTALL_PREFIX=${EXTERNAL_PROJECTS_INSTALL_PREFIX}
            -DRESTC_CPP_USE_CPP17=ON
            -DRESTC_CPP_WITH_EXAMPLES=OFF
            -DRESTC_CPP_WITH_UNIT_TESTS=OFF
            -DRESTC_CPP_WITH_FUNCTIONALT_TESTS=OFF
            -DBoost_INCLUDE_DIR=${EXTERNAL_PROJECTS_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}
        )
    set_target_properties(external_restc_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
    add_dependencies(external_restc_cpp external_boost)
    add_dependencies(external_all external_restc_cpp)
    

    Solution from google seem to not work. I just want to disable logs completely because we plan to migrate completely to Restbed client.

    opened by 01e9 4
  • Impossible to access all `Set-Cookie` headers

    Impossible to access all `Set-Cookie` headers

    In response I have multiple cookies but Reply::GetHeader(name) returns only the last header with the give name

    https://github.com/jgaa/restc-cpp/blob/6398d70c772cc857c50d0ea4add8acfe85ccd10b/include/restc-cpp/restc-cpp.h#L226-L228

    Until this will be fixed, any workaround?

    bug 
    opened by 01e9 4
  • provide build package for MSVC via vcpkg

    provide build package for MSVC via vcpkg

    Hello,

    I'm trying to build restc-cpp on windows and like everyone else I'm stumbling upon build issue. one thing i noticed that probably makes all problems go away is using vcpkg for dependencies. since your project depends on boost and zlib and both are available via vcpkg it shouldn't be a problem making a cmake file for it.

    I don't know how to do that , else i'd have opened a PR.

    opened by danyhm 3
  • Testing with Ubuntu Jammy fails with an exception in Jenkins

    Testing with Ubuntu Jammy fails with an exception in Jenkins

    I'm not sure why this fails.

    Pipeline] End of Pipeline
    Also:   java.io.IOException: Failed to run image '692f7cce9b970633dba347a9aaf12846429c073f'. Error: docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: chdir to cwd ("/home/jenkins/build/workspace/restc-staging") set in config.json failed: permission denied: unknown.
    java.io.IOException: Failed to run image '692f7cce9b970633dba347a9aaf12846429c073f'. Error: docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: chdir to cwd ("/home/jenkins/build/workspace/restc-staging") set in config.json failed: permission denied: unknown.
    	at org.jenkinsci.plugins.docker.workflow.client.DockerClient.run(DockerClient.java:145)
    	at org.jenkinsci.plugins.docker.workflow.WithContainerStep$Execution.start(WithContainerStep.java:200)
    	at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
    	at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
    	at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
    	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47)
    	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    	at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
    	at org.jenkinsci.plugins.docker.workflow.Docker$Image.inside(Docker.groovy:140)
    	at org.jenkinsci.plugins.docker.workflow.Docker.node(Docker.groovy:66)
    	at org.jenkinsci.plugins.docker.workflow.Docker$Image.inside(Docker.groovy:125)
    	at org.jenkinsci.plugins.docker.workflow.declarative.DockerPipelineFromDockerfileScript.runImage(DockerPipelineFromDockerfileScript.groovy:56)
    	at org.jenkinsci.plugins.docker.workflow.declarative.AbstractDockerPipelineScript.configureRegistry(AbstractDockerPipelineScript.groovy:63)
    	at org.jenkinsci.plugins.docker.workflow.declarative.AbstractDockerPipelineScript.run(AbstractDockerPipelineScript.groovy:50)
    	at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.checkoutAndRun(CheckoutScript.groovy:61)
    
    bug 
    opened by jgaa 0
  • Socks5 and TLS handshake failures in Debian Jessie and Ubuntu Xenial

    Socks5 and TLS handshake failures in Debian Jessie and Ubuntu Xenial

    I have observed a weird error where initial binary handshakes (TLS and Socks5) fails with error 11 (EAGAIN) on these systems, at least when running in Docker and communicating with a server outside the container. It could be related to old versions of the boost library. If I link with boost 1.76, the socks5 tests pass.

    bug 
    opened by jgaa 0
  • On Debian 11, ctest fails unless I use RESTC_CPP_TEST_DOCKER_ADDRESS to set the ip

    On Debian 11, ctest fails unless I use RESTC_CPP_TEST_DOCKER_ADDRESS to set the ip

    It's probably related to localhost defaulting to ipv6, while docker by default use only ipv4.

    I need to investigate and see if the dns library provide both ipv6 and ipv4 addresses. If so, restc should fall back to using ipv4.

    enhancement 
    opened by jgaa 0
  • HTTPS_FUNCTIONAL_TESTS failing on Debian Stretch and Ununtu Xenial

    HTTPS_FUNCTIONAL_TESTS failing on Debian Stretch and Ununtu Xenial

    It looks like an issue with boost/openssl on those platforms not being able to establish a TLS connection with the current minimum requirements. But I'll have to investigate further.

    bug 
    opened by jgaa 0
  • Issue while compiling

    Issue while compiling

    I have built the library (With several of the tests failing) and then I created a simple hello world project:

    #include <iostream>
    #include <boost/lexical_cast.hpp>
    #include <boost/fusion/adapted.hpp>
    #include </home/i2cat/Downloads/restc-cpp/include/restc-cpp/restc-cpp.h>
    #include </home/i2cat/Downloads/restc-cpp/include/restc-cpp/SerializeJson.h>
    #include </home/i2cat/Downloads/restc-cpp/include/restc-cpp/RequestBuilder.h>
    using namespace std;
    int main() {
    	cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    	return 0;
    }
    

    But on the compilation stage, the following error appears:

    image

    I am running Ubuntu 20.04 LTS

    opened by juansebastiani2cat 1
Releases(v0.94.0-rc1)
  • v0.94.0-rc1(Aug 7, 2022)

    The library is getting more mature, so it makes sense to start moving towards a stable release.

    What's Changed

    • A couple of bugfixes and minor features
    • Added partial support for SOCKS5 (authentication not supported)
    • Added support for local binding. Closes #122 by @jgaa in https://github.com/jgaa/restc-cpp/pull/127
    • bat file to build restc-cpp using vcpkg in windows by @danyhm in https://github.com/jgaa/restc-cpp/pull/133
    • bat file to build restc-cpp using vcpkg in windows by @danyhm in https://github.com/jgaa/restc-cpp/pull/132

    New Contributors

    • @danyhm made their first contribution in https://github.com/jgaa/restc-cpp/pull/133

    Full Changelog: https://github.com/jgaa/restc-cpp/compare/v0.10.0...v0.94.0-rc1

    Source code(tar.gz)
    Source code(zip)
  • v0.10.0(Oct 31, 2020)

    Multiple bugfixes.

    Some new features:

    • Boost.Log is made optional.
    • Logging to std::clog is supported.
    • Logging can be disabled, and the log-level set at compile time. Use RESTC_CPP_LOG_LEVEL_STR cmake option.
    • The asio context can be multi-threaded (excellent for use in servers, and to stress-test servers). Enable RESTC_CPP_THREADED_CTX cmake option.

    Updated to work with the latest Debian, MacOS and Windows 10 OS/compilers.

    Source code(tar.gz)
    Source code(zip)
  • Beta2(Mar 24, 2018)

  • Beta1(Apr 21, 2017)

    The project is finally in a state where it is ready for broader testing and experimental use.

    All tests pass on all supported platforms.

    Please open an issue for any bug, flaw or annoyance found.

    Source code(tar.gz)
    Source code(zip)
  • v0.01(Apr 11, 2016)

Owner
Jarle Aase
Freelance Senior C++ developer <<>>
Jarle Aase
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 52 Jul 3, 2022
HTTP/HTTPS REST Client C Library

https_client HTTP/HTTPS REST Client C Library This library is a tiny https client library. it use only small memory(default read buffer size(H_READ_SI

HISONA 97 Jul 21, 2022
C++ client for making HTTP/REST requests

REST client for C++ About This is a simple REST client for C++. It wraps libcurl for HTTP requests. Usage restclient-cpp provides two ways of interact

Daniel Schauenberg 1.4k Aug 12, 2022
C++ library for creating an embedded Rest HTTP server (and more)

The libhttpserver reference manual Tl;dr libhttpserver is a C++ library for building high performance RESTful web servers. libhttpserver is built upon

Sebastiano Merlino 667 Aug 3, 2022
A REST API in C, yeah, C...

A REST API that fetches custom data from École 42 users, written in C. (Challenge from 42Labs) Constructed with: Mongoose Mjson Org-mode MongoDB Atlas

Henrique Rocha 3 Jun 14, 2022
Various utilities such as WebServer, JSON, WebSocket server, REST framework

DumaisLib This is a library containing several utilities for some projects of Patrick Dumais. Previously, the libraries were all individual but it bec

Patrick Dumais 25 Feb 22, 2022
C++ Web Framework REST API

✨ wfrest: C++ Web Framework REST API Fast, efficient, and easiest c++ async micro web framework based on C++ Workflow. ?? Contents wfrest: C++ Web Fra

null 430 Aug 11, 2022
Triton Python and C++ client libraries and example, and client examples for go, java and scala.

Triton Client Libraries and Examples To simplify communication with Triton, the Triton project provides several client libraries and examples of how t

Triton Inference Server 164 Aug 7, 2022
VEngine-Client - vEngine: Official Client Module

━ S Y N O P S I S ━ Maintainer(s): Aviril, Tron vEngine is Next-Gen Sandbox-Engine being crafted in C++. In contrast to UE/Unity/ReverseEngineered-Mod

ᴠ : ꜱᴛᴜᴅɪᴏ 13 Apr 13, 2022
Pyth-client - client API for on-chain pyth programs

pyth-client client API for on-chain pyth programs Build Instructions # depends on openssl apt install libssl-dev # depends on libz apt install zlib1g

Pyth Network 101 Jul 3, 2022
Webdav-client-cpp - C++ WebDAV Client provides easy and convenient to work with WebDAV-servers.

WebDAV Client Package WebDAV Client provides easy and convenient to work with WebDAV-servers: Yandex.Disk Dropbox Google Drive Box 4shared ownCloud ..

Cloud Polis 102 Jul 10, 2022
This repository provides a C++ client SDK for Unleash that meets the Unleash Client Specifications.

Unleash Client SDK for C++ This repository provides a C++ client SDK for Unleash that meets the Unleash Client Specifications. Features The below tabl

Antonio Ruiz 4 Jan 30, 2022
A C++ header-only HTTP/HTTPS server and client library

cpp-httplib A C++11 single-file header-only cross platform HTTP/HTTPS library. It's extremely easy to setup. Just include the httplib.h file in your c

null 7.6k Aug 15, 2022
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 867 Aug 8, 2022
C++ websocket client/server library

WebSocket++ (0.8.2) WebSocket++ is a header only C++ library that implements RFC6455 The WebSocket Protocol. It allows integrating WebSocket client an

Peter Thorson 5.7k Aug 10, 2022
A network library for client/server games written in C++

yojimbo yojimbo is a network library for client/server games written in C++. It's designed around the networking requirements of competitive multiplay

The Network Protocol Company 2.2k Aug 15, 2022
Ole Christian Eidheim 737 Aug 6, 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. 329 Aug 8, 2022
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 284 Jul 7, 2022