Coder Social home page Coder Social logo

libcpr / cpr Goto Github PK

View Code? Open in Web Editor NEW
6.2K 126.0 896.0 1.71 MB

C++ Requests: Curl for People, a spiritual port of Python Requests.

Home Page: https://docs.libcpr.org/

License: Other

CMake 5.81% C 0.17% C++ 93.47% Shell 0.50% Makefile 0.06%
c-plus-plus libcurl http requests hacktoberfest cpp library

cpr's Introduction

C++ Requests: Curl for People

Documentation CI Gitter

Announcements

Supported Releases

Release Min. C++ Standard Status Notes
master cpp17 alt text
1.10.x cpp17 alt text
1.9.x cpp11 alt text Supported until 01.01.2025
<= 1.8.x cpp11 alt text

TLDR

C++ Requests is a simple wrapper around libcurl inspired by the excellent Python Requests project.

Despite its name, libcurl's easy interface is anything but, and making mistakes, misusing it is a common source of error and frustration. Using the more expressive language facilities of C++17 (or C++11 in case you use cpr < 1.10.0), this library captures the essence of making network calls into a few concise idioms.

Here's a quick GET request:

#include <cpr/cpr.h>

int main(int argc, char** argv) {
    cpr::Response r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
                      cpr::Authentication{"user", "pass", cpr::AuthMode::BASIC},
                      cpr::Parameters{{"anon", "true"}, {"key", "value"}});
    r.status_code;                  // 200
    r.header["content-type"];       // application/json; charset=utf-8
    r.text;                         // JSON text string
    return 0;
}

And here's less functional, more complicated code, without cpr.

Documentation

Documentation
You can find the latest documentation here. It's a work in progress, but it should give you a better idea of how to use the library than the tests currently do.

Features

C++ Requests currently supports:

  • Custom headers
  • Url encoded parameters
  • Url encoded POST values
  • Multipart form POST upload
  • File POST upload
  • Basic authentication
  • Bearer authentication
  • Digest authentication
  • NTLM authentication
  • Connection and request timeout specification
  • Timeout for low speed connection
  • Asynchronous requests
  • ๐Ÿช support!
  • Proxy support
  • Callback interfaces
  • PUT methods
  • DELETE methods
  • HEAD methods
  • OPTIONS methods
  • PATCH methods
  • Thread Safe access to libCurl
  • OpenSSL and WinSSL support for HTTPS requests

Planned

For a quick overview about the planed features, have a look at the next Milestones.

Usage

CMake

fetch_content:

If you already have a CMake project you need to integrate C++ Requests with, the primary way is to use fetch_content. Add the following to your CMakeLists.txt.

include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
                         GIT_TAG 3b15fa82ea74739b574d705fea44959b58142eb8) # Replace with your desired git commit from: https://github.com/libcpr/cpr/releases
FetchContent_MakeAvailable(cpr)

This will produce the target cpr::cpr which you can link against the typical way:

target_link_libraries(your_target_name PRIVATE cpr::cpr)

That should do it! There's no need to handle libcurl yourself. All dependencies are taken care of for you.
All of this can be found in an example here.

find_package():

If you prefer not to use fetch_content, you can download, build, and install the library and then use CMake find_package() function to integrate it into a project.

