### Perform a GET Request with cpr Source: https://docs.libcpr.dev/index Demonstrates a basic GET request using the cpr library. It shows how to specify the URL, authentication credentials, and query parameters. The response object provides access to status code, headers, and text content. This is a simple example of making an HTTP request. ```cpp #include int main(int argc, char** argv) { cpr::Response r = cpr::Get(cpr::Url{"https://api.github.com/repos/libcpr/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 } ``` -------------------------------- ### Install cpr using vcpkg Source: https://docs.libcpr.dev/index This snippet shows how to clone the vcpkg repository, bootstrap it, integrate it with your system, and finally install the cpr library. vcpkg is a cross-platform package manager for C++ libraries. ```bash git clone https://github.com/Microsoft/vcpkg.git cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install ./vcpkg install cpr ``` -------------------------------- ### Preparing a GET Request with CPR Session for libcurl Integration Source: https://docs.libcpr.dev/advanced-usage Illustrates how to prepare a GET request using a CPR Session object by calling `PrepareGet()` instead of `Get()`. This is the first step when integrating with libcurl's advanced APIs, allowing manual control over the request execution. ```cpp cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; cpr::Session session; session.SetOption(url); session.PrepareGet(); // Here, curl_easy_perform would typically be replaced // by a more complex scheme using curl_multi API ``` -------------------------------- ### Install cpr using CMake's find_package Method Source: https://docs.libcpr.dev/index This code illustrates the process of cloning, building, and installing the cpr library using CMake. It configures the build with `CPR_USE_SYSTEM_CURL=ON` to potentially use a system-provided libcurl, then builds and installs the library. This allows integration via `find_package` in other CMake projects. ```cmake 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 . ``` -------------------------------- ### Setup cpr::MultiPerform and Add Sessions Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to create a cpr::MultiPerform object and add multiple cpr::Session objects to it for concurrent execution. Sessions are added as shared pointers, and their URLs are configured. ```cpp // Create and setup session objects cpr::Url url{"https://www.httpbin.org/get"}; std::shared_ptr session_1 = std::make_shared(); std::shared_ptr session_2 = std::make_shared(); session_1->SetUrl(url); session_2->SetUrl(url); // Create MultiPerform object cpr::MultiPerform multiperform; // Add sessions to the MultiPerform multiperform.AddSession(session_1); multiperform.AddSession(session_2); ``` -------------------------------- ### Basic Asynchronous GET Request Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to initiate an asynchronous GET request and retrieve the response later. The AsyncResponse object returned by GetAsync can be used to wait for and get the final Response. ```cpp cpr::AsyncResponse fr = cpr::GetAsync(cpr::Url{"http://www.httpbin.org/get"}); // Sometime later... cpr::Response r = fr.get(); // This blocks until the request is complete std::cout << r.text << std::endl; ``` -------------------------------- ### Using CPR Session for GET Requests Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to create and use a CPR Session object to perform a GET request with initial parameters, and then update those parameters for a subsequent GET request. This highlights the stateful nature of the Session object. ```cpp cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; cpr::Parameters parameters = cpr::Parameters{{"hello", "world"}}; cpr::Session session; session.SetUrl(url); session.SetParameters(parameters); cpr::Response r = session.Get(); // Equivalent to cpr::Get(url, parameters); std::cout << r.url << std::endl; // Prints http://www.httpbin.org/get?hello=world cpr::Parameters new_parameters = cpr::Parameters{{"key", "value"}}; session.SetParameters(new_parameters); cpr::Response new_r = session.Get(); // Equivalent to cpr::Get(url, new_parameters); std::cout << new_r.url << std::endl; // Prints http://www.httpbin.org/get?key=value ``` -------------------------------- ### Execute Request with Interceptors in C++ Source: https://docs.libcpr.dev/advanced-usage This C++ code shows how to execute a GET request on a `cpr::Session` that has previously had interceptors added. When `session.Get()` is called, the `intercept` methods of all added interceptors are invoked in the order they were added. This example assumes the CPR library is included. ```cpp // Make a get request to the session we have previously added our LoggingInterceptor to Response response = session.Get(); /* * Output produced by the LoggingInterceptor: * Request url: https://www.httpbin.org/get * Response status code: 200 */ ``` -------------------------------- ### cpr: GET Request with Multiple Parameters (In-Place and External) Source: https://docs.libcpr.dev/introduction Demonstrates performing GET requests with multiple URL parameters in cpr. It shows two approaches: constructing the `Parameters` object directly within the `Get` call, and constructing it separately beforehand. Both methods yield the same result, highlighting the library's flexibility. ```cpp // Constructing it in place cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::Parameters{{"hello", "world"}, {"stay", "cool"}}); std::cout << r.url << std::endl; // http://www.httpbin.org/get?hello=world&stay=cool std::cout << r.text << std::endl; /* * { * "args": { * "hello": "world" * "stay": "cool" * }, * "headers": { * .. * }, * "url": "http://httpbin.org/get?hello=world&stay=cool" * } */ // Constructing it outside cpr::Parameters parameters = cpr::Parameters{{"hello", "world"}, {"stay", "cool"}}; cpr::Response r_outside = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, parameters); std::cout << r_outside.url << std::endl; // http://www.httpbin.org/get?hello=world&stay=cool std::cout << r_outside.text << std::endl; // Same text response as above ``` -------------------------------- ### Basic Authentication in C++ using cpr Source: https://docs.libcpr.dev/introduction Demonstrates how to perform HTTP GET requests with Basic Authentication using the cpr library. It requires a URL and authentication credentials (username, password, and authentication mode). ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/basic-auth/user/pass"}, cpr::Authentication{"user", "pass", cpr::AuthMode::BASIC}); std::cout << r.text << std::endl; /* * { * "authenticated": true, * "user": "user" * } */ ``` -------------------------------- ### Setting Custom Request Headers Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to set custom headers for a GET request using the `cpr::Header` object. ```APIDOC ## GET /headers ### Description This endpoint demonstrates how to send custom headers with an HTTP request. The response will include the headers that were sent with the request. ### Method GET ### Endpoint `/headers` ### Parameters #### Query Parameters None #### Request Body None ### Request Example ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Header{{"accept", "application/json"}}); std::cout << r.text << std::endl; ``` ### Response #### Success Response (200) - **headers** (object) - A JSON object containing the headers received by the server. #### Response Example ```json { "headers": { "Accept": "application/json", "Host": "www.httpbin.org", "User-Agent": "curl/7.42.0-DEV" } } ``` ``` -------------------------------- ### Managing Multiple Async Requests Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to manage a collection of asynchronous requests, retrieve their responses, and process them individually. ```APIDOC ## Managing Multiple Async Requests ### Description Allows for initiating multiple asynchronous requests and storing them in a container (e.g., `std::vector`). Each request can be retrieved and processed individually after completion. ### Method GET (for example) ### Endpoint Asynchronous equivalent of `/get` endpoint. ### Parameters #### Path Parameters None #### Query Parameters - **i** (string) - Example query parameter. #### Request Body None ### Request Example ```cpp std::vector container{}; cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; for (int i = 0; i < 10; ++i) { container.emplace_back(cpr::GetAsync(url, cpr::Parameters{{"i", std::to_string(i)}})); } // Sometime later for (cpr::AsyncResponse& ar : container) { cpr::Response r = ar.get(); std::cout << r.text << std::endl; } ``` ### Response #### Success Response (200) - **text** (string) - The response body text for each individual request. #### Response Example ```json { "example": "response body text for request i" } ``` ``` -------------------------------- ### Multiple Asynchronous GET Requests Source: https://docs.libcpr.dev/advanced-usage Illustrates how to queue multiple asynchronous GET requests in a std::vector and process their responses later. Each request is initiated with GetAsync and added to the container. ```cpp std::vector container{}; cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; for (int i = 0; i < 10; ++i) { container.emplace_back(cpr::GetAsync(url, cpr::Parameters{{"i", std::to_string(i)}})); } // Sometime later for (cpr::AsyncResponse& ar: container) { cpr::Response r = ar.get(); std::cout << r.text << std::endl; } ``` -------------------------------- ### Managing Headers and Body with CPR Session Source: https://docs.libcpr.dev/advanced-usage Illustrates how to configure a CPR Session with custom headers and a request body for a POST request. It also shows how to remove the content and modify headers for a subsequent GET request, demonstrating state management. ```cpp cpr::Url getUrl = cpr::Url{"http://www.httpbin.org/get"}; cpr::Url postUrl = cpr::Url{"http://www.httpbin.org/post"}; cpr::Session session; session.SetUrl(postUrl); session.SetHeader(Header{{{"My-Custom-Header", "hello"}, {"Content-Type", "application/json"}}}); session.SetBody("x=5"); cpr::Response postResponse = session.Post(); std::cout << postResponse.text << std::endl; // [...] "headers": " My-Custom-Header": " hello", "Content-Type": "application/json" [...] "data": "x=5" session.RemoveContent(); // don't send a body in next request auto& headers = session.GetHeader(); // also don't send unnecessary headers headers.erase("content-type"); // headers interface is case-insensitive session.SetUrl(getUrl); cpr::Response getResponse = session.Get(); // equivalent to cpr::Get(getUrl); std::cout << getResponse.text << std::endl; // [...] "headers": " My-Custom-Header": " hello", [...] /* no data */ ``` -------------------------------- ### Asynchronous GET Request with explicit wait Source: https://docs.libcpr.dev/advanced-usage Shows an alternative way to handle asynchronous GET requests by explicitly calling wait() before get(). This approach clarifies the control flow for waiting on the request completion. ```cpp cpr::AsyncResponse fr = cpr::GetAsync(cpr::Url{"http://www.httpbin.org/get"}); fr.wait(); // This waits until the request is complete cpr::Response r = fr.get(); // Since the request is complete, this returns immediately std::cout << r.text << std::endl; ``` -------------------------------- ### cpr: GET Request with URL-Encoded Parameters Source: https://docs.libcpr.dev/introduction Illustrates how to add URL-encoded parameters to a GET request using cpr. It shows the construction of the `Parameters` object and its inclusion in the `cpr::Get` call. The output demonstrates how the parameters are appended to the URL and reflected in the response text. ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::Parameters{{"hello", "world"}}); std::cout << r.url << std::endl; // http://www.httpbin.org/get?hello=world std::cout << r.text << std::endl; /* * { * "args": { * "hello": "world" * }, * "headers": { * .. * }, * "url": "http://httpbin.org/get?hello=world" * } */ ``` -------------------------------- ### Build cpr as a Static Library with CMake Source: https://docs.libcpr.dev/index Instructions for building cpr as a static library using CMake. This involves cloning the repository, configuring the build with `-DBUILD_SHARED_LIBS=OFF`, building, and installing. It also shows how to find and link the static library in a CMake project. ```cmake git clone https://github.com/libcpr/cpr.git cd cpr && mkdir build && cd build cmake .. -DCPR_USE_SYSTEM_CURL=ON -DBUILD_SHARED_LIBS=OFF 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) ``` -------------------------------- ### Downloading a File to a Stream with CPR Source: https://docs.libcpr.dev/advanced-usage Shows how to download a file from a URL and save it directly to an output stream, such as a file stream. Dependencies include CPR and fstream. ```cpp std::ofstream of("1.jpg", std::ios::binary); cpr::Response r = cpr::Download(of, cpr::Url{"http://www.httpbin.org/1.jpg"}); std::cout << "http status code = " << r.status_code << std::endl << std::endl; ``` -------------------------------- ### Combining Headers from Multiple Sources Source: https://docs.libcpr.dev/advanced-usage Illustrates how to combine headers from different sources, such as default headers set in a helper function and headers passed directly to the request. ```APIDOC ## GET /headers (with combined headers) ### Description This example shows how to combine headers from different sources. A helper function `myGet` adds a default `Authorization` header, and additional headers like `accept` can be provided when calling the function. ### Method GET ### Endpoint `/headers` ### Parameters #### Query Parameters None #### Request Body None ### Request Example ```cpp template cpr::Response myGet(Ts&& ...ts) { return cpr::Get(std::forward(ts)..., cpr::Header{{"Authorization", "token"}}); } ... cpr::Response r = cpr::myGet(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Header{{"accept", "application/json"}}); std::cout << r.text << std::endl; ``` ### Response #### Success Response (200) - **headers** (object) - A JSON object containing the combined headers received by the server. #### Response Example ```json { "headers": { "Accept": "application/json", "Accept-Encoding": "deflate, gzip", "Authorization": "token", "Host": "www.httpbin.org", "User-Agent": "curl/7.81.0" } } ``` ``` -------------------------------- ### Integrate cpr into a CMake Project using find_package Source: https://docs.libcpr.dev/index This CMake snippet shows how to integrate a pre-installed cpr library into a project using `find_package`. This method requires the library to be installed system-wide and is feasible only if `CPR_USE_SYSTEM_CURL` is set. It then links the `cpr::cpr` target to your executable. ```cmake find_package(cpr REQUIRED) add_executable(your_target_name your_target_name.cpp) target_link_libraries(your_target_name PRIVATE cpr::cpr) ``` -------------------------------- ### cpr Design: Flexible Option Ordering in Get Requests Source: https://docs.libcpr.dev/introduction Demonstrates the flexible option ordering in cpr's Get requests. The order of Url and Parameters objects does not affect the outgoing call, showcasing the library's keyword args-like interface. This allows for more readable and maintainable code. ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::Parameters{{"hello", "world"}}); // Url object before Parameters cpr::Response r = cpr::Get(cpr::Parameters{{"hello", "world"}}, cpr::Url{"http://www.httpbin.org/get"}); // Parameters object before Url ``` -------------------------------- ### Download File Source: https://docs.libcpr.dev/advanced-usage Provides instructions on how to download files to a local file path using the CPR library's `Download` function. ```APIDOC ## Download File ### Description This section details how to use the CPR library to download files from a URL and save them to a local file. The `cpr::Download` function is provided for this purpose. ### Download To File To download a file to a specified file path: ```cpp std::ofstream of("1.jpg", std::ios::binary); cpr::Response r = cpr::Download(of, cpr::Url{"http://www.httpbin.org/1.jpg"}); std::cout << "http status code = " << r.status_code << std::endl << std::endl; ``` ### Parameters - **ofstream object** - An output file stream object where the downloaded content will be written. - **cpr::Url** - The URL of the file to download. ``` -------------------------------- ### Execute CPR Session and Handle Response Source: https://docs.libcpr.dev/advanced-usage Demonstrates executing a CPR session and handling the result. It shows how to perform a request and then complete the session to get the response. This is a fundamental operation in using the CPR library. ```cpp CURLcode curl_result = curl_easy_perform(session.GetCurlHolder()->handle); cpr::Response response = session.Complete(curl_result); ``` -------------------------------- ### Execute HTTP Requests with cpr::MultiPerform Source: https://docs.libcpr.dev/advanced-usage Shows how to execute common HTTP methods (GET, DELETE, PUT, etc.) on all sessions added to a cpr::MultiPerform object. The function returns a vector of cpr::Response objects corresponding to each session's request. ```cpp // Perform GET request on all previously added sessions std::vector responses = multiperform.Get(); ``` -------------------------------- ### Digest Authentication in C++ using cpr Source: https://docs.libcpr.dev/introduction Illustrates how to use Digest Authentication for HTTP GET requests with the cpr library. Similar to Basic Authentication, it requires a URL and credentials, specifying the DIGEST mode. ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/digest-auth/auth/user/pass"}, cpr::Authentication{"user", "pass", cpr::AuthMode::DIGEST}); std::cout << r.text << std::endl; /* * { * "authenticated": true, * "user": "user" * } */ ``` -------------------------------- ### PUT and PATCH Requests Source: https://docs.libcpr.dev/advanced-usage Explains how to perform PUT and PATCH requests using the CPR library, noting their similarity to POST requests but with different HTTP methods. ```APIDOC ## PUT and PATCH Requests ### Description This section covers how to make PUT and PATCH requests using the CPR library. These methods function similarly to POST requests, but utilize the distinct HTTP verbs "PUT" or "PATCH". This is useful when interacting with APIs that implement specific behaviors for these methods, often for updating or partially updating resources. ### PUT Request Example To perform a PUT request: ```cpp // We can't POST to the "/put" endpoint so the status code is rightly 405 assert(cpr::Post(cpr::Url{"http://www.httpbin.org/put"}, cpr::Payload{{"key", "value"}}).status_code == 405); // On the other hand, this works just fine cpr::Response r = cpr::Put(cpr::Url{"http://www.httpbin.org/put"}, cpr::Payload{{"key", "value"}}); std::cout << r.text << std::endl; ``` ### PATCH Request Example To perform a PATCH request: ```cpp // We can't POST or PUT to the "/patch" endpoint so the status code is rightly 405 assert(cpr::Post(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}).status_code == 405); assert(cpr::Put(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}).status_code == 405); // On the other hand, this works just fine cpr::Response r = cpr::Patch(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}); std::cout << r.text << std::endl; ``` ### Request Body Parameters - **key** (string) - Required - The key for the payload. - **value** (string) - Required - The value for the payload. ### Response Example (PUT/PATCH) ```json { "args": {}, "data": "", "files": {}, "form": { "key": "value" }, "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "json": null, "url": "https://httpbin.org/put" } ``` ``` -------------------------------- ### C++ Asynchronous Callback with Lambda Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to perform an asynchronous GET request using a lambda function as a callback. The callback processes the response and returns the text content. The result is retrieved asynchronously using std::future. ```cpp auto future_text = cpr::GetCallback([](cpr::Response r) { return r.text; }, cpr::Url{"http://www.httpbin.org/get"}); // Sometime later if (future_text.wait_for(std::chrono::seconds(0)) == std::future_status::ready) { std::cout << future_text.get() << std::endl; } ``` -------------------------------- ### Range Requests Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to perform HTTP range requests using `cpr::Range` and `cpr::MultiRange` to fetch specific parts of a resource. ```APIDOC ## Range Requests HTTP range requests can be used to receive only a part of a HTTP message. This allows specific access to required areas of large files or to pause downloads and resume them later. ### Simple Range Request To make a simple HTTP range request, the range options need to be set as follows: ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Range{1, 5}); std::cout << r.text << std::endl; /* * { "headers": { "Range": "bytes=1-5", ... } } */ ``` ### Partial Range Request To leave parts of the range empty, `std::nullopt` can be specified as the boundary index when creating the partial range: ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Range{std::nullopt, 5}); std::cout << r.text << std::endl; /* * { "headers": { "Range": "bytes=-5", ... } } */ ``` ### Multiple Range Request Moreover, multiple ranges can be specified in a single request with `cpr::MultiRange`: ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/headers"}, cpr::MultiRange{cpr::Range{1, 3}, cpr::Range{5, 6}}); std::cout << r.text << std::endl; /* * { "headers": { "Range": "bytes=1-3, 5-6", ... } } */ ``` ### Setting Range on Session Object As always, there is of course also the possibility to set the range of a session object manually: ```cpp cpr::Session session; session.SetOption(cpr::Range{1, 3}); // Alternative: SetRange() session.SetOption(cpr::MultiRange{cpr::Range{1, 3}, cpr::Range{5, 6}}); // Alternative: SetMultiRange() ``` ### Parameters #### Request Body - **Range** (cpr::Range) - Optional - Specifies a single byte range. - **start** (int or std::nullopt) - The starting byte of the range. - **end** (int or std::nullopt) - The ending byte of the range. - **MultiRange** (cpr::MultiRange) - Optional - Specifies multiple byte ranges. - **ranges** (array of cpr::Range) - An array of `cpr::Range` objects. ``` -------------------------------- ### Map-like Objects for Request Data Source: https://docs.libcpr.dev/advanced-usage Explains the similarity in constructors for `cpr::Header`, `cpr::Parameters`, `cpr::Payload`, and `cpr::Multipart`, highlighting their map-like nature. ```APIDOC ## Data Structures for Request Data ### Description The CPR library uses consistent syntax for various map-like data structures used in requests, including Headers, Parameters, Payload, and Multipart. This uniformity simplifies their usage and allows for potential interchangeability in certain scenarios. ### Method N/A (Conceptual Explanation) ### Endpoint N/A ### Parameters N/A ### Request Example ```cpp cpr::Header header = cpr::Header{{"header-key", "header-value"}}; cpr::Parameters parameters = cpr::Parameters{{"parameter-key", "parameter-value"}}; cpr::Payload payload = cpr::Payload{{"payload-key", "payload-value"}}; cpr::Multipart multipart = cpr::Multipart{{"multipart-key", "multipart-value"}}; ``` ### Response N/A ### Notes All these objects (`Header`, `Parameters`, `Payload`, `Multipart`) share a common constructor pattern, making them easy to instantiate and use. Their specific semantics are determined by the object type itself. ``` -------------------------------- ### Live Data Streams Use Case Source: https://docs.libcpr.dev/sse Example for setting up SSE to receive and process live data streams, such as stock price updates. ```APIDOC ## Live Data Streams ### Description This example illustrates setting up a Server-Sent Events callback to handle live data streams, like real-time stock price updates. The callback checks for a "price-update" event and processes the associated data. ### Method `session.SetUrl()`, `session.SetServerSentEventCallback()`, `session.Get()` ### Endpoint `https://api.example.com/stock-prices` ### Request Example ```cpp cpr::Session session; session.SetUrl(cpr::Url{"https://api.example.com/stock-prices"}); session.SetServerSentEventCallback( cpr::ServerSentEventCallback{ [](cpr::ServerSentEvent&& event, intptr_t /*userdata*/) { if (event.event == "price-update") { // Parse JSON data and update UI std::cout << "Price update: " << event.data << std::endl; } return true; } } ); session.Get(); ``` ### Response Example ``` // When the server sends an event like: // event: price-update // data: {"symbol": "AAPL", "price": 170.50} // The output will be: Price update: {"symbol": "AAPL", "price": 170.50} ``` ``` -------------------------------- ### Progress Updates Use Case Source: https://docs.libcpr.dev/sse Example demonstrating how to use SSE to receive progress updates for a long-running task and to detect task completion. ```APIDOC ## Progress Updates ### Description This example shows how to use Server-Sent Events to receive progress notifications for a long-running task. The callback handles "progress" events and stops listening when a "complete" event is received. ### Method `session.SetUrl()`, `session.SetServerSentEventCallback()`, `session.Get()` ### Endpoint `https://api.example.com/long-running-task/123` ### Request Example ```cpp cpr::Session session; session.SetUrl(cpr::Url{"https://api.example.com/long-running-task/123"}); session.SetServerSentEventCallback( cpr::ServerSentEventCallback{ [](cpr::ServerSentEvent&& event, intptr_t /*userdata*/) { if (event.event == "progress") { std::cout << "Progress: " << event.data << std::endl; } else if (event.event == "complete") { std::cout << "Task completed!" << std::endl; return false; // Stop listening } return true; } } ); session.Get(); ``` ### Response Example ``` // When the server sends progress updates and completion: // event: progress // data: 50% // event: progress // data: 75% // event: complete // data: Task finished successfully. // The output will be: Progress: 50% Progress: 75% Task completed! ``` ``` -------------------------------- ### Cancellable Asynchronous POST Requests Source: https://docs.libcpr.dev/advanced-usage Demonstrates using MultiPostAsync with cancellable transactions to execute multiple POST requests in parallel. It includes logic to cancel requests if they time out. ```cpp // The second template parameter denotes a cancellable transaction using AsyncResC = cpr::AsyncWrapper; cpr::Url postUrl{"http://www.httpbin.org/post"}; std::vectorresponses{MultiPostAsync( std::tuple{post_url, cpr::Payload{{"name", "Alice"}}}, std::tuple{post_url, cpr::Payload{{"role", "admin"}}} // ... )}; // If the first transaction isn't completed within 10 ms, we'd like to cancel all of them bool all_cancelled{false}; if(responses.at(0).wait_for(std::chrono::milliseconds(10)) == std::future_status::timeout) { all_cancelled = true; for(AsyncResC& res: responses) { all_cancelled &= (res.Cancel() == CancellationResult::success); } } // If not cancelled, process results ``` -------------------------------- ### Using Proxies Source: https://docs.libcpr.dev/advanced-usage CPR allows you to configure proxies for network requests. Proxies can be set for individual requests or persistently for a `Session`. Proxies can also include authentication details. ```APIDOC ## Using Proxies ### Description `Proxies`, like `Parameters`, are map-like objects. It’s easy to set one: ### Request Example (Single Request) ```c++ cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::Proxies{{"http", "http://www.fakeproxy.com"}}); // Note: The original URL is returned, not the proxy URL. std::cout << r.url << std::endl; ``` ### Request Example (Session) Setting `Proxies` on a `Session` lets you intelligently route requests using different protocols through different proxies. ```c++ cpr::Session session; session.SetProxies({{"http", "http://www.fakeproxy.com"}, {"https", "http://www.anotherproxy.com"}}) session.SetUrl("http://www.httpbin.org/get"); { cpr::Response r = session.Get(); std::cout << r.url << std::endl; // Prints http://www.httpbin.org/get after going // through http://www.fakeproxy.com } session.SetUrl("https://www.httpbin.org/get"); { cpr::Response r = session.Get(); std::cout << r.url << std::endl; // Prints https://www.httpbin.org/get after going // through http://www.anotherproxy.com } ``` ### Request Example (Proxy Authentication) ```c++ cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::Proxies{{"http", "http://www.fake_auth_proxy.com"}}, cpr::ProxyAuthentication{{"http", EncodedAuthentiction{"user", "pass"}}}); std::cout << r.text << std::endl; /* * { ... } */ ``` ### Options Use `Proxiesno_proxy` or `Proxiesno_proxy` to override corresponding NO_PROXY environment variable settings. ``` -------------------------------- ### Manual Domain Name Resolution (Resolve) Source: https://docs.libcpr.dev/advanced-usage This section details how to manually specify IP address resolution for domain names and port combinations using the cpr library. ```APIDOC ## Manual Domain Name Resolution (Resolve) ### Description It is possible to specify which IP address should a specific domain name and port combination resolve to. This allows for fine-grained control over network requests by providing a list of hostnames, addresses, and ports. ### Method GET (Implicit through cpr::Get) ### Endpoint N/A (This is a library feature, not a direct API endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body This functionality is configured via parameters within the `cpr::Get` function or by using `setResolve` and `setResolves` methods. - **cpr::Resolve** (struct) - Represents a single resolution rule. - **hostname** (string) - The domain name to resolve. - **address** (string) - The IP address to resolve to. - **ports** (std::vector, optional) - A vector of ports for which this resolution applies. Defaults to 80 and 443 if not specified. ### Request Example ```c++ cpr::Response getResponse = cpr::Get(cpr::Url{"https://www.example.com"}, std::vector({cpr::Resolve{"www.example.com", "127.0.0.1", {443}}, cpr::Resolve{"www.example.com", "127.0.0.2", {80}}}, cpr::Resolve{"subdomain.example.com", "127.0.0.3"})); // Not specifying any ports defaults to 80 and 443 ``` ### Response #### Success Response (200) Standard cpr::Response object. #### Response Example ```json { "status_code": 200, "header": {}, "body": "...", "url": "https://www.example.com" } ``` ### Notes - Use `setResolves` with a vector of `cpr::Resolve` objects for multiple resolutions. Avoid consecutive calls to `setResolve` as each call clears previous values. ``` -------------------------------- ### Build and run cpr image with Podman Source: https://docs.libcpr.dev/index This snippet shows how to build a Docker/Podman image for testing documentation and then run a container from that image, exposing port 4000 and mounting the current directory. This allows for interactive testing of the cpr documentation within a containerized environment. ```bash podman build . --tag cpr-image podman run --rm -it -p 4000:4000 -v ${PWD}:/app -w /app cpr-image ``` -------------------------------- ### Build cpr using Meson Source: https://docs.libcpr.dev/index This demonstrates how to set up a new C++ project with Meson, add cpr as a subproject dependency, and then build the project. Meson is a fast, dependency-aware, and expressive build system. ```bash meson init -l cpp -n cpr-test meson wrap install cpr meson setup builddir --wipe meson compile -C builddir ./builddir/cpr-test ``` ```meson project('cpr-test', 'cpp', version : '0.1', default_options : ['warning_level=3', 'cpp_std=c++17']) cpr_dep = dependency('cpr') exe = executable('cpr-test', 'cpr_test.cpp', dependencies: [ cpr_dep ], install: true) test('basic', exe) ``` -------------------------------- ### GET Async Request Source: https://docs.libcpr.dev/advanced-usage Initiates an asynchronous GET request and retrieves the response later. The `get()` method on the `AsyncResponse` object blocks until the request is complete. ```APIDOC ## GET Async Request ### Description Initiates an asynchronous GET request. The response can be retrieved later by calling the `get()` method on the returned `AsyncResponse` object, which will block until the request is complete. ### Method GET ### Endpoint Asynchronous equivalent of `/get` endpoint. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```cpp cpr::AsyncResponse fr = cpr::GetAsync(cpr::Url{"http://www.httpbin.org/get"}); // Sometime later... cpr::Response r = fr.get(); // This blocks until the request is complete std::cout << r.text << std::endl; ``` ### Response #### Success Response (200) - **text** (string) - The response body text. #### Response Example ```json { "example": "response body text" } ``` ``` -------------------------------- ### Manual Domain Resolution with cpr::Resolve in C++ Source: https://docs.libcpr.dev/advanced-usage This snippet demonstrates how to manually specify IP address resolutions for domain name and port combinations using `cpr::Resolve`. It shows how to map 'www.example.com' on ports 443 and 80 to different IPs, and 'subdomain.example.com' to another IP. This is useful for testing or directing traffic to specific local instances. ```cpp cpr::Response getResponse = cpr::Get(cpr::Url{"https://www.example.com"}, std::vector({cpr::Resolve{"www.example.com", "127.0.0.1", {443}}, cpr::Resolve{"www.example.com", "127.0.0.2", {80}}}, cpr::Resolve{"subdomain.example.com", "127.0.0.3"}})); // Not specifying any ports defaults to 80 and 443 ``` -------------------------------- ### Performing PUT Requests with CPR Source: https://docs.libcpr.dev/advanced-usage Illustrates how to perform HTTP PUT requests using the CPR library. This is useful for updating existing resources on a server. Dependencies include CPR, iostream, and cassert. ```cpp #include // We can't POST to the "/put" endpoint so the status code is rightly 405 assert(cpr::Post(cpr::Url{"http://www.httpbin.org/put"}, cpr::Payload{{"key", "value"}}).status_code == 405); // On the other hand, this works just fine cpr::Response r = cpr::Put(cpr::Url{"http://www.httpbin.org/put"}, cpr::Payload{{"key", "value"}}); std::cout << r.text << std::endl; ``` -------------------------------- ### Setting Session Options using SetOption Source: https://docs.libcpr.dev/advanced-usage Demonstrates an alternative way to configure a CPR Session using the generic `SetOption()` method, which accepts various configuration objects like `Url` and `Parameters`. This method is useful for order-less configuration. ```cpp cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; cpr::Parameters parameters = cpr::Parameters{{"hello", "world"}}; cpr::Session session; session.SetOption(url); session.SetOption(parameters); cpr::Response r = session.Get(); ``` -------------------------------- ### Asynchronous GET Request with cpr::Session Source: https://docs.libcpr.dev/advanced-usage Shows how to perform an asynchronous GET request using a cpr::Session object managed by a std::shared_ptr. This approach is necessary for correct lifetime management of the session during asynchronous operations. ```cpp std::shared_ptr session = std::make_shared(); cpr::Url url = cpr::Url{"http://www.httpbin.org/get"}; session->SetUrl(url); cpr::AsyncResponse fr = session->GetAsync(); cpr::Response r = fr.get(); std::cout << r.text << std::endl; ``` -------------------------------- ### Configure HTTP Accept-Encoding for Compression Source: https://docs.libcpr.dev/advanced-usage Shows how to specify supported compression schemes (deflate, gzip, zlib) in HTTP requests using CPR's AcceptEncoding. This allows clients to control or indicate preferred compression methods, improving transfer speed and bandwidth usage. It can be used with both direct requests and stateful sessions. ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::AcceptEncoding{{cpr::AcceptEncodingMethods::deflate, cpr::AcceptEncodingMethods::gzip, cpr::AcceptEncodingMethods::zlib}}); // or you could specify specific schemes with the customized string cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::AcceptEncoding{{"deflate", "gzip", "zlib"}}); ``` ```cpp cpr::Url url{server->GetBaseUrl() + "/check_accept_encoding.html"}; cpr::Session session; session.SetUrl(url); session.SetAcceptEncoding({{cpr::AcceptEncodingMethods::deflate, cpr::AcceptEncodingMethods::gzip, cpr::AcceptEncodingMethods::zlib}}); // or you could specify specific schemes with the customized string session.SetAcceptEncoding({{"deflate", "gzip", "zlib"}}); Response response = session.Get(); ``` ```cpp // An empty list of accepted encodings in combination with a direct request without any state cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/get"}, cpr::AcceptEncoding{}); // An empty list of accepted encodings in combination with a stateful cpr::Session object session.SetAcceptEncoding(cpr::AcceptEncoding{}); ``` -------------------------------- ### Performing PATCH Requests with CPR Source: https://docs.libcpr.dev/advanced-usage Demonstrates how to execute HTTP PATCH requests using the CPR library. This is typically used for partial modifications of a resource. Dependencies include CPR, iostream, and cassert. ```cpp #include // We can't POST or PUT to the "/patch" endpoint so the status code is rightly 405 assert(cpr::Post(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}).status_code == 405); assert(cpr::Put(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}).status_code == 405); // On the other hand, this works just fine[libcurl](http://curl.haxx.se/libcurl/) cpr::Response r = cpr::Patch(cpr::Url{"http://www.httpbin.org/patch"}, cpr::Payload{{"key", "value"}}); std::cout << r.text << std::endl; ``` -------------------------------- ### Build and Test cpr with CMake Source: https://docs.libcpr.dev/index This code demonstrates how to build cpr with tests enabled using CMake. It involves cloning the repository, configuring the build with `-DCPR_BUILD_TESTS=ON`, building, and then running the tests using `ctest`. Other test-related options like SSL and proxy support are also mentioned. ```cmake 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 ``` -------------------------------- ### Inject Multiple Headers from Different Sources in cpr Source: https://docs.libcpr.dev/advanced-usage Shows how to combine headers from different sources, including a helper function and explicit header object, in a cpr GET request. This is beneficial for modularizing header injection from various utilities. ```cpp template cpr::Response myGet(Ts&& ...ts) { return cpr::Get(std::forward(ts)..., cpr::Header{{"Authorization", "token"}}); } ... cpr::Response r = cpr::myGet(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Header{{"accept", "application/json"}}); std::cout << r.text << std::endl; /* * "headers": { * "Accept": "application/json", * "Accept-Encoding": "deflate, gzip", * "Authorization": "token", * "Host": "www.httpbin.org", * "User-Agent": "curl/7.81.0" * } */ ``` -------------------------------- ### Set Custom Request Headers in cpr Source: https://docs.libcpr.dev/advanced-usage Demonstrates setting custom 'accept' header in a cpr GET request. The response text will show the sent headers, including the custom one. This is useful for controlling request details like content negotiation. ```cpp cpr::Response r = cpr::Get(cpr::Url{"http://www.httpbin.org/headers"}, cpr::Header{{"accept", "application/json"}}); std::cout << r.text << std::endl; /* * "headers": { * "Accept": "application/json", * "Host": "www.httpbin.org", * "User-Agent": "curl/7.42.0-DEV" * } */ ```