Giter Site home page Giter Site logo

mrtazz / restclient-cpp Goto Github PK

View Code? Open in Web Editor NEW
1.5K 87.0 370.0 4.31 MB

C++ client for making HTTP/REST requests

Home Page: http://code.mrtazz.com/restclient-cpp/

License: MIT License

Shell 0.63% C++ 85.07% Makefile 6.10% M4 1.34% CMake 6.86%
restclient libcurl packagecloud c-plus-plus rest rest-client http http-client

restclient-cpp's Introduction

REST client for C++

build status Coverage Status Packagecloud doxygen MIT license

About

This is a simple REST client for C++. It wraps libcurl for HTTP requests.

Usage

restclient-cpp provides two ways of interacting with REST endpoints. There is a simple one, which doesn't need you to configure an object to interact with an API. However the simple way doesn't provide a lot of configuration options either. So if you need more than just a simple HTTP call, you will probably want to check out the advanced usage.

Simple Usage

The simple API is just some static methods modeled after the most common HTTP verbs:

#include "restclient-cpp/restclient.h"

RestClient::Response r = RestClient::get("http://url.com")
RestClient::Response r = RestClient::post("http://url.com/post", "application/json", "{\"foo\": \"bla\"}")
RestClient::Response r = RestClient::put("http://url.com/put", "application/json", "{\"foo\": \"bla\"}")
RestClient::Response r = RestClient::patch("http://url.com/patch", "application/json", "{\"foo\": \"bla\"}")
RestClient::Response r = RestClient::del("http://url.com/delete")
RestClient::Response r = RestClient::head("http://url.com")
RestClient::Response r = RestClient::options("http://url.com")

The response is of type RestClient::Response and has three attributes:

RestClient::Response.code // HTTP response code
RestClient::Response.body // HTTP response body
RestClient::Response.headers // HTTP response headers

Advanced Usage

However if you want more sophisticated features like connection reuse, timeouts or authentication, there is also a different, more configurable way.

#include "restclient-cpp/connection.h"
#include "restclient-cpp/restclient.h"

// initialize RestClient
RestClient::init();

// get a connection object
RestClient::Connection* conn = new RestClient::Connection("http://url.com");

// configure basic auth
conn->SetBasicAuth("WarMachine68", "WARMACHINEROX");

// set connection timeout to 5s
conn->SetTimeout(5);

// set custom user agent
// (this will result in the UA "foo/cool restclient-cpp/VERSION")
conn->SetUserAgent("foo/cool");

// enable following of redirects (default is off)
conn->FollowRedirects(true);
// and limit the number of redirects (default is -1, unlimited)
conn->FollowRedirects(true, 3);

// set headers
RestClient::HeaderFields headers;
headers["Accept"] = "application/json";
conn->SetHeaders(headers)

// append additional headers
conn->AppendHeader("X-MY-HEADER", "foo")

// if using a non-standard Certificate Authority (CA) trust file
conn->SetCAInfoFilePath("/etc/custom-ca.crt")

RestClient::Response r = conn->get("/get")
RestClient::Response r = conn->head("/get")
RestClient::Response r = conn->del("/delete")
RestClient::Response r = conn->options("/options")

// set different content header for POST, PUT and PATCH
conn->AppendHeader("Content-Type", "application/json")
RestClient::Response r = conn->post("/post", "{\"foo\": \"bla\"}")
RestClient::Response r = conn->put("/put", "application/json", "{\"foo\": \"bla\"}")
RestClient::Response r = conn->patch("/patch", "text/plain", "foobar")

// deinit RestClient. After calling this you have to call RestClient::init()
// again before you can use it
RestClient::disable();

The responses are again of type RestClient::Response and have three attributes:

RestClient::Response.code // HTTP response code
RestClient::Response.body // HTTP response body
RestClient::Response.headers // HTTP response headers