Note: this feature is feasible only if CPR_USE_SYSTEM_CURL is set. (see #645)

git clone https://github.com/libcpr/cpr.git
cd cpr && mkdir build && cd build
cmake .. -DCPR_USE_SYSTEM_CURL=ON
cmake --build . --parallel
sudo cmake --install .

In your CMakeLists.txt:

find_package(cpr REQUIRED)
add_executable(your_target_name your_target_name.cpp)
target_link_libraries(your_target_name PRIVATE cpr::cpr)

Tests

cpr provides a bunch of tests that can be executed via the following commands.

git clone https://github.com/libcpr/cpr.git
cd cpr && mkdir build && cd build
cmake .. -DCPR_BUILD_TESTS=ON # There are other test related options like 'CPR_BUILD_TESTS_SSL' and 'CPR_BUILD_TESTS_PROXY'
cmake --build . --parallel
ctest -VV # -VV is optional since it enables verbose output

Bazel

Please refer to hedronvision/bazel-make-cc-https-easy.

Packages for Linux Distributions

Alternatively, you may install a package specific to your Linux distribution. Since so few distributions currently have a package for cpr, most users will not be able to run your program with this approach.

Currently, we are aware of packages for the following distributions:

If there's no package for your distribution, try making one! If you do, and it is added to your distribution's repositories, please submit a pull request to add it to the list above. However, please only do this if you plan to actively maintain the package.

NuGet Package

For Windows, there is also a libcpr NuGet package available. Currently, x86 and x64 builds are supported with release and debug configuration.

The package can be found here: NuGet.org

Requirements

The only explicit requirements are:

  • a C++17 compatible compiler such as Clang or GCC. The minimum required version of GCC is unknown, so if anyone has trouble building this library with a specific version of GCC, do let us know
  • in case you only have a C++11 compatible compiler available, all versions below cpr 1.9.x are for you. The 1.10.0 release of cpr switches to C++17 as a requirement.
  • If you would like to perform https requests OpenSSL and its development libraries are required.

Building cpr - Using vcpkg

You can download and install cpr using the vcpkg dependency manager:

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

The cpr 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.

Building cpr - Using Conan

You can download and install cpr using the Conan package manager. Setup your CMakeLists.txt (see Conan documentation on how to use MSBuild, Meson and others). An example can be found here.

The cpr package in Conan is kept up to date by Conan contributors. If the version is out of date, please create an issue or pull request on the conan-center-index repository.

cpr's People

Contributors

adam-nielsen avatar alex-87 avatar andregleichner avatar bobjansen avatar com8 avatar cpsauer avatar dbungert avatar dependabot[bot] avatar dilshodm avatar edmbernard avatar felixvanorder avatar ithewei avatar jmhersc avatar jsouquie avatar kingkili avatar leviliangtw avatar nightlark avatar nyorain avatar ruleofthrees avatar saendigphilip avatar simon-berger avatar smiley avatar thedrow avatar tstack avatar vittorioromeo avatar waltronix avatar whoshuu avatar xiaoloudongfeng avatar xloem avatar zydxhs 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cpr's Issues

Windows compatibility (MSVC14)

I tried giving it a go in Visual Studio 2015 Community, and it's mostly OK save for a few fixable issues:

Compilation errors

Code Description Project Filename Line no.
C2512 'Response': no appropriate default constructor available put_tests D:\GitHub\cpr\test\put_tests.cpp 192
C2512 'Response': no appropriate default constructor available delete_tests D:\GitHub\cpr\test\delete_tests.cpp 163
C2512 'Response': no appropriate default constructor available async_tests D:\GitHub\cpr\test\async_tests.cpp 17
C2338 tuple_element index out of bounds callback_tests ...\include\utility (361) (from D:\GitHub\cpr\test\callback_tests.cpp) 486

Linkage errors

Looks like Google Test uses static linkage, while CPR tests use dynamic linkage. There's a CMake variable to make it switch to the CRT DLL, so I'm adding that on Windows to fix this. (IF(WIN32) ... ENDIF())

Avoid unnecessary runtime overhead due to `std::string` "sink" parameters

Most of the constructors in cpr take std::string parameters by const std::string&.

Digest(const std::string& username, const std::string& password);

This is not the most efficient way of dealing with "sink" parameters.
Refer to isocpp/CppCoreGuidelines's parameter passing diagram.

My suggestion is using perfect-forwarding, to always make sure sink std::string members are initialized as efficiently as possible. Example:

#define FWD(...) \
    ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)

template<typename TS0, typename TS1>
Digest(TS0&& username, TS1&& password) :
            Authentication{FWD(username), FWD(password)} {}

Put all public classes into a namespace to avoid pollution

All of the classes being in the global namespace is probably a no-go for a lot of applications. The right thing to do is to introduce at least one namespace out of respect for those applications.

The most obvious namespace to use is just cpr. If everything is behind that namespace, that should be enough for the most part. Tests can use the normally bad using namespace cpr to avoid onerous changes in that directory.

Update CURL

I have submitted a PR tu bagder/curl (curl/curl#488) with the same content as the one submitted to your fork, now I'm testing whoshuu/cpr#master with bagder/curl#master and everything seems to work ok (Win7 64bits MSVC2015).

I've just had to choose in CMake between CMAKE_USE_OPENSSL and CMAKE_USE_SCHANNEL because under both macros there is the same definition in curl/lib/urldata.h (line#273 and line#322)

ssl_connect_state connecting_state;

Both seems to be "ON" by default... I don't know what the difference is among all the USE_XXX macros in that file, but I can confirm that last revision works with CPR (I'll try to run all the tests, but my computer crash with them :S)

Update this dependency (after PR merge and tag so install in windows works ok)?

Provide CPRConfig.cmake to allow easy find_package()

I'm all but a cmake expert but if I interpret this
http://www.cmake.org/cmake/help/git-master/manual/cmake-packages.7.html#creating-packages
link and my cmake output correctly, supplying CPRConfig.cmake
would allow downstream projects to include cpr as a dependency like this:

 set ( CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} vendor/cpr/)
 find_package ( CPR REQUIRED )
 include_directories ( ${CPR_INCLUDE_DIRS} )

and then use ${CPR_LIBRARIES} in target_link_libraries(). Instead of vendoring it could also be installed in the system path getting rid of the first line in the snippet above.

Document build settings and integration methods

