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

Overview

C++ Requests: Curl for People

Documentation CI Gitter

Announcements

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++11, 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::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

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 beb9e98806bb84bcc130a2cebfbcbbc6ce62b335) # The commit hash for 1.7.2. Replace with the latest 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.

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.

Requirements

The only explicit requirements are:

  • a C++11 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 me know
  • 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.

Issues
  • cmake config

    cmake config

    I'm still creating a FreeBSD port, and it would be great to have a cmake config for cpr in order to do stuff like find_package(cpr).

    Thank you very much in advance.

    opened by part1zano 30
  • progress callback draft

    progress callback draft

    Hi! I added an issue here #432 a few minutes ago, but then i realised that there was an already existing issue that's been open for quite a while sadly #111.

    This is a quick draft / example of adding a progress callback option, and it works 😄 . This allows us to create progress bars and also cancel any request early by returning a non zero value from the callback!

    If there's any chance of adding this and you want me to clean up anything, let me know! Thanks

    Tests Needed :rotating_light: Feature :sparkles: Documentation Needed :green_book: 
    opened by ITotalJustice 20
  • "free(): invalid pointer" when using CPR with conan

    Description

    When using CPR with conan I get this error when trying to run the binary

    free(): invalid pointer
    Aborted
    

    Expected Behavior

    Should work

    Actual Behavior

    It breaks

    Possible Fix

    Steps to Reproduce

    1. Use CPR with conan

    Context

    I was trying to reach out to a website and get the response body/text.

    Your Environment

    • Version used: 1.6.2
    • Where did you get it from (e.g. conan, vcpkg, master, ...): conan
    • Operating System and version: Linux ari-gentoo 5.14.2-gentoo #1 SMP Thu Sep 9 18:26:44 EEST 2021 x86_64 Intel(R) Core(TM) i3-8130U CPU @ 2.20GHz GenuineIntel GNU/Linux
    • Link to a small example: https://replit.com/@B00bleaTea/ghufhuerhyur4gyfghryfhryhfyufhurehufberfhberhbfhuerbfhuerf#main.cpp

    Run this when trying the example (in the shell tab):

    chmod a+rx ./build.sh
    
    ./build.sh
    
    ./bin/conantest 'https://google.com'
    
    Bug :bug: Needs Investigation :mag: 
    opened by TruncatedDinosour 17
  • Static linking (Windows)

    Static linking (Windows)

    Hello. I am trying to use a static version of the library installed through VCPKG using the command./vcpkg install cpr:x86-windows-static but i am getting many errors. image

    This are my settings: image image

    Bug :bug: Build :construction_worker: Windows :tv: 
    opened by John4266 17
  • Provide CPRConfig.cmake to allow easy find_package()

    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.

    Documentation :books: Build :construction_worker: 
    opened by niklas88 17
  • Empty response text and status code 0 at example code

    Empty response text and status code 0 at example code

    Code

    #include <cpr/cpr.h>
    #include <iostream>
    
    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::Parameters{{"anon", "true"}, {"key", "value"}});
        std::cout << r.status_code << std::endl << r.text;
        return 0;
    }
    

    Expected Behavior

    It should print the status code and the response body

    Actual Behavior

    It prints 0

    Your Environment

    • Where did you get it from (e.g. conan, vcpkg, master, ...): master
    • Operating System and version: MacOS 12.1
    • Build System: g++/clang++
    Needs Investigation :mag: 
    opened by Pxddyk45 16
  • Add ability to install library and headers through CMake

    Add ability to install library and headers through CMake

    There are three competing pull requests right now that implement this. My laziness has unfortunately resulted in some duplicate work 😥 .

    #176 #132 #56

    Unbiased discussion on the pros and cons of each approach would be appreciated. The immediate goal is to make make install in a sane way. The long term goal is to make packaging the library (for something like Homebrew for instance) feasible so it can be distributed without git.

    Build :construction_worker: Discussion :interrobang: 
    opened by whoshuu 15
  • Problems with HTTPS requests.

    Problems with HTTPS requests.

    Description

    The problem occurs when I'm trying to send any type of request to an https server. With http it works just fine. If server supports both, http and https it also works when I'm trying to send https request. To make sure that issue is actual I tried to install libcpr on another computer, and it did the same. Moreover, I used libcpr for a month and there were no problems ever, but as soon as I reinstalled the library, this happened. Also, I tried to test libCurl, and it sends https requests to any server.

    Expected Behavior

    Sending HTTPS requests as always.

    Actual Behavior

    Does send only HTTP requests and returns code 0 when trying to send HTTPS.

    Your Environment

    • Version used: 1.7.2
    • Where did you get it from (e.g. conan, vcpkg, master, ...): vcpkg
    • Operating System and version: Windows 10 Pro 21H1, Build 19043.1526
    • Link to a small example: https://imgur.com/4TOPax9
    curl :globe_with_meridians: 
    opened by 1Klas 14
  • CPR on Raspberry Pi

    CPR on Raspberry Pi

    Hi there,

    For a home project I would like to use CPR on the raspberry pi 2b+. I made a small test program to read and write data to a Rest Api, but the POST request hangs forever and is not executed on the Rest Api. The GET request works fine. I build the the same code also on my desktop(Ubuntu 20.04 amd64) and that gives no problems. My first attempt was cross-compiling with various toolchains, but it always hangs on the POST/PUT request. Finally I did a local build on the raspberry pi and it kept hanging on the POST request.

    The c++ code is:

    #include <iostream>
    #include <cpr/cpr.h>
    #include "nlohmann/json.hpp"
    
    using json = nlohmann::json;
    
    int main()
    {
    	std::cout << "Hello World\n";
    
    	auto r = cpr::Get(cpr::Url("http://192.168.10.188:3001/environment?select=location,pressure"));
    
    		std::cout << r.status_code << std::endl;
    		std::cout << r.header["content-type"] << std::endl;
    		std::cout << r.text << std::endl;
    
    	json msg;
    	msg["location"] = "livingroom";
    	msg["temperature"] = 27.5;
    	msg["pressure"] = 1006.1;
    	msg["humidity"] = 61;
    	msg["time"] = "2020-07-01T13:21:22.18542+00:00";
    	std::cout << msg.dump() << std::endl;
    	r = cpr::Post(cpr::Url("http://192.168.10.188:3001/environment"),
    				  cpr::Header{{"Content-Type", "application/json"},
    							  {"Content-Length", std::to_string(msg.dump().length())}},
    				  cpr::Body(msg.dump()));
    
    	std::cout << r.status_code << std::endl;
    	std::cout << r.header["content-type"] << std::endl;
    	std::cout << r.text << std::endl;
    
    	return 0;
    }
    

    my makefile is:

    OBJECTS=build/main.o 
    
    BUILDDIR=build/
    SOURCEDIR=src/
    LIB=-L/usr/local/lib/ -L/usr/local/lib
    # include the src directory for rapidjson and spdlog includes
    INC=-Isrc
    MKDIR_P = mkdir -p
    
    .PHONY : all
    all: $(BUILDDIR)testCprSimple
    
    $(BUILDDIR)testCprSimple : $(OBJECTS)
    	g++ -o $(BUILDDIR)testCprSimple $(OBJECTS) $(LIB) -latomic -lcpr -lcurl
    
    $(BUILDDIR)main.o : $(SOURCEDIR)main.cpp
    	g++ -o $(BUILDDIR)main.o $(SOURCEDIR)main.cpp -std=c++14 $(INC) -g3 -O2 -Wall -c -fmessage-length=0
    
    # There are two reasons to use a phony target: 
    # to avoid a conflict with a file of the same name, and to improve performance. 	
    .PHONY: clean
    clean :
    	rm $(BUILDDIR)testCprSimple $(OBJECTS)
    # Tab must be used as indentation
    

    I am using 2020-02-13-raspbian-buster-lite as OS on the raspberry pi with gcc (Raspbian 8.3.0-6+rpi1) 8.3.0

    I have installed and build CPR successfully on the raspberry pi with:

    git clone https://github.com/whoshuu/cpr.git
    cd cpr
    git submodule update --init
    mkdir build; cd build
    cmake -DCMAKE_USE_OPENSSL=OFF ..
    make
    sudo make install
    

    The curl program itself is working with POST request on the pi: curl http://192.168.10.188:3001/environment -X POST -H "Content-Type: application/json" -d '{"location":"livingroom", "temperature":23.2,"pressure":1002.5, "humidity":49, "time":"2020-07-01T13:21:22.18542+00:00"}'

    Am i forgetting something for the raspberry pi / arm build or is it a bug? Thanks in advance for your help.

    Bug :bug: 
    opened by skipper85 14
  • HTTP Error 411 while making POST request to Microsoft Azure Workspace

    HTTP Error 411 while making POST request to Microsoft Azure Workspace

    I am trying to set up a remote log system on the Microsoft Azure Workspace. I am using cpr POST request to send sample JSON data over to the server. The code I used is as follows:

    #include <iostream>
    #include <map>
    #include <utility>
    #include <nlohmann/json.hpp>
    using json = nlohmann::json;
    #include <cpr/cpr.h>
    #include <time.h>
    using std::cout;
    using std::cerr;
    using std::endl;
    
    #include <string>
    using std::string;
    
    #include "cryptopp/cryptlib.h"
    using CryptoPP::Exception;
    
    #include "cryptopp/hmac.h"
    using CryptoPP::HMAC;
    
    #include "cryptopp/sha.h"
    using CryptoPP::SHA256;
    
    #include "cryptopp/base64.h"
    using CryptoPP::Base64Encoder;
    using CryptoPP::Base64Decoder;
    
    #include "cryptopp/filters.h"
    using CryptoPP::StringSink;
    using CryptoPP::StringSource;
    using CryptoPP::HashFilter;
    
    
    
    typedef unsigned char byte;
    
    string CUSTOMER_ID = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    string SHARED_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    string METHOD = "POST";
    string CONTENT_TYPE = "application/json";
    string RESOURCE = "/api/logs";
    string uri = "https://" + CUSTOMER_ID + ".ods.opinsights.azure.com/api/logs?api-version=2016-04-01";
    string uri2 = "https://postman-echo.com/post";
    
    string sign(string key, string plain)
    {
        string mac, encoded;
        try
        {
    
            HMAC< SHA256 > hmac((byte*)key.c_str(), key.length());
    
            StringSource(plain, true,
                         new HashFilter(hmac,
                                        new StringSink(mac)
                         ) // HashFilter
            ); // StringSource
        }
        catch(const CryptoPP::Exception& e)
        {
            cerr << e.what() << endl;
        }
    
        encoded.clear();
        StringSource(mac, true,
                     new Base64Encoder(
                             new StringSink(encoded)
                     ) // Base64Encoder
        ); // StringSource
    
        return encoded;
    }
    
    string getTimestamp()
    {
        char buf[1000];
        time_t now = time(0);
        //struct tm tm = *localtime(&now);
        struct tm *tm = gmtime(&now);
        strftime(buf, sizeof buf, "%a, %d %b %Y %H:%M:%S GMT", tm);
        cout << buf << endl;
        return buf;
    
    }
    
    string getSignature(const string& customer_id, const string& shared_key, const string& date, size_t content_length,
                        const string& method, const string& content_type, const string& resource)
    {
        string x_headers = "x-ms-date:" + date;
        string string_to_hash = (method + "\n" + std::to_string(content_length) + "\n" + content_type + "\n" + x_headers + "\n" + resource);
        string decoded_share_key;
        decoded_share_key.clear();
        StringSource(shared_key,true, new Base64Decoder( new StringSink(decoded_share_key)));
        string encoded_hash = sign(decoded_share_key,string_to_hash);
    
        string signature = "SharedKey "+ customer_id + ":" +encoded_hash;
                //SharedKey {customer_id}:{encoded_hash}
    
        cout << signature << endl;
    
        return signature;
    }
    
    
    void post(string customer_id, string shared_key, string body, string log_type)
    {
        string date = getTimestamp();
    
        string signature = getSignature(CUSTOMER_ID, SHARED_KEY, date,
                                        body.length(), METHOD,
                                        CONTENT_TYPE, RESOURCE);
    
        auto response = cpr::Post(cpr::Url(uri),
                                    cpr::Header{{"content-type",CONTENT_TYPE},
                                                {"Authorization",signature},
                                                {"log-type",log_type},
                                                {"x-ms-date", date},
                                                {"content-length",std::to_string(body.length())}},
                                    cpr::Body(body));
    
    
    
        cout << response.url << endl;
        try {
            json j = json::parse(response.text);
            cout << j.dump(4) << endl;
        }
        catch (std::exception& e) {
            cout << e.what() << endl << endl;
            cout << response.text << endl;
        }
        cout << response.status_code << endl;
        if(response.status_code!=200)
        {
           cout << response.error.message << endl;
        }
        cout << response.elapsed << endl;
    }
    
    
    int main() {
        
        string log_type = "LoggingTest";
    
        json log_msg;
        json msg;
        log_msg["property1"] = "value1";
    
        msg = {log_msg};
    
        post(CUSTOMER_ID, SHARED_KEY, msg.dump(), log_type);
    
    
        return 0;
    }
    

    However, I'm always getting the same error like this (from response.text) :

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
    <HTML><HEAD><TITLE>Length Required</TITLE>
    <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
    <BODY><h2>Length Required</h2>
    <hr><p>HTTP Error 411. The request must be chunked or have a content length.</p>
    </BODY></HTML>
    

    Things I have tried and the results:

    1. Added "content-length" header: Same error
    2. Tried sending empty body with content length zero: Same error
    3. Made POST request to Postman-echo service to see if the library is unable to forward all data: Results as follows -

    3.1 Sending JSON data with authorization header:

    {
        "args": {},
        "data": {},
        "files": {},
        "form": {},
        "headers": {
            "accept": "*/*",
            "authorization": "SharedKey xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "host": "postman-echo.com",
            "user-agent": "curl/7.47.0",
            "x-amzn-trace-id": "Root=1-5ebe2da5-2275dd11f1b39c54c33fa6df",
            "x-forwarded-port": "443",
            "x-forwarded-proto": "https"
        },
        "json": null,
        "url": "https://postman-echo.com/post"
    }
    

    Notice that even though I'm sending JSON data with the POST request, Postman-echo does not show it. This is strange because when I did the same thing using a Python script, the result showed me both the data as well as the authorization signature.

    3.2 Sending JSON data without authorization header:

    {
         "args": {},
        "data": [
            {
                "property1": "value1"
            }
        ],
        "files": {},
        "form": {},
        "headers": {
            "accept": "*/*",
            "content-length": "24",
            "content-type": "application/json",
            "host": "postman-echo.com",
            "log-type": "LoggingTest",
            "user-agent": "curl/7.47.0",
            "x-amzn-trace-id": "Root=1-5ebe2f54-bfcef7b08ee37ca8efe47d90",
            "x-forwarded-port": "443",
            "x-forwarded-proto": "https",
            "x-ms-date": "Fri, 15 May 2020 05:57:40 GMT"
        },
        "json": [
            {
                "property1": "value1"
            }
        ],
        "url": "https://postman-echo.com/post"
    }
    

    Then Postman-echo is showing me the json data sent.

    In my understanding, generated key is not wrong, since in that case, authorization failure is the first error. The same code above, written in Python3 and Python2 worked correctly. This was the link I was following: https://docs.microsoft.com/de-de/azure/azure-monitor/platform/data-collector-api

    Is there any known issue of similar kind in the cpr library? Please help.

    Bug :bug: curl :globe_with_meridians: 
    opened by PatronusCoder 14
  • Multi-part file uploading via buffer does not work properly.

    Multi-part file uploading via buffer does not work properly.

    According to this feature "Add support for POST file uploads from in-memory buffers " https://github.com/whoshuu/cpr/pull/129.

    This support will allow you upload data from the buffer. so when we do something like :

    (1)
    std::vector<unsigned char> content{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
    auto url = Url{"https://httpbin.org/post"};
    auto response = cpr::Post(url, Multipart{
              { "fileContent", 
                 Buffer{content.begin(), content.end(), "test_file.txt"}
              }});
    

    and :

    (2)
    std::vector<unsigned char> content{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
    auto url = Url{"https://httpbin.org/post"};
    auto buff = Buffer{content.begin(), content.end(), "test_file.txt"};
    auto response = cpr::Post(url, Multipart{
              { "fileContent", 
                 buff
              }});
    

    ps: I use httpbin.org to check my request details.

    The expected behavior of POST request from both (1) and (2) should give the same result. They should be sent fileContent as a file not a form but only a code in (2) is work.The problem of (1) is fileContent was sent as a form (It should be a file).

    I'm not sure, I think this code might be related to this issue.

    https://github.com/whoshuu/cpr/blob/b5758fbc88021437f968fe5174f121b8b92f5d5c/cpr/session.cpp#L29-L30 https://github.com/whoshuu/cpr/blob/b5758fbc88021437f968fe5174f121b8b92f5d5c/cpr/session.cpp#L184 https://github.com/whoshuu/cpr/blob/b5758fbc88021437f968fe5174f121b8b92f5d5c/cpr/session.cpp#L217

    Bug :bug: Needs Investigation :mag: 
    opened by ninearif 14
  • How to send data that is not form-encoded?

    How to send data that is not form-encoded?

    When I send a post request using libcpr or Python's requests, the server returns:

    {'msg':'illegal request method','returnCode':'00405','data':'Content type'application/x-www-form-urlencoded; charset=UTF-8'not supported'}'.
    

    C++ Code:

    cpr::Response r = cpr::Post(cpr::Url{ "https://ec.95306.cn/api/bl/queryProduct/querySkb" },
    	cpr::Timeout{ 7000 },
    	cpr::Payload{ {"gbcc", "X8003"} });
    

    Python Code:

    data = {
        "gbcc": "X8003"
    }
    r = requests.post("https://ec.95306.cn/api/bl/queryProduct/querySkb", data=data)
    

    It is written in the docs of Python's requests that: There are times that you may want to send data that is not form-encoded. If you pass in a string instead of a dict, that data will be posted directly.Instead of encoding the dict yourself, you can also pass it directly using the json parameter (added in version 2.4.2) and it will be encoded automatically. So I use:

    data = {
        "gbcc": "X8003"
    }
    r = requests.post("https://ec.95306.cn/api/bl/queryProduct/querySkb", json=data)
    

    In this way, it works normally. So how do you use libcurl to do this?

    Another problem is how to pass a numeric value with payload, like this:

    cpr::Payload{ {"skbbbh",1} });
    
    Feature :sparkles: 
    opened by denglihong2007 2
  • cpr fails to compile when using submodules or FetchContent and Clang 11 on a Raspberry Pi 3B+

    cpr fails to compile when using submodules or FetchContent and Clang 11 on a Raspberry Pi 3B+

    Description

    cpr detects my Raspberry Pi 3B+ as ARMv6, which is wrong. 3B+ is ARMv8, but because Raspbian didn't support 64 bit back when I installed it, the OS identifies it as ARMv7l. The correct identification for this device is consequently ARMv7/ARMv7l, which is also how the device self-identifies in all commands.

    lscpu, lsb_release, and uname all pick up armv7 or armv7l. Additionally, one of the errors are about not supporting NEON, which from what I can tell, my CPU most certainly does. I assume this is down to how Clang interacts with the wrong architecture picked up by presumably cpr. That said, the compile errors seem to suggest this is CPR's fault (CMake seems to do the identifying, and zlib uses make), though I'm not entirely sure if it is, much less how.

    Relevant output from cmake ..:

    -- Arch detected: 'armv6'
    -- Basearch of 'armv6' has been detected as: 'arm'
    

    Conan picks up ARMv7, and forces its use across the board. GCC 8 also successfully compiles it for some reason, so not sure why Clang is an outlier here. It's definitely related to the incorrect ARMv6 identification, as Clang 11 when using Conan compiles everything correctly, without complaints.

    Also not sure if this is in any way relevant:

    CMake Warning at src/CMakeLists.txt:5 (add_executable):                                                                                                                                                                                        
    Cannot generate a safe runtime search path for target cprtest because files                                                                                                                                                                  
    in some directories may conflict with libraries in implicit directories:                                                                                                                                                                                                                                                                                                                                                                                                                    
    runtime library [libz.so.1] in /usr/lib/arm-linux-gnueabihf may be hidden by files in:                                                                                                                                                         
    /home/pi/build/cprtest/build/bin                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    Some of these libraries may not be found correctly.
    

    Expected Behavior

    cpr should compile

    Actual Behavior

    cpr doesn't compile

    $ make
    [  1%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/adler32.c.o
    [  1%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/chunkset.c.o
    [  2%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/compare258.c.o
    [  2%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/compress.c.o
    [  3%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/crc32.c.o
    [  3%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/crc32_comb.c.o
    [  4%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/deflate.c.o
    [  4%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/deflate_fast.c.o
    [  4%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/deflate_medium.c.o
    [  5%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/deflate_quick.c.o
    [  5%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/deflate_slow.c.o
    [  6%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/functable.c.o
    [  6%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/infback.c.o
    [  7%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/inffast.c.o
    [  7%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/inflate.c.o
    [  8%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/inftrees.c.o
    [  8%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/insert_string.c.o
    [  9%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/trees.c.o
    [  9%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/uncompr.c.o
    [ 10%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/zutil.c.o
    [ 10%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/arch/arm/armfeature.c.o
    [ 11%] Building C object _deps/zlib-build/CMakeFiles/zlib.dir/arch/arm/adler32_neon.c.o
    In file included from /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:11:
    /usr/lib/llvm-11/lib/clang/11.0.1/include/arm_neon.h:32:2: error: "NEON support not enabled"
    #error "NEON support not enabled"
     ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:23:5: error: unknown type name 'uint32x2_t'; did you mean 'uint32_t'?
        uint32x2_t adacc2, s2acc2, as;
        ^~~~~~~~~~
        uint32_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:26:20: note: 'uint32_t' declared here
    typedef __uint32_t uint32_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:24:5: error: unknown type name 'uint8x16_t'; did you mean 'uint16_t'?
        uint8x16_t t0 = vld1q_u8(taps), t1 = vld1q_u8(taps + 16);
        ^~~~~~~~~~
        uint16_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:25:20: note: 'uint16_t' declared here
    typedef __uint16_t uint16_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:24:21: warning: implicit declaration of function 'vld1q_u8' is invalid in C99 [-Wimplicit-function-declaration]
        uint8x16_t t0 = vld1q_u8(taps), t1 = vld1q_u8(taps + 16);
                        ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:26:5: error: unknown type name 'uint32x4_t'; did you mean 'uint32_t'?
        uint32x4_t adacc = vdupq_n_u32(0), s2acc = vdupq_n_u32(0);
        ^~~~~~~~~~
        uint32_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:26:20: note: 'uint32_t' declared here
    typedef __uint32_t uint32_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:26:24: warning: implicit declaration of function 'vdupq_n_u32' is invalid in C99 [-Wimplicit-function-declaration]
        uint32x4_t adacc = vdupq_n_u32(0), s2acc = vdupq_n_u32(0);
                           ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:27:13: warning: implicit declaration of function 'vsetq_lane_u32' is invalid in C99 [-Wimplicit-function-declaration]
        adacc = vsetq_lane_u32(s[0], adacc, 0);
                ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:31:9: error: unknown type name 'uint8x16_t'; did you mean 'uint16_t'?
            uint8x16_t d0 = vld1q_u8(buf), d1 = vld1q_u8(buf + 16);
            ^~~~~~~~~~
            uint16_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:25:20: note: 'uint16_t' declared here
    typedef __uint16_t uint16_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:32:9: error: unknown type name 'uint16x8_t'; did you mean 'uint16_t'?
            uint16x8_t adler, sum2;
            ^~~~~~~~~~
            uint16_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:25:20: note: 'uint16_t' declared here
    typedef __uint16_t uint16_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:33:17: warning: implicit declaration of function 'vaddq_u32' is invalid in C99 [-Wimplicit-function-declaration]
            s2acc = vaddq_u32(s2acc, vshlq_n_u32(adacc, 5));
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:33:34: warning: implicit declaration of function 'vshlq_n_u32' is invalid in C99 [-Wimplicit-function-declaration]
            s2acc = vaddq_u32(s2acc, vshlq_n_u32(adacc, 5));
                                     ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:34:17: warning: implicit declaration of function 'vpaddlq_u8' is invalid in C99 [-Wimplicit-function-declaration]
            adler = vpaddlq_u8(       d0);
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:35:17: warning: implicit declaration of function 'vpadalq_u8' is invalid in C99 [-Wimplicit-function-declaration]
            adler = vpadalq_u8(adler, d1);
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:36:16: warning: implicit declaration of function 'vmull_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmull_u8(      vget_low_u8(t0), vget_low_u8(d0));
                   ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:36:31: warning: implicit declaration of function 'vget_low_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmull_u8(      vget_low_u8(t0), vget_low_u8(d0));
                                  ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:37:16: warning: implicit declaration of function 'vmlal_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmlal_u8(sum2, vget_high_u8(t0), vget_high_u8(d0));
                   ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:37:31: warning: implicit declaration of function 'vget_high_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmlal_u8(sum2, vget_high_u8(t0), vget_high_u8(d0));
                                  ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:40:17: warning: implicit declaration of function 'vpadalq_u16' is invalid in C99 [-Wimplicit-function-declaration]
            adacc = vpadalq_u16(adacc, adler);
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:47:9: error: unknown type name 'uint8x16_t'; did you mean 'uint16_t'?
            uint8x16_t d0 = vld1q_u8(buf);
            ^~~~~~~~~~
            uint16_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:25:20: note: 'uint16_t' declared here
    typedef __uint16_t uint16_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:48:9: error: unknown type name 'uint16x8_t'; did you mean 'uint16_t'?
            uint16x8_t adler, sum2;
            ^~~~~~~~~~
            uint16_t
    /usr/include/arm-linux-gnueabihf/bits/stdint-uintn.h:25:20: note: 'uint16_t' declared here
    typedef __uint16_t uint16_t;
                       ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:49:17: warning: implicit declaration of function 'vaddq_u32' is invalid in C99 [-Wimplicit-function-declaration]
            s2acc = vaddq_u32(s2acc, vshlq_n_u32(adacc, 4));
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:49:34: warning: implicit declaration of function 'vshlq_n_u32' is invalid in C99 [-Wimplicit-function-declaration]
            s2acc = vaddq_u32(s2acc, vshlq_n_u32(adacc, 4));
                                     ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:50:17: warning: implicit declaration of function 'vpaddlq_u8' is invalid in C99 [-Wimplicit-function-declaration]
            adler = vpaddlq_u8(d0);
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:51:16: warning: implicit declaration of function 'vmull_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmull_u8(      vget_low_u8(t1), vget_low_u8(d0));
                   ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:51:31: warning: implicit declaration of function 'vget_low_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmull_u8(      vget_low_u8(t1), vget_low_u8(d0));
                                  ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:52:16: warning: implicit declaration of function 'vmlal_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmlal_u8(sum2, vget_high_u8(t1), vget_high_u8(d0));
                   ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:52:31: warning: implicit declaration of function 'vget_high_u8' is invalid in C99 [-Wimplicit-function-declaration]
            sum2 = vmlal_u8(sum2, vget_high_u8(t1), vget_high_u8(d0));
                                  ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:53:17: warning: implicit declaration of function 'vpadalq_u16' is invalid in C99 [-Wimplicit-function-declaration]
            adacc = vpadalq_u16(adacc, adler);
                    ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:59:14: warning: implicit declaration of function 'vpadd_u32' is invalid in C99 [-Wimplicit-function-declaration]
        adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc));
                 ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:59:24: warning: implicit declaration of function 'vget_low_u32' is invalid in C99 [-Wimplicit-function-declaration]
        adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc));
                           ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:59:45: warning: implicit declaration of function 'vget_high_u32' is invalid in C99 [-Wimplicit-function-declaration]
        adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc));
                                                ^
    /home/pi/build/cprtest/build/_deps/zlib-src/arch/arm/adler32_neon.c:62:12: warning: implicit declaration of function 'vget_lane_u32' is invalid in C99 [-Wimplicit-function-declaration]
        s[0] = vget_lane_u32(as, 0);
               ^
    24 warnings and 8 errors generated.
    make[2]: *** [_deps/zlib-build/CMakeFiles/zlib.dir/build.make:355: _deps/zlib-build/CMakeFiles/zlib.dir/arch/arm/adler32_neon.c.o] Error 1
    make[1]: *** [CMakeFiles/Makefile2:234: _deps/zlib-build/CMakeFiles/zlib.dir/all] Error 2
    make: *** [Makefile:149: all] Error 2
    

    Possible Fix

    N/A

    Steps to Reproduce

    1. Code: CMakeLists.txt:
    cmake_minimum_required(VERSION 3.10)
    project(cprtest)
    
    set (CMAKE_CXX_STANDARD 11)
    
    set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
    
    include(FetchContent)
    FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
                             GIT_TAG 871ed52d350214a034f6ef8a3b8f51c5ce1bd400) # The commit hash for 1.9.0. Replace with the latest from: https://github.com/libcpr/cpr/releases
    FetchContent_MakeAvailable(cpr)
    
    add_subdirectory(src)
    # vim:ft=cmake
    

    src/CMakeLists.txt:

    set (SOURCE_FILES
        cprtest/Main.cpp
    )
    
    add_executable(cprtest ${SOURCE_FILES})
    target_include_directories(cprtest PUBLIC ./)
    
    target_link_libraries(cprtest PUBLIC cpr::cpr)
    
    # vim:ft=cmake
    

    src/cprtest/Main.cpp:

    #include<iostream>
    
    #include <cpr/cpr.h>
    
    int main() {
        std::cout << "Hello, World!" << std::endl;
    }
    
    1. mkdir build && cd build && cmake .., with CXX=clang++ CC=clang, where clang++ and clang refer to Clang 11
    2. Lo and behold as the build explodes

    Your Environment

    • Version used: 1.9.0, 1.9.1, master
    • Where did you get it from (e.g. conan, vcpkg, master, ...): master/1.9.1 (as a submodule), 1.9.0 (FetchContent). 1.9.0 via Conan compiles fine
    • Operating System and version: Raspbian (Debian Buster 10)
    • Link to a small example: the code is included in the issue; this is about the cpr dependency itself, and not an execution error in either my or cpr's non-buildscript code.
    Build :construction_worker: Needs Investigation :mag: 
    opened by LunarWatcher 1
  • Enable ENABLE_DEBUG option when CMAKE_BUILD_TYPE is Debug

    Enable ENABLE_DEBUG option when CMAKE_BUILD_TYPE is Debug

    This enables more verbose logging like: STATE: DID => PERFORMING handle 0x56082ff9dd38; line 2218 (connection #0)

    Signed-off-by: Matthias Klein [email protected]

    Build :construction_worker: Enhancement :ok_hand: 
    opened by matthiasklein 0
  • Mongoose update

    Mongoose update

    Issue

    Solves #757. The webserver should use mongoose 7 instead of mongoose 6, for not using deprecated OpenSSL functions. Furthermore, the test cases simulating slow connections should be fixed.

    Tasks

    • [x] Update code, so that it supports the API of mongoose 7
    • [x] Find a way to simulate slow connections
    • [x] Update certificates to make the HTTPS tests work (see #773)
    • [x] Fix failing tests
    • [x] Fix remaining merge conflicts
    • [x] ~~Fix failing windows tests~~

    API Changes in mongoose 7

    Building

    • Parameter MG_ENABLE_SSL is now MG_ENABLE_OPENSSL

    Structural changes

    A few functionalities got outsourced to the callback

    • The context (in our case a pointer to an HttpServer or HttpsServer object) is passed as a callback parameter
    • The TLS connection gets initialized inside the callback for each connection, via the mg_tls_init method

    Methods -- Renames and changes

    • mg_send_head and mg_printf are now mg_http_reply. For each header, \r\n needs to be appended manually
    • mg_http_send_error does not exist anymore. We replace it with a static SendError method in AbstractServer
    • mg_http_listen is now used for binding and listening instead of mg_bind

    Structures -- Renames and changes

    • Trivial renaming of attributes, e.g. pointer attributes formerly named p are now ptr
    • http_message is now mg_http_message. HTTP headers are now stored in an array of struct mg_http_header

    Further details

    This list of changes is not complete. There are some further minor changes. For further information about mongoose 7, see the mongoose documentation.

    Simulation of slow connections

    TLDR; It works with mg_timer structs provided by mongoose (also see timer documentation, timer example). For further information, also see the comment below.

    Enhancement :ok_hand: 
    opened by saendigPhilip 10
Releases(1.9.1)
  • 1.9.1(Jul 31, 2022)

  • 1.9.0(Jul 18, 2022)

    This will be the last release where the minimum required C++ standard is cpp11. With the next major release (1.10.0) in ~late 2022/early 2023 we will increase the minimum C++ standard to cpp17 (Issue). This release (1.9.0) will still receive bug fixes, at least until the end of 2023, but all new features require from now on a cpp17 compatible compiler.

    Thanks to everyone who helped making this next release of cpr possible 🎉! Especially I would like to thank @simon-berger, @saendigPhilip @leviliangtw .

    In case everything goes like planed we will even offer a .deb package and a NuGet package soon. So stay tuned!

    What's Changed

    • Improve usability for ResponseStringReserve by @WorkingRobot in https://github.com/libcpr/cpr/pull/726
    • Make sure mutex is properly initialized by @cordbleibaum in https://github.com/libcpr/cpr/pull/728
    • Only use CURLOPT_SSLKEY_BLOB on curl 7.71.0+ by @alebcay in https://github.com/libcpr/cpr/pull/737
    • Unified basic, digest and ntlm authentication into one authenticaton class by @simon-berger in https://github.com/libcpr/cpr/pull/735
    • Use UpdateHeader to allow header updates from different sources by @simon-berger in https://github.com/libcpr/cpr/pull/738
    • Added function to get the full request URL by @simon-berger in https://github.com/libcpr/cpr/pull/741
    • Improved range requests and added support for multiple ranges by @simon-berger in https://github.com/libcpr/cpr/pull/742
    • Use thread pool to instead of std::async (#633) by @ithewei in https://github.com/libcpr/cpr/pull/734
    • Add Interceptors by @simon-berger in https://github.com/libcpr/cpr/pull/744
    • Support for CURLOPT_LOCALPORT and CURLOPT_LOCALPORTRANGE by @jmhersc in https://github.com/libcpr/cpr/pull/748
    • Add CaBuffer to enable loading of CA certificates from buffers by @simon-berger in https://github.com/libcpr/cpr/pull/750
    • Add method SetAcceptEncoding for customized Accept-Encoding header (#683) by @leviliangtw in https://github.com/libcpr/cpr/pull/746
    • Add support of customized filename for Multipart (#642) by @leviliangtw in https://github.com/libcpr/cpr/pull/755
    • Added CI script for automatically building a debian package by @saendigPhilip in https://github.com/libcpr/cpr/pull/760
    • Add unit tests for file uploading using buffer of rvalue/lvalue reference (#216) by @leviliangtw in https://github.com/libcpr/cpr/pull/764
    • Add async methods to the Session object interface by @simon-berger in https://github.com/libcpr/cpr/pull/756
    • Add support of file and buffer for the POST Body (#581) by @leviliangtw in https://github.com/libcpr/cpr/pull/763
    • Securely remove sensitive data from memory by @Garfield96 in https://github.com/libcpr/cpr/pull/776
    • secureStringClear Fix for Empty Strings by @COM8 in https://github.com/libcpr/cpr/pull/779
    • New certificates for HTTPS tests by @saendigPhilip in https://github.com/libcpr/cpr/pull/773
    • MacOS and Windows OpenSSL CI fixes by @COM8 in https://github.com/libcpr/cpr/pull/783
    • Refactor cpr::Cookies for storing more fields (#777) by @leviliangtw in https://github.com/libcpr/cpr/pull/778
    • Fix certificate information extraction from the response (#769) by @leviliangtw in https://github.com/libcpr/cpr/pull/781
    • Workaround for PUT requests with a read callback by @COM8 in https://github.com/libcpr/cpr/pull/787

    New Contributors

    • @WorkingRobot made their first contribution in https://github.com/libcpr/cpr/pull/726
    • @cordbleibaum made their first contribution in https://github.com/libcpr/cpr/pull/728
    • @alebcay made their first contribution in https://github.com/libcpr/cpr/pull/737
    • @simon-berger made their first contribution in https://github.com/libcpr/cpr/pull/735
    • @ithewei made their first contribution in https://github.com/libcpr/cpr/pull/734
    • @jmhersc made their first contribution in https://github.com/libcpr/cpr/pull/748
    • @leviliangtw made their first contribution in https://github.com/libcpr/cpr/pull/746
    • @saendigPhilip made their first contribution in https://github.com/libcpr/cpr/pull/760

    Full Changelog: https://github.com/libcpr/cpr/compare/1.8.4...1.9.0

    Source code(tar.gz)
    Source code(zip)
  • 1.8.4(Jul 6, 2022)

    This release addresses a security concern, where an attacker could extract sensitive information from cpr after the application had been exited.

    Changes:

    • Explicit removal of sensitive data from memory (@Garfield96)

    Full Changelog: https://github.com/libcpr/cpr/compare/1.8.3...1.8.4

    Source code(tar.gz)
    Source code(zip)
  • 1.8.3(May 5, 2022)

    This release disables setting SSL-Key blobs for older versions of curl below 7.71.0, since it was not available previously to that. More information on that can be found here: https://github.com/libcpr/cpr/issues/732

    Full Changelog: https://github.com/libcpr/cpr/compare/1.8.2...1.8.3

    Source code(tar.gz)
    Source code(zip)
  • 1.8.2(Apr 27, 2022)

    What's Changed

    • Downgraded curl to 1.80.0 to fix #709 and #732 by @COM8 in https://github.com/libcpr/cpr/pull/733

    Full Changelog: https://github.com/libcpr/cpr/compare/1.8.1...1.8.2

    Source code(tar.gz)
    Source code(zip)
  • 1.8.1(Mar 25, 2022)

  • 1.8.0(Mar 25, 2022)

    Changes

    • Added DownloadAsync(...) #696
    • Added basic range support via SetRange(...) #701
    • Added support for setting the private key blob directly #699
    • Added Mbed TLS support #714
    • Added an option to reserve space before downloading the response string #712
    • Updated the build in curl to 7.81.0
    • Fixed CA-Path for Android #707
    • Fix overwriting of ca bundle #717
    • Fix build with OpenSSL on Ubuntu bionic #696
    • Fixed installing DLLs to binary directory
    Source code(tar.gz)
    Source code(zip)
  • 1.7.2(Dec 9, 2021)

  • 1.7.1(Dec 9, 2021)

    Small bug fix release.

    Changes

    • Fixed setting headers when calling cpr::Session::Download(...).

    Now something like this should work:

    cpr::Url url{server->GetBaseUrl() + "/download_gzip.html"};
    cpr::Session session;
    session.SetUrl(url);
    session.SetHeader(cpr::Header{{"Accept-Encoding", "gzip"}}); // Works now
    cpr::Response response = session.Download(cpr::WriteCallback{write_data, 0});
    
    Source code(tar.gz)
    Source code(zip)
  • 1.7.0(Nov 24, 2021)

    • Added a Cppcheck CI run
    • Fixed automated libcurl ca path detection
    • Fixed missing raw_header in cpr::Response
    • Fixed bugprone narrowing conversions
    • Fixed MaxRedirects exceeded should be treated as error
    • Updated libcurl from 7.75.0 to 7.79.1
    • Fixed cprConfig.cmake when building cpr as a submodule
    • Added cpr version macros in cprver.h
    • Fixed CMake paths for subprojects
    • Updated zlib-ng from 2.0.0-RC2 to 2.0.5
    • Fixed usage of CPR_USE_SYSTEM_GTEST
    • Added CMake find-package support
    • Added more redirect options:
      • cont_send_cred: Continue to send authentication (user+password) credentials when following locations, even when hostname changed.
    • Added an option to specify the HTML version with SetHttpVersion(...)
    • Fixed respecting system proxy configuration
    • Added an option to select the outgoing interface with SetInterface(...)
    • Added an option to get the file download length GetDownloadFileLength(...)
    • Updated Google Tests from 1.10.0 to 1.11.0
    • Added proxy authentication
    • Don't forcibly override user setting for FETCHCONTENT_QUIET
    Source code(tar.gz)
    Source code(zip)
  • 1.6.2(Apr 27, 2021)

  • 1.6.1(Apr 27, 2021)

    Minor feature and bugfix release with the following changes:

    • Added MacOS darwin-ssl support #549
    • Added an option to split a request preparation from its execution #533
    • cpr::Session is now movable #544
    • Not overriding BUILD_TESTING as cache variable any more #561
    • Avoid recursive template instantiation in priv::set_option() #540
    • Do not move targets in to a bin if cpr is a sub project #531
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Mar 19, 2021)

    In this release the CMake integration has been refactored to fix a bunch of SSL issues. During this change all relevant CMake variable names changed. Here are the new ones:

    -- =======================================================
    --   CPR_GENERATE_COVERAGE: OFF
    --   CPR_CURL_NOSIGNAL: OFF
    --   CPR_USE_SYSTEM_GTEST: OFF
    --   CPR_FORCE_USE_SYSTEM_CURL: OFF
    --   CPR_ENABLE_SSL: ON
    --   CPR_FORCE_OPENSSL_BACKEND: OFF
    --   CPR_FORCE_WINSSL_BACKEND: OFF
    --   CPR_BUILD_TESTS: ON
    --   CPR_BUILD_TESTS_SSL: ON
    -- =======================================================
    

    Documentation for those can be found here: https://github.com/whoshuu/cpr/blob/aac5058a15e9ad5ad393973dc6fe44d7614a7f55/CMakeLists.txt#L30-L40

    If neither CPR_FORCE_OPENSSL_BACKEND nore CPR_FORCE_WINSSL_BACKEND has been set to ON, CMake will try to automatically detect the best SSL backend for your system (WinSSL - Windows, OpenSSL - Linux & Mac, ...).

    How to build on Windows

    With WinSSL

    mkdir build
    cd build
    cmake .. -DCPR_BUILD_TESTS_SSL=OFF # SSL test are only supported with OpenSSL
    cmake --build .
    

    With OpenSSL

    mkdir build
    cd build
    cmake .. -DCPR_FORCE_OPENSSL_BACKEND=ON # Disable auto detect and force OpenSSL
    cmake --build .
    

    Changes

    • Added support for GCC10 static analysis
    • Added an option to retrieve the std::shared_ptr<CurlHolder> from a session
    • Added UpdateHeader(const Header& header) support #506
    • Added support for retrieving certificate information #453
    • Added urlDecode(std::string) for url decoding
    • Add BearerToken support #465
    • Explicit move operator for StringHolder
    • cpr::Session cleanup and allow the compiler to generate the needed constructor
    • Updated curl from 7.69.1 to 7.75.0 #529
    • Compatibility for libcurl <= 7.60
    • Less auto and more explicit types
    • Refactored the CMake variables #529
    • Change listening ports used for tests
    • Fixed AbstractServer data race
    • Fixed Windows OpenSSL builds #529
    • Fixed Windows SSL backend detection #529
    • Fixed ReadCallback will reset Header #517
    • Fixed the Windows OpenSSL CI build
    Source code(tar.gz)
    Source code(zip)
  • 1.5.2(Oct 20, 2020)

    This hotfix for v1.5.1 includes the following fixes:

    • Fixed: cpr::Post wrong content length (#450, #456, #458)
    • Fixed: Mutex for multithreaded access not being static
    • Fixed: No const rvalue references (#424)
    Source code(tar.gz)
    Source code(zip)
  • v1.5.1(Jul 8, 2020)

    Changes

    • CMake add ability to use WINSSL (#404)
    • Thread save access to libCurl (#313)
    • Allow implicit creation of cpr:Url, cpr:Body and cpr:UserAgent (#411)
    • Payload with string variables (#409)
    • Cleanup (#407, #408)
    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Jun 22, 2020)

    Changes

    • Updated CURL to curl-7_69_1 (#343)
    • Updated mongoose to 6.18
    • Updated googletest to release-1.10.0
    • Refactored the mongoose test server setup
    • Added SSL options (#276)
    • Fixed URL encoding (#379)
    • Fixed Windows std::min type deduction
    • GitHub Actions CI (#393)
    • Refactored all the CMake stuff (#383)
    • Fixed passing correct data type when setting CURLOPT_POSTFIELDSIZE_LARGE
    • Switched Body, UserAgent and Url from std::string derivation classes to string holder classes (#303)
    • General cleanup of the code base
    Source code(tar.gz)
    Source code(zip)
Owner
C++ Requests: Curl for People, a spiritual port of Python Requests.
null
JeVois-Pro People Counter : Implement people counter on JeVois-Pro Deep Learning Smart Camera

JeVois-Pro People Counter Refer to the OpenCV People Counter article to implement a people counter on the JeVois-Pro Deep Learning Smart Camera. First

On-Device AI Co., Ltd. 1 Nov 10, 2021
This is a simple version of Apex-Legends-SDK since so many people having struggles with python binding

This is a simple version of Apex-Legends-SDK since so many people having struggles with python binding

skidword64 38 Jul 29, 2022
Threat Emulation and Red Teaming Framework, The Hacking Software for normal people.

The Remote Hacker Probe is a Threat Emulation and Red Teaming Framework built to be easy to use. The Remote Hacker Probe is Feature Rich! Including, K

QuantumCored 159 Aug 2, 2022
A simple wrapper for 'pacman' with a syntax similar to 'apt' to help people transitioning to Arch and Arch based distributions like Manjaro.

aptpac aptpac is a program which helps with the transition to Arch Linux and Arch based distros like Manjaro. It simplifies using pacman as it works l

Itai Nelken 14 Jul 20, 2022
Off The Grid (OTG) Messenger is an easy way for people to communicate through text messages when in remote areas.

Off The Grid (OTG) Messenger is an easy way for people to communicate through text messages when in remote areas. With a theoretical transmission range of 10 miles (16kms), OTG messenger can be used by groups of people to stay connected when they are in areas not serviced by mobile connectivity.

Trevor Attema 490 Aug 9, 2022
The Xnoe Operating System, for people who want an OS that is useless.

Xnoe OS An attempt at writing an "Operating System" in x86 assembler. Hi all, I have many hobbies, one of those is torturing myself with knowledge I p

Xnoe 9 Jul 12, 2022
To turn on and off the pump, most people use a manual switch.

To turn on and off the pump, most people use a manual switch. As a result, people forget to switch off the pump from time to time, resulting in water overflow. They may forget to switch on the motor at times, resulting in a water problem later on. It also wastes a lot of electricity. To solve this problem, we need a smart device to control the pump.

Md. Asad Chowdhury Dipu 1 Oct 14, 2021
ClickLock which supports old games where the Windows ClickLock fails to work. This is a charity project, designed for people with disabilities.

Mouse ClickLock For Games This small utility works in a similar way as ClickLock available on Windows, but also supports old games where the normal Cl

null 5 Jul 31, 2022
🔍 A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM.

?? ImHex A Hex Editor for Reverse Engineers, Programmers and people who value their retinas when working at 3 AM. Supporting If you like my work, plea

WerWolv 19.9k Aug 10, 2022
A repo for helping people get started with Competitive Programming and Data Structures & Algorithms

Hack CP DSA Update regarding hacktoberfest: please refer this announcement Wanna improve your problem solving skills ❓ Wanna practice collaborating on

TLE MEC 172 Jul 22, 2022
Remote hacker probe - Threat Emulation and Red Teaming Framework, The Hacking Software for normal people.

The Remote Hacker Probe is a Threat Emulation and Red Teaming Framework built to be easy to use. The Remote Hacker Probe is Feature Rich! Including, K

Fahad 159 Aug 2, 2022
Software to support people learning OpenMP with our book

Software to support people learning OpenMP with our book ... The OpenMP Common Core: Making OpenMP Simple Again

Tim Mattson 43 Jul 28, 2022
Bank of challenges & solutions from r/dailyprogrammer for people learning to program

DailyProgrammerChallenges This repo contains all of the challenges from r/dailyprogrammer and also scripts used to pull challenges from the subreddit

Freddie Vargus 315 Jul 9, 2022
An Xposed module to detect or reject applist requests

Hide My Applist About this module Although "It is incorrect to detect specific app's installation", yet not every app using root provides random packa

null 890 Aug 9, 2022
Register for Hacktoberfest and make four pull requests (PRs) between October 1st-31st to grab free SWAGS

⭐️ Projects and Codes ⭐️ This is beginner friendly repo. We aim for beginners to start with their first contributions to open-source. If you are looki

Joel Sunny Varghese 8 Jun 13, 2022
You may learn how to make successful pull requests and get your first valid open source contribution by using this repository.

Your-First-Contribution You may learn how to make successful pull requests and get your first valid open source contribution by using this repository.

Veshraj Ghimire 25 Jul 31, 2022
Helping everyone to code and creating pull requests

Novice Coding It's an initiative to help create more awareness about Open Source and help introduce many more students to the benefits of FOSS. We wil

Saptarshi Sarkar 17 May 15, 2022
all valid pull requests accepted!!

Hacktoberfest_2021 Hacktober Fest Details Important Notice The repository has been marked as "Excluded Project" by Hacktoberfest Algorithm. I have no

Gautam Jain 23 Aug 6, 2022
Lua HTTP async client using libcurl (supports multi requests in parallel)

lua-async-http lua-async-http rock, is a new lua rock written in C and based on libcurl. It allow us to make multiple http/https (with client certific

International Business Machines 4 Jun 11, 2022