The connection object also provides a simple way to get some diagnostics and metrics information via conn->GetInfo(). The result is a RestClient::Connection::Info struct and looks like this:

typedef struct {
  std::string base_url;
  RestClients::HeaderFields headers;
  int timeout;
  struct {
    std::string username;
    std::string password;
  } basicAuth;

  std::string certPath;
  std::string certType;
  std::string keyPath;
  std::string keyPassword;
  std::string customUserAgent;
  std::string uriProxy;
  struct {
    // total time of the last request in seconds Total time of previous
    // transfer. See CURLINFO_TOTAL_TIME
    int totalTime;
    // time spent in DNS lookup in seconds Time from start until name
    // resolving completed. See CURLINFO_NAMELOOKUP_TIME
    int nameLookupTime;
    // time it took until Time from start until remote host or proxy
    // completed. See CURLINFO_CONNECT_TIME
    int connectTime;
    // Time from start until SSL/SSH handshake completed. See
    // CURLINFO_APPCONNECT_TIME
    int appConnectTime;
    // Time from start until just before the transfer begins. See
    // CURLINFO_PRETRANSFER_TIME
    int preTransferTime;
    // Time from start until just when the first byte is received. See
    // CURLINFO_STARTTRANSFER_TIME
    int startTransferTime;
    // Time taken for all redirect steps before the final transfer. See
    // CURLINFO_REDIRECT_TIME
    int redirectTime;
    // number of redirects followed. See CURLINFO_REDIRECT_COUNT
    int redirectCount;
  } lastRequest;
} Info;

Persistent connections/Keep-Alive

The connection object stores the curl easy handle in an instance variable and uses that for the lifetime of the object. This means curl will automatically reuse connections made with that handle.

Progress callback

Two wrapper functions are provided to setup the progress callback for uploads/downloads.

Calling conn->SetFileProgressCallback(callback) with a callback parameter matching the prototype int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) will setup the progress callback.

Calling conn->SetFileProgressCallbackData(data) is optional. This will set the data pointer which is the first parameter fed back to the progress callback - clientp. If this isn't set then clientp will default to the connection object conn.

// set CURLOPT_NOPROGRESS
// set CURLOPT_PROGRESSFUNCTION
conn->SetFileProgressCallback(progressFunc);
// set CURLOPT_PROGRESSDATA
conn->SetFileProgressCallbackData(data);

Write callback

A write callback function can be provided for processing data as it's received from a GET call (for instance the Kubernetes Watch API).

Calling conn->SetWriteFunction(callback) with a function parameter matching the prototype size_t write_function(void *data, size_t size, size_t nmemb, void *userdata)int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) will setup the write function.

Here is an example of a write callback function, processing result data line by line.

auto writeCallback = [](void *data, size_t size, size_t nmemb, void *userdata) -> size_t
{
  size_t bytes = size * nmemb;
  try
  {
      // Add to the buffer
      auto res = reinterpret_cast<RestClient::Response *>(userdata);
      res->body.append(static_cast<char*>(data), bytes);
      // If the last character is not a new line, wait for the rest.
      if ('\n' != *(res->body.end() - 1))
      {
          return bytes;
      }
      // Process data one line at a time.
      std::stringstream stream(res->body);
      std::string line;
      while (std::getline(stream, line))
      {
        // Do something with the line here...
      }
      // Done processing the line
      res->body.clear();
  }
  catch(std::exception e)
  {
      // Log caught exception here
      return 0;
  }
  return bytes;
};

Error handling

When restclient-cpp encounters an error, generally the error (or "status") code is returned in the Response (see Response struct in restclient.h). This error code can be either an HTTP error code, or if a lower-level cURL error was encountered, it may be a CURLCode. Currently, libcurl only defines 92 error codes, which means there is no overlap between cURL error codes and HTTP response codes (which start at 1xx). However, if in the future, libcurl defines more than 99 error codes, meaning that cURL errors overlap with the HTTP 1xx class of responses, restclient-cpp will return a -1 if the CURLCode is 100 or higher. In this case, callers can use GetInfo().lastRequest.curlCode to inspect the actual cURL error.