Right now, there's only documentation for how to build the library and tests. This is far from ideal -- the most important piece of information that needs to be put up front is how to integrate this library into an existing or new codebase. Building the library/tests should be in a separate contributors section of the documentation.

Two methods of integration should be detailed:

  1. Using git submodules and CMake to build this library as a subproject of a larger application.
  2. Using CMake to pull (as in, use find_package) this project into a downstream application if they're in separate project directories. This is an extension of the work done in #28.

Additionally, all of the build options should be enumerated and explained in a separate section.

Use develop/master branching model

Currently master is a snapshot of the most recent official release, and release/x.x branches are where the most recent development work happens. This isn't ideal because the release branch should be feature stable as bugs are ironed out, and development shouldn't be halted just because a release is taking time to complete.

POST Requests with raw post data

Maybe I'm missing something but I couldn't find a way to do a post request with a custom content-type and raw body which is needed for many REST APIs that expect e.g. JSON in a POST body.

PATCH methods

As per RFC 5789. Mechanically, the data being sent up should be similar to what's being done for a PUT, even if the semantics are all not the same (PUT's are usually for whole object replacements, PATCH's are usually for partial updates to existing objects).

The curl option to set is this:

curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "PATCH");

The documentation can probably be folded into the header PUT Requests under a more inclusive name. Testing is a bit more involved, but can be done after the main implementation and documentation, which should be easy.

Handle `curl_easy_perform()` errors

Hello! I'd like to be able to detect with a finer-grained resolution errors that prevent Curl from performing a request. It seems the right place to start is to change session.cpp:350 to capture the return value from curl_easy_perform(), and then perhaps add some error fields to the cpr::Response that is returned.

I'm happy to open a PR with this feature added if there were interest in it; and if so, I'd like to get your opinion on the right way to structure this feature.

Tests are failing in debug mode due to a destroyed, locked mutex

While looking into exporting test results into XML for actual reporting (more on that later), I saw that tests are passing on my end but marked as failed by CTest.

Looks like this is because the unit tests are destroying some mutex while it's still locked.

9:
9: [----------] 8 tests from CallbackPutTests
9: [ RUN      ] CallbackPutTests.CallbackPutLambdaStatusTest
9: [       OK ] CallbackPutTests.CallbackPutLambdaStatusTest (50 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutLambdaTextTest
9: [       OK ] CallbackPutTests.CallbackPutLambdaTextTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutLambdaStatusReferenceTest
9: [       OK ] CallbackPutTests.CallbackPutLambdaStatusReferenceTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutLambdaTextReferenceTest
9: [       OK ] CallbackPutTests.CallbackPutLambdaTextReferenceTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutFunctionStatusTest
9: [       OK ] CallbackPutTests.CallbackPutFunctionStatusTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutFunctionTextTest
9: [       OK ] CallbackPutTests.CallbackPutFunctionTextTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutFunctionStatusReferenceTest
9: [       OK ] CallbackPutTests.CallbackPutFunctionStatusReferenceTest (51 ms)
9: [ RUN      ] CallbackPutTests.CallbackPutFunctionTextReferenceTest
9: [       OK ] CallbackPutTests.CallbackPutFunctionTextReferenceTest (51 ms)
9: [----------] 8 tests from CallbackPutTests (407 ms total)
9:
9: [----------] Global test environment tear-down
9: [==========] 40 tests from 5 test cases ran. (2985 ms total)
9: [  PASSED  ] 40 tests.
9: f:\dd\vctools\crt\crtw32\stdcpp\thr\mutex.c(51): mutex destroyed while busy
9/9 Test #9: cpr_callback_tests ...............***Failed    8.93 sec

0% tests passed, 9 tests failed out of 9

And it looks like this doesn't happen on AppVeyor because this is a debug check, and tests are run in release mode there. They should be switched to debug mode to catch this sort of thing.

I also found the mutex in question in server.cpp:

void runServer(struct mg_server* server) {
    {
        std::lock_guard<std::mutex> server_lock(server_mutex);
        mg_set_option(server, "listening_port", SERVER_PORT);
        server_cv.notify_one();
    }

    do {
        mg_poll_server(server, 1000);
    } while (!shutdown_mutex.try_lock());

    std::lock_guard<std::mutex> server_lock(server_mutex);
    mg_destroy_server(&server);
    server_cv.notify_one();
}

shutdown_mutex is locked in the while condition, but isn't unlocked before exiting the scope. GTest also doesn't notice this as this check is done on-destruction -- and shutdown_mutex is a global object, so this is thrown in the static deinitiailization phase. (:disappointed:)

shutdown_mutex and other assorted utilities should be a class member (and I'm guessing that this wasn't noticed before as this is a test utility class) so any issues would be reported and taken care of at the proper time. (GTest could halt and report a test environment error)

I'm fixing this locally now and pushing in an upcoming PR.

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.