Thread Safety

restclient-cpp leans heavily on libcurl as it aims to provide a thin wrapper around it. This means it adheres to the basic level of thread safety provided by libcurl. The RestClient::init() and RestClient::disable() methods basically correspond to curl_global_init and curl_global_cleanup and thus need to be called right at the beginning of your program and before shutdown respectively. These set up the environment and are not thread-safe. After that you can create connection objects in your threads. Do not share connection objects across threads as this would mean accessing curl handles from multiple threads at the same time which is not allowed.

The connection level method SetNoSignal can be set to skip all signal handling. This is important in multi-threaded applications as DNS resolution timeouts use signals. The signal handlers quite readily get executed on other threads. Note that with this option DNS resolution timeouts do not work. If you have crashes in your multi-threaded executable that appear to be in DNS resolution, this is probably why.

In order to provide an easy to use API, the simple usage via the static methods implicitly calls the curl global functions and is therefore also not thread-safe.

HTTPS User Certificate

Simple wrapper functions are provided to allow clients to authenticate using certificates. Under the hood these wrappers set cURL options, e.g. CURLOPT_SSLCERT, using curl_easy_setopt. Note: currently libcurl compiled with gnutls (e.g. libcurl4-gnutls-dev on ubuntu) is buggy in that it returns a wrong error code when these options are set to invalid values.

// set CURLOPT_SSLCERT
conn->SetCertPath(certPath);
// set CURLOPT_SSLCERTTYPE
conn->SetCertType(type);
// set CURLOPT_SSLKEY
conn->SetKeyPath(keyPath);
// set CURLOPT_KEYPASSWD
conn->SetKeyPassword(keyPassword);

HTTP Proxy Tunneling Support

An HTTP Proxy can be set to use for the upcoming request. To specify a port number, append :[port] to the end of the host name. If not specified, libcurl will default to using port 1080 for proxies. The proxy string may be prefixed with http:// or https://. If no HTTP(S) scheme is specified, the address provided to libcurl will be prefixed with http:// to specify an HTTP proxy. A proxy host string can embedded user + password. The operation will be tunneled through the proxy as curl option CURLOPT_HTTPPROXYTUNNEL is enabled by default. A numerical IPv6 address must be written within [brackets].

// set CURLOPT_PROXY
conn->SetProxy("https://37.187.100.23:3128");
/* or you can set it without the protocol scheme and
http:// will be prefixed by default */
conn->SetProxy("37.187.100.23:3128");
/* the following request will be tunneled through the proxy */
RestClient::Response res = conn->get("/get");

Unix Socket Support

Note that the URL used with a unix socket has only ONE leading forward slash.

RestClient::Connection* conn = new RestClient::Connection("http:/v1.30");
conn->SetUnixSocketPath("/var/run/docker.sock");
RestClient::HeaderFields headers;
headers["Accept"] = "application/json; charset=UTF-8";
headers["Expect"] = "";
conn->SetHeaders(headers);
auto resp = conn->get("/images/json");

Dependencies

Installation

There are some packages available for Linux on packagecloud. And for OSX you can get it from the mrtazz/oss homebrew tap:

brew tap mrtazz/oss
brew install restclient-cpp

Otherwise you can do the regular autotools dance:

./autogen.sh
./configure
make install

Alternatively, you can build and install restclient-cpp using vcpkg dependency manager:

git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install restclient-cpp

The restclient-cpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.

Another option is to use Mingw64 and CMake to compile on Windows. This requires you to have Mingw64 installed with CMake and libCurl (MSYS2 would also work fine).

# Make sure cmake, mingw32-make and g++ are in PATH
# Clone the repo
git clone https://github.com/mrtazz/restclient-cpp && cd restclient-cpp
# Build library
mkdir build && cd build
# Run cmake
cmake -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CC_COMPILER=gcc -DCMAKE_MAKE_PROGRAM=mingw32-make -G "MinGW Makefiles" ..
# Builds the dll.a lib and dll file
mingw32-make

Contribute

All contributions are highly appreciated. This includes filing issues, updating documentation and writing code. Please take a look at the contributing guidelines before so your contribution can be merged as fast as possible.

restclient-cpp's People

Contributors

69736c616d avatar aknoerig avatar aronrubin avatar bas-vk avatar bl4ck5un avatar concernedrat avatar cypherpunksamurai avatar dennisjenkins75 avatar drodil avatar edwinpjacques avatar embeddedmz avatar eriksson avatar giursino-vimar avatar krujos avatar lawmaestro avatar limhyungseok avatar lucklove avatar m4burns avatar marczych avatar mgerhardy avatar montdidier avatar mrtazz avatar phoebehui avatar spencatro avatar tastytea avatar tgoetze avatar williamspatrick avatar zhoudayang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

restclient-cpp's Issues

fix TestProxy unit test

It seems like the proxy connection is timing out:

[ RUN      ] ConnectionTest.TestProxy
test/test_connection.cc:224: Failure
Value of: res.code
  Actual: 28
Expected: 200

Might be worth looking into running a proxy server in a docker container for that test.

Compilation on Cygwin does not build shared libraries

Attempting to compile the library on cygwin yields the libtool error:

libtool: warning: undefined symbols not allowed in x86_64-unknown-cygwin shared
libraries; building static only

Indeed, attempting to compile a program with the library yields a slew of reference not found errors in the vein of:

undefined reference to `RestClient::post(std::string const&, std::string const&, 
std::string const&)'
relocation truncated to fit: R_X86_64_PC32 against undefined symbol `RestClient::post(
std::string const&, std::string const&, std::string const&)'
collect2: error: ld returned 1 exit status

Having proxy variables set in shell environment fails test.

Having proxy variables such as http_proxy, https_proxy, ftp_proxy make the tests fail. Should these environment variables be considered while running the tests?
Also unsetting those variables make the RestClientPutTest.TestRestClientPUTHeaders test fail and all others pass, since the request is made to heroku server.

Should there be any curl_global_init in RestClient?

I found no call to curl_global_init in RestClient class. As said in curl documentation: "This function must be called at least once within a program", is it a bug?
Update: Sorry, I found that "If you did not already call curl_global_init, curl_easy_init does it automatically."

curl_global_cleanup at the end of every request is harmful

The following was observed in AOSP. Calling curl_global_cleanup at the end of every request is harmful, because it cleans up OpenSSL's internal algorithm directory by EVP_Cleanup, effectively undoing OpenSSL_add_all_algorithms(). If OpenSSL is used between requests, for instance certificate vaildation fails with a signature error 7 since the library cannot lookup for algorithms. I would suggest removing the curl_global_cleanup call as AFAIK it's not really needed.

Empty response, no connection

Hi!

I'm using a slightly modified version of the advanced example from the README and having issues getting off the ground. Specifically, the response object returned from conn -> post(...) comes back instantly with code 500 and an empty body. The server it's supposed to be talking to receives no requests.

The code I'm using looks like this

Proxy::Proxy(Proxy::Settings settings)
{
    // parse settings
    RestClient::init();
}

Proxy::~Proxy()
{
    RestClient::disable();
}

// requests are handled by a thread pool
Proxy::Request(...)
{
    // translate end-user request for back-end server
    std::string workerAddress; // address to back-end server, no trailing slash
    std::string payload; // json string with escaped quotes
    
    std::unique_ptr<RestClient::Connection> conn(new RestClient::Connection(workerAddress));
    conn->SetTimeout(1);
    RestClient::HeaderFields headers;
    headers["Content-Type"] = "application/json";
    conn->SetHeaders(headers);
    RestClient::Response r = conn->post("/", payload);

    // translate r back to what the end-user wants
}

Environment and debugging details

Thanks for any help in the right direction!

bundle json-cpp with restclient

most REST APIs are JSON based anways. So maybe it would make this a lot nicer to use if it came with an opinionated way of how JSON responses are parsed into objects. At least look into it.

clang: error: linker command failed with exit code 1

I am trying to build a simple project with this library and so far no success yet. I think i am doing something.

I built the library with prefix set to --prefix=/usr/local/restclient-cpp.

I copied the sample code from the repo and tried to compile it with the flags below.

g++ -I /usr/local/restclient-cpp/include -std=c++11 main.cpp -o main -v

Below is the output.

`Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.11.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 264.3.102 -v -dwarf-column-info -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.3.0 -I /usr/local/restclient-cpp/include -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/joefazee/Desktop/curl-test -ferror-limit 19 -fmessage-length 203 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.11.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/s9/w9447kdn4pd5b44ldn7xmxm80000gp/T/main-8a7637.o -x c++ main.cpp
clang -cc1 version 7.3.0 (clang-703.0.31) default target x86_64-apple-darwin15.4.0
ignoring nonexistent directory "/usr/include/c++/v1"

include "..." search starts here:

include <...> search starts here:

/usr/local/restclient-cpp/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1
/usr/local/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.3.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.11.0 -o main /var/folders/s9/w9447kdn4pd5b44ldn7xmxm80000gp/T/main-8a7637.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.3.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"RestClient::del(std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator > const&)", referenced from:
_main in main-8a7637.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)`

How to put using uploadobject and the read callback function ?

Can we have an example in the documentation ? The current documentation says the following :

RestClient::Response RestClient::Connection::put (const std::string & url, const std::string & data )
HTTP PUT method.

Parameters: url to query, data HTTP PUT body
Returns response struct

  • initialize upload object
  • Now specify we want to PUT data
  • set read callback function
  • set data object to pass to callback function
  • set data size

Add method to set user-agent

Add a method to set a custom user agent. This could prepend a custom agent onto the existing restclient-cpp user agent, eg User-Agent: foobar/1.2.3 restclient-cpp/2.0.0.

This is useful when building a custom reporter on top of a REST client API.

i can't find the version.h

in the restclient.cpp, #include "restclient-cpp/version.h",but i can't find the version.h,so that i can't put it to my project...can you help me?

License

Hello, what type of LICENSE is associated with this software? The license file gives a description of what is expected; however, it does not explicitly call out a license. I am looking to describe the license terms and am wondering if it is one of the well known license types (MIT, BOOST, Public Domain/Unlicense, etc...). Thank you

Small memory leak in post and put methods

Using Valgrind, I found a small memory leak.

You need to add the following code to the post and put methods near the end of the method code.

curl_slist_free_all(header);

Error: Undefined symbols for architecture x86_64

Command

$ make

Environment

OSX Yosemite 10.10.2
GNU Make 3.81
gxx version 6.1.0 

Error

Undefined symbols for architecture x86_64:
  "RestClient::post(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)"
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

json query string

Using restclient for a rest api that requires a json query string.
constructing the query string with Jasonvalue.
The ruby server receiving the string cannot process the json as it seems to have "escaped quotes" e.g. {"key":"value"} etc which means it doesn't seem to process it.
when i print out the json to stdout there are no escapes showing.

Undefined reference to `RestClient::get(std::string const&)'

Hello,

So I installed all the files using the configure, make and make install commands.
Now when I use the example I get the following error:
Undefined reference to RestClient::get(std::string const&).
Do you have any idea how to fix this?

cURL include not necessary in restclient.h

When using just the simple API provided by restclient.h, The curl include seems to be unnecessary:

#include <curl/curl.h> // needed?

If the consumer of restclient-cpp wants to use only restclient.h, it would be best to avoid having to configure the curl include path. (Even pointing to libcurl.lib can be avoided if restclient-cpp is built using the "Link Library Dependencies" option in VS.)

Great library, BTW!

Curl problem

Hello,
I am getting the following error:
include/restclient-cpp/restclient.h:12:23: fatal error: curl/curl.h: No such file or directory #include <curl/curl.h>
Even though I have libcurl3 installed on ubuntu.
Still, this is what I get during configure.
checking curl/curl.h usability... no checking curl/curl.h presence... no checking for curl/curl.h... no

Could you please provide me some insight, kind of a noob here :$ :)

improve method usability wrt configuration options

We have now introduced some more configurable options like auth and timeouts, and are looking to add support for headers and cookies. We also have 2 ways now to set configuration options: via passed in parameters and via helper methods. I think this should be converged into one way of doing configuration. So we basically have two options:

  1. Introduce a configuration struct and keep the static nature of the methods
    This means the calling convention stays mostly the same, but for more advanced usage patterns we will have to pass in a struct with options like timeout, headers, etc set.
  2. Go a more OO oriented route.
    This basically means turning the static namespace into an object and being able to call helper methods on it like set_timeout().

I'm not convinced yet which one is nicer to use, so I'm open for feedback on this one.

make valgrind run blocking on CI

the CI build should block if valgrind finds leaks. The invocation in the Makefile for make valgrind needs to be changed to valgrind --leak-check=full --error-exitcode=1 ./test-program. However right now this results in some reported leaks so I will fix those first before adding it blocking to the CI build.

[Q] oAuth2 authentication

Is it possible to use oAuth2 with this library? I would like to build a client for the Google Rest APIs.

How to check timeout expiration in a rest connection ??

Hello,

I use a multithreaded application where a c++ thread sends some information in a google protocol buffer to a Java thread using RestClient. I want to initialize a timeout of the Rest connection so that to check expiration timeout in case the Java thread do'nt respond. How to do that ? This is the c++ main code.

                RestClient::init();
		RestClient::Connection* conn = new RestClient::Connection(applicationUrl);
		conn->SetTimeout(5);
		RestClient::HeaderFields headers;
		headers["Accept"] = "application/x-protobuf";
		conn->SetHeaders(headers);
		
                std::string url(applicationUrl);
	        string restRoot((VoiceLayer::getConfigParamValue("REST_ROOT")).c_str());
	        url.append(restRoot);
		string serialized;
	        stvproto::StartEvent event;
                event.set_info(info);
                event.SerializeToString(&serialized);
	
                RestClient::Response r=conn->post(url, serialized); 
                if (r.code==408)
                   cout <<"Request timeout!!" << endl;

This code results in a response code=-1 ! What's wrong in my code ?? please help me !
Thank you a lot !

Best regards,
Nabila

Documentation does not match actual API

In README.md the Content-Cype is supplied in the example for making a POST:
RestClient::Response r = conn->post("/post", "text/json", "{\"foo\": \"bla\"}")
However, include/restclient-cpp/connection.h has the POST api as:

    RestClient::Response post(const std::string& uri,
                              const std::string& data);

In the current API, this should probably be two calls, one to conn->AppendHeader("Content-Type", "text/json") and then conn->post(uri,data)

This is also true for the PUT example.

Memory leak on Fail to query/No response

I found another memory leak in restclient.cpp.

If the remote server does not respond to the request, line 223 returns from the PUT function before doing the CURL cleanups on lines 229 thru 231. This causes a memory leak.

I tested the following code change and it resolves the leak. This same issue is elsewhere in the file as well.

if (res != CURLE_OK)
{
ret.body = "Failed to query.";
ret.code = -1;
//return ret; //Commented the return
} else { //else added here
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
ret.code = static_cast(http_code);
}

Function now has only one return statement.

undefined reference to RestClient::Connection::Connection(std::string const&)

Hello everybody!

Expected behaviour

As read in the documentation, it should be possible to create an object (lets say a pointer to an object) of the class connection. For getting that, it is supposed that should be coded the next sencence:
-RestClient::Connection* conn = new RestClient::Connection("http://url.com");

Actual behaviour

When I am trying to build the following program, I get the error in the title of this issue.

#include
#include "connection.h"
#include "restclient.h"

int main(){

RestClient::Response r = RestClient::get("www.google.es");
std::cout << r.code;
RestClient::init();
RestClient::Connection* conn = new RestClient::Connection("www.google.es");
return 0;
}

Environment and debugging details

Eclipse

  • g++ 4.8.4
  • Ubuntu trusty
  • undefined reference to RestClient::Connection::Connection(std::string const&)

The problem is that there is no problem using the RestClient::get method, but however I cannot build any object of the RestClient::Connection class, so I cannot do the request I want.

The request I want to do needs to have a kind of special header, so I cannot do a normal get request to a single url.

Anybody know how could I fix it? I read it in the documentation and I have tried to check in the test, in order to follow the way it is done there, but is not running neither. I have included the path for the headers and added the library -l restclient-cpp, but I am wondering if the fail could be there, and it is not foud because of there is a different library wich contains it.

improve the unit test suite

right now it mostly checks the HTTP return code, to make sure everything went fine. In order to check for some more sophisticated things, we need JSON support. So the steps would be:

  • add JSON-CPP to the test build (this should be done similar to how gtest is included)
  • use it in the test suites to assert things that httpbin gives us

add custom / additional header fields

I'd like to use this little library in a toy project of mine. However, I couldn't find a way to add additional header fields to any of the REST method calls.

Is it planned to support that in the near future? What about the HEAD method? Are you going to support this too?

A .deb for ARM (raspberrypi)?

I built this on a raspberrypi, but I haven't found a .deb file in the packagecloud repository. Is it possible to upload an ARM .deb too?

Whether there is wince version restclient

Thanks your software, I just wonder whether there is a version for Wince, when I tried in my VS2008, I got some error message:(, I am very appreciate if there is a version for WINCE

Build with CMake?

Would you merge a change that adds CMake support? I'm having a pretty evil time using this project in my CMake-based project.

SSL Errors

Hia, thanks for your work.

I Suggest two additions to go around ssl errors.
Maybe switchable via parameter or however you like:

  • Parameter "insecure" and then:
    //SSL Ignore all err
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_easy_setopt(curl, CURLOPT_SSLVERSION, 3);
  • Parameter "verbose"
    //get error details
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);

Greetings & Thanks
Philipp

Please confirm if license of restclient-cpp is MIT license

Hi Daniel,
The license of restclient-cpp project looks exactly like MIT license, but it is not explicitly mentioned.
Could you kindly confirm that license of restclient-cpp is MIT license? The clarification would immensely help users who are conscious about licenses and attribution.
Thanking you,

  • Amit

Android NDK Support and iOS support

Hi,
Can this be used on Android and iOS apps? Any info on how to build using latest Android NDK and Android studio will be really helpful.
Thanks,

built .so can be linked to libgtest.so

I think the libgtest.so should only be built into the test_program and not the shared object, since it is not used at runtime.
From looking at the Makefile.am, it looks like -lgtest is included in the test_program in all cases, so I believe a simple fix is to just remove the line
AC_CHECK_LIB([gtest], [main])
from the configure.ac

Does this sound reasonable?

Includes Error

  • I had errors while trying to start using restclient-cpp within my own project due to missing includes. These are all the includes required to work for me.
#include <libcurl\curl.h>
#include <string>
#include <map>
#include <cstdlib>
#include "meta.h"
#include <algorithm>
#include <iostream>
#include <functional>
#include <locale>
#include <numeric>
#include <cctype>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.