1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 00:37:15 +01:00

Update CPR to latest git.

This commit is contained in:
Sandu Liviu Catalin 2021-08-22 20:28:37 +03:00
parent 69a4d305a5
commit f23a2fe389
16 changed files with 284 additions and 281 deletions

View File

@ -13,6 +13,7 @@ add_library(CPR STATIC
cpr/payload.cpp
cpr/proxies.cpp
cpr/proxyauth.cpp
cpr/redirect.cpp
cpr/session.cpp
cpr/timeout.cpp
cpr/unix_socket.cpp
@ -30,14 +31,15 @@ add_library(CPR STATIC
include/cpr/curlholder.h
include/cpr/digest.h
include/cpr/error.h
include/cpr/interface.h
include/cpr/limit_rate.h
include/cpr/max_redirects.h
include/cpr/multipart.h
include/cpr/ntlm.h
include/cpr/parameters.h
include/cpr/payload.h
include/cpr/proxies.h
include/cpr/proxyauth.h
include/cpr/redirect.h
include/cpr/response.h
include/cpr/session.h
include/cpr/ssl_options.h

View File

@ -1,27 +0,0 @@
# Contributing to C++ Requests
Please fork this repository and contribute back using [pull requests](https://github.com/whoshuu/cpr/pulls). Features can be requested using [issues](https://github.com/whoshuu/cpr/issues). All code, comments, and critiques are greatly appreciated.
## Formatting
To avoid unproductive debates on formatting, this project uses `clang-format` to ensure a consistent style across all source files. Currently, `clang-format` 3.8 is the version of `clang-format` we use. The format file can be found [here](https://github.com/whoshuu/cpr/blob/master/.clang-format). To install `clang-format` on Ubuntu, run this:
```
apt-get install clang-format-3.8
```
To install `clang-format` on OS X, run this:
```
brew install clang-format
```
Note that `brew` might install a later version of `clang-format`, but it should be mostly compatible with what's run on the Travis servers.
To run `clang-format` on every source file, run this in the root directory:
```
./format-check.sh
```
This should indicate which files need formatting and also show a diff of the requested changes. More specific usage instructions can be found on the official [LLVM website](http://releases.llvm.org/3.8.0/tools/clang/docs/ClangFormat.html).

141
vendor/CPR/README.md vendored
View File

@ -1,141 +0,0 @@
# C++ Requests: Curl for People <img align="right" height="40" src="http://i.imgur.com/d9Xtyts.png">
[![Documentation](https://img.shields.io/badge/docs-online-informational?style=flat&link=https://whoshuu.github.io/cpr/)](https://whoshuu.github.io/cpr/)
![CI](https://github.com/whoshuu/cpr/workflows/CI/badge.svg)
## Announcements
The cpr project has new maintainers: [Fabian Sauter](https://github.com/com8) and [Tim Stack](https://github.com/tstack).
## TLDR
C++ Requests is a simple wrapper around [libcurl](http://curl.haxx.se/libcurl) inspired by the excellent [Python Requests](https://github.com/kennethreitz/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:
```c++
#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
}
```
And here's [less functional, more complicated code, without cpr](https://gist.github.com/whoshuu/2dc858b8730079602044).
## Documentation
[![Documentation](https://img.shields.io/badge/docs-online-informational?style=for-the-badge&link=https://whoshuu.github.io/cpr/)](https://whoshuu.github.io/cpr/)
You can find the latest documentation [here](https://whoshuu.github.io/cpr). It's a work in progress, but it should give you a better idea of how to use the library than the [tests](https://github.com/whoshuu/cpr/tree/master/test) 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
* :cookie: support!
* Proxy support
* Callback interfaces
* PUT methods
* DELETE methods
* HEAD methods
* OPTIONS methods
* PATCH methods
* Thread Safe access to [libCurl](https://curl.haxx.se/libcurl/c/threadsafe.html)
* OpenSSL and WinSSL support for HTTPS requests
## Planned
For a quick overview about the planed features, have a look at the next [Milestones](https://github.com/whoshuu/cpr/milestones).
## Usage
If you already have a project you need to integrate C++ Requests with, the primary way is to use CMake `fetch_content`.
Add the following to your `CMakeLists.txt`.
```cmake
include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/whoshuu/cpr.git GIT_TAG c8d33915dbd88ad6c92b258869b03aba06587ff9) # the commit hash for 1.5.0
FetchContent_MakeAvailable(cpr)
```
This will produce the target `cpr::cpr` which you can link against the typical way:
```cmake
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.
## 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](https://github.com/Microsoft/vcpkg) dependency manager:
```Bash
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](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Building cpr - Using Conan
You can download and install `cpr` using the [Conan](https://conan.io/) package manager. Setup your CMakeLists.txt (see [Conan documentation](https://docs.conan.io/en/latest/integrations/build_system.html) on how to use MSBuild, Meson and others) like this:
```CMake
project(myproject CXX)
add_executable(${PROJECT_NAME} main.cpp)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) # Include Conan-generated file
conan_basic_setup(TARGETS) # Introduce Conan-generated targets
target_link_libraries(${PROJECT_NAME} CONAN_PKG::cpr)
```
Create `conanfile.txt` in your source dir:
```
[requires]
cpr/1.5.0
[generators]
cmake
```
Install and run Conan, then build your project as always:
```Bash
pip install conan
mkdir build
cd build
conan install ../ --build=missing
cmake ../
cmake --build .
```
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](https://github.com/conan-io/conan-center-index) on the `conan-center-index` repository.

View File

@ -6,9 +6,6 @@ namespace cpr {
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
std::mutex CurlHolder::curl_easy_init_mutex_{};
#ifndef _WIN32 // There is no thread sanitizer on windows
__attribute__((no_sanitize("thread")))
#endif
CurlHolder::CurlHolder() {
/**
* Allow multithreaded access to CPR by locking curl_easy_init().

View File

@ -11,7 +11,6 @@ bool ProxyAuthentication::has(const std::string& protocol) const {
const char* ProxyAuthentication::operator[](const std::string& protocol) {
return proxyAuth_[protocol].GetAuthString();
;
}
} // namespace cpr

40
vendor/CPR/cpr/redirect.cpp vendored Normal file
View File

@ -0,0 +1,40 @@
#include "cpr/redirect.h"
namespace cpr {
PostRedirectFlags operator|(PostRedirectFlags lhs, PostRedirectFlags rhs) {
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
}
PostRedirectFlags operator&(PostRedirectFlags lhs, PostRedirectFlags rhs) {
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
}
PostRedirectFlags operator^(PostRedirectFlags lhs, PostRedirectFlags rhs) {
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) ^ static_cast<uint8_t>(rhs));
}
PostRedirectFlags operator~(PostRedirectFlags flag) {
return static_cast<PostRedirectFlags>(~static_cast<uint8_t>(flag));
}
PostRedirectFlags& operator|=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
uint8_t tmp = static_cast<uint8_t>(lhs);
lhs = static_cast<PostRedirectFlags>(tmp);
return lhs;
}
PostRedirectFlags& operator&=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
return lhs;
}
PostRedirectFlags& operator^=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) ^ static_cast<uint8_t>(rhs));
return lhs;
}
bool any(PostRedirectFlags flag) {
return flag != PostRedirectFlags::NONE;
}
} // namespace cpr

View File

@ -35,7 +35,7 @@ std::vector<std::string> Response::GetCertInfo() {
std::vector<std::string> info;
info.resize(ci->num_of_certs);
for (size_t i = 0; i < ci->num_of_certs; i++) {
for (int i = 0; i < ci->num_of_certs; i++) {
// No way around here.
// NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
info[i] = std::string{ci->certinfo[i]->data};

View File

@ -49,8 +49,7 @@ class Session::Impl {
void SetMultipart(Multipart&& multipart);
void SetMultipart(const Multipart& multipart);
void SetNTLM(const NTLM& auth);
void SetRedirect(const bool& redirect);
void SetMaxRedirects(const MaxRedirects& max_redirects);
void SetRedirect(const Redirect& redirect);
void SetCookies(const Cookies& cookies);
void SetBody(Body&& body);
void SetBody(const Body& body);
@ -65,7 +64,9 @@ class Session::Impl {
void SetUnixSocket(const UnixSocket& unix_socket);
void SetVerbose(const Verbose& verbose);
void SetSslOptions(const SslOptions& options);
void SetInterface(const Interface& iface);
cpr_off_t GetDownloadFileLength();
Response Delete();
Response Download(const WriteCallback& write);
Response Download(std::ofstream& file);
@ -121,9 +122,8 @@ Session::Impl::Impl() : curl_(new CurlHolder()) {
curl_version_info_data* version_info = curl_version_info(CURLVERSION_NOW);
std::string version = "curl/" + std::string{version_info->version};
curl_easy_setopt(curl_->handle, CURLOPT_USERAGENT, version.c_str());
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, 1L);
SetRedirect(Redirect());
curl_easy_setopt(curl_->handle, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, 50L);
curl_easy_setopt(curl_->handle, CURLOPT_ERRORBUFFER, curl_->error.data());
curl_easy_setopt(curl_->handle, CURLOPT_COOKIEFILE, "");
#ifdef CPR_CURL_NOSIGNAL
@ -209,6 +209,14 @@ void Session::Impl::SetAuth(const Authentication& auth) {
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
}
void Session::Impl::SetInterface(const Interface& iface) {
if (iface.str().empty()) {
curl_easy_setopt(curl_->handle, CURLOPT_INTERFACE, nullptr);
} else {
curl_easy_setopt(curl_->handle, CURLOPT_INTERFACE, iface.c_str());
}
}
// Only supported with libcurl >= 7.61.0.
// As an alternative use SetHeader and add the token manually.
#if LIBCURL_VERSION_NUM >= 0x073D00
@ -232,16 +240,14 @@ void Session::Impl::SetUserAgent(const UserAgent& ua) {
void Session::Impl::SetPayload(Payload&& payload) {
hasBodyOrPayload_ = true;
const std::string content = payload.GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
}
void Session::Impl::SetPayload(const Payload& payload) {
hasBodyOrPayload_ = true;
const std::string content = payload.GetContent(*curl_);
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(content.length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
}
@ -269,9 +275,7 @@ void Session::Impl::SetMultipart(Multipart&& multipart) {
std::vector<curl_forms> formdata;
if (part.is_buffer) {
// Do not use formdata, to prevent having to use reinterpreter_cast:
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER,
part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH,
part.datalen, CURLFORM_END);
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER, part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH, part.datalen, CURLFORM_END);
} else {
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
if (part.is_file) {
@ -302,9 +306,7 @@ void Session::Impl::SetMultipart(const Multipart& multipart) {
std::vector<curl_forms> formdata;
if (part.is_buffer) {
// Do not use formdata, to prevent having to use reinterpreter_cast:
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER,
part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH,
part.datalen, CURLFORM_END);
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER, part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH, part.datalen, CURLFORM_END);
} else {
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
if (part.is_file) {
@ -338,12 +340,22 @@ void Session::Impl::SetNTLM(const NTLM& auth) {
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
}
void Session::Impl::SetRedirect(const bool& redirect) {
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, std::int32_t(redirect));
}
void Session::Impl::SetRedirect(const Redirect& redirect) {
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, redirect.follow ? 1L : 0L);
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, redirect.maximum);
void Session::Impl::SetMaxRedirects(const MaxRedirects& max_redirects) {
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, max_redirects.number_of_redirects);
// NOLINTNEXTLINE (google-runtime-int)
long mask = 0;
if (any(redirect.post_flags & PostRedirectFlags::POST_301)) {
mask |= CURL_REDIR_POST_301;
}
if (any(redirect.post_flags & PostRedirectFlags::POST_302)) {
mask |= CURL_REDIR_POST_302;
}
if (any(redirect.post_flags & PostRedirectFlags::POST_303)) {
mask |= CURL_REDIR_POST_303;
}
curl_easy_setopt(curl_->handle, CURLOPT_POSTREDIR, mask);
}
void Session::Impl::SetCookies(const Cookies& cookies) {
@ -353,15 +365,13 @@ void Session::Impl::SetCookies(const Cookies& cookies) {
void Session::Impl::SetBody(Body&& body) {
hasBodyOrPayload_ = true;
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body.c_str());
}
void Session::Impl::SetBody(const Body& body) {
hasBodyOrPayload_ = true;
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE,
static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body.str().length()));
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, body.c_str());
}
@ -449,13 +459,15 @@ void Session::Impl::SetSslOptions(const SslOptions& options) {
#if LIBCURL_VERSION_NUM >= 0x072900
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYSTATUS, options.verify_status ? ON : OFF);
#endif
int maxTlsVersion = options.ssl_version;
#if SUPPORT_MAX_TLS_VERSION
maxTlsVersion |= options.max_version;
#endif
curl_easy_setopt(curl_->handle, CURLOPT_SSLVERSION,
// Ignore here since this has been defined by libcurl.
options.ssl_version
#if SUPPORT_MAX_TLS_VERSION
| options.max_version
#endif
);
maxTlsVersion);
#if SUPPORT_SSL_NO_REVOKE
if (options.ssl_no_revoke) {
curl_easy_setopt(curl_->handle, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
@ -479,8 +491,7 @@ void Session::Impl::SetSslOptions(const SslOptions& options) {
}
#endif
#if SUPPORT_SESSIONID_CACHE
curl_easy_setopt(curl_->handle, CURLOPT_SSL_SESSIONID_CACHE,
options.session_id_cache ? ON : OFF);
curl_easy_setopt(curl_->handle, CURLOPT_SSL_SESSIONID_CACHE, options.session_id_cache ? ON : OFF);
#endif
}
@ -491,6 +502,27 @@ void Session::Impl::PrepareDelete() {
prepareCommon();
}
cpr_off_t Session::Impl::GetDownloadFileLength() {
cpr_off_t downloadFileLenth = -1;
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
std::string protocol = url_.str().substr(0, url_.str().find(':'));
if (proxies_.has(protocol)) {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
if (proxyAuth_.has(protocol)) {
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
}
}
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 1);
if (curl_easy_perform(curl_->handle) == CURLE_OK) {
curl_easy_getinfo(curl_->handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &downloadFileLenth);
}
return downloadFileLenth;
}
Response Session::Impl::Delete() {
PrepareDelete();
return makeRequest();
@ -498,7 +530,7 @@ Response Session::Impl::Delete() {
Response Session::Impl::Download(const WriteCallback& write) {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
SetWriteCallback(write);
@ -507,7 +539,7 @@ Response Session::Impl::Download(const WriteCallback& write) {
Response Session::Impl::Download(std::ofstream& file) {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeFileFunction);
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &file);
@ -616,8 +648,6 @@ Response Session::Impl::makeDownloadRequest() {
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
}
} else {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, "");
}
curl_->error[0] = '\0';
@ -633,14 +663,18 @@ Response Session::Impl::makeDownloadRequest() {
CURLcode curl_error = curl_easy_perform(curl_->handle);
if (!headercb_.callback) {
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, nullptr);
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, 0);
}
curl_slist* raw_cookies{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
Cookies cookies = util::parseCookies(raw_cookies);
curl_slist_free_all(raw_cookies);
std::string errorMsg = curl_->error.data();
return Response(curl_, "", std::move(header_string), std::move(cookies),
Error(curl_error, std::move(errorMsg)));
return Response(curl_, "", std::move(header_string), std::move(cookies), Error(curl_error, std::move(errorMsg)));
}
void Session::Impl::prepareCommon() {
@ -665,8 +699,6 @@ void Session::Impl::prepareCommon() {
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
}
} else {
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, nullptr);
}
#if LIBCURL_VERSION_MAJOR >= 7
@ -700,14 +732,12 @@ void Session::Impl::prepareCommon() {
curl_easy_setopt(curl_->handle, CURLOPT_CERTINFO, 1L);
}
Response Session::Impl::makeRequest()
{
Response Session::Impl::makeRequest() {
CURLcode curl_error = curl_easy_perform(curl_->handle);
return Complete(curl_error);
}
Response Session::Impl::Complete(CURLcode curl_error)
{
Response Session::Impl::Complete(CURLcode curl_error) {
curl_slist* raw_cookies{nullptr};
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
Cookies cookies = util::parseCookies(raw_cookies);
@ -717,13 +747,12 @@ Response Session::Impl::Complete(CURLcode curl_error)
hasBodyOrPayload_ = false;
std::string errorMsg = curl_->error.data();
return Response(curl_, std::move(response_string_), std::move(header_string_), std::move(cookies),
Error(curl_error, std::move(errorMsg)));
return Response(curl_, std::move(response_string_), std::move(header_string_), std::move(cookies), Error(curl_error, std::move(errorMsg)));
}
// clang-format off
Session::Session() : pimpl_(new Impl()) {}
Session::Session(Session&& old) noexcept = default;
Session::Session(Session&& /*old*/) noexcept = default;
Session::~Session() = default;
Session& Session::operator=(Session&& old) noexcept = default;
void Session::SetReadCallback(const ReadCallback& read) { pimpl_->SetReadCallback(read); }
@ -750,8 +779,7 @@ void Session::SetProxyAuth(const ProxyAuthentication& proxy_auth) { pimpl_->SetP
void Session::SetMultipart(const Multipart& multipart) { pimpl_->SetMultipart(multipart); }
void Session::SetMultipart(Multipart&& multipart) { pimpl_->SetMultipart(std::move(multipart)); }
void Session::SetNTLM(const NTLM& auth) { pimpl_->SetNTLM(auth); }
void Session::SetRedirect(const bool& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetMaxRedirects(const MaxRedirects& max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
void Session::SetRedirect(const Redirect& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetCookies(const Cookies& cookies) { pimpl_->SetCookies(cookies); }
void Session::SetBody(const Body& body) { pimpl_->SetBody(body); }
void Session::SetBody(Body&& body) { pimpl_->SetBody(std::move(body)); }
@ -760,6 +788,7 @@ void Session::SetVerifySsl(const VerifySsl& verify) { pimpl_->SetVerifySsl(verif
void Session::SetUnixSocket(const UnixSocket& unix_socket) { pimpl_->SetUnixSocket(unix_socket); }
void Session::SetSslOptions(const SslOptions& options) { pimpl_->SetSslOptions(options); }
void Session::SetVerbose(const Verbose& verbose) { pimpl_->SetVerbose(verbose); }
void Session::SetInterface(const Interface& iface) { pimpl_->SetInterface(iface); }
void Session::SetOption(const ReadCallback& read) { pimpl_->SetReadCallback(read); }
void Session::SetOption(const HeaderCallback& header) { pimpl_->SetHeaderCallback(header); }
void Session::SetOption(const WriteCallback& write) { pimpl_->SetWriteCallback(write); }
@ -789,8 +818,7 @@ void Session::SetOption(const ProxyAuthentication& proxy_auth) { pimpl_->SetProx
void Session::SetOption(const Multipart& multipart) { pimpl_->SetMultipart(multipart); }
void Session::SetOption(Multipart&& multipart) { pimpl_->SetMultipart(std::move(multipart)); }
void Session::SetOption(const NTLM& auth) { pimpl_->SetNTLM(auth); }
void Session::SetOption(const bool& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetOption(const MaxRedirects& max_redirects) { pimpl_->SetMaxRedirects(max_redirects); }
void Session::SetOption(const Redirect& redirect) { pimpl_->SetRedirect(redirect); }
void Session::SetOption(const Cookies& cookies) { pimpl_->SetCookies(cookies); }
void Session::SetOption(const Body& body) { pimpl_->SetBody(body); }
void Session::SetOption(Body&& body) { pimpl_->SetBody(std::move(body)); }
@ -799,7 +827,9 @@ void Session::SetOption(const VerifySsl& verify) { pimpl_->SetVerifySsl(verify);
void Session::SetOption(const Verbose& verbose) { pimpl_->SetVerbose(verbose); }
void Session::SetOption(const UnixSocket& unix_socket) { pimpl_->SetUnixSocket(unix_socket); }
void Session::SetOption(const SslOptions& options) { pimpl_->SetSslOptions(options); }
void Session::SetOption(const Interface& iface) { pimpl_->SetInterface(iface); }
cpr_off_t Session::GetDownloadFileLength() { return pimpl_->GetDownloadFileLength(); }
Response Session::Delete() { return pimpl_->Delete(); }
Response Session::Download(const WriteCallback& write) { return pimpl_->Download(write); }
Response Session::Download(std::ofstream& file) { return pimpl_->Download(file); }

View File

@ -2,28 +2,25 @@
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <string>
#include <type_traits>
namespace cpr {
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
long Timeout::Milliseconds() const {
static_assert(std::is_same<std::chrono::milliseconds, decltype(ms)>::value,
"Following casting expects milliseconds.");
static_assert(std::is_same<std::chrono::milliseconds, decltype(ms)>::value, "Following casting expects milliseconds.");
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
if (ms.count() > std::numeric_limits<long>::max()) {
throw std::overflow_error(
"cpr::Timeout: timeout value overflow: " + std::to_string(ms.count()) + " ms.");
throw std::overflow_error("cpr::Timeout: timeout value overflow: " + std::to_string(ms.count()) + " ms.");
}
// No way around since curl uses a long here.
// NOLINTNEXTLINE(google-runtime-int)
if (ms.count() < std::numeric_limits<long>::min()) {
throw std::underflow_error(
"cpr::Timeout: timeout value underflow: " + std::to_string(ms.count()) + " ms.");
throw std::underflow_error("cpr::Timeout: timeout value underflow: " + std::to_string(ms.count()) + " ms.");
}
// No way around since curl uses a long here.

View File

@ -89,12 +89,12 @@ std::vector<std::string> split(const std::string& to_split, char delimiter) {
size_t readUserFunction(char* ptr, size_t size, size_t nitems, const ReadCallback* read) {
size *= nitems;
return read->callback(ptr, size) ? size : CURL_READFUNC_ABORT;
return (*read)(ptr, size) ? size : CURL_READFUNC_ABORT;
}
size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCallback* header) {
size *= nmemb;
return header->callback({ptr, size}) ? size : 0;
return (*header)({ptr, size}) ? size : 0;
}
size_t writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data) {
@ -111,7 +111,7 @@ size_t writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* fi
size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write) {
size *= nmemb;
return write->callback({ptr, size}) ? size : 0;
return (*write)({ptr, size}) ? size : 0;
}
#if LIBCURL_VERSION_NUM < 0x072000
@ -121,12 +121,12 @@ int progressUserFunction(const ProgressCallback* progress, double dltotal, doubl
int progressUserFunction(const ProgressCallback* progress, curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow) {
#endif
return progress->callback(dltotal, dlnow, ultotal, ulnow) ? 0 : 1;
return (*progress)(dltotal, dlnow, ultotal, ulnow) ? 0 : 1;
}
int debugUserFunction(CURL* /*handle*/, curl_infotype type, char* data, size_t size,
const DebugCallback* debug) {
debug->callback(DebugCallback::InfoType(type), std::string(data, size));
(*debug)(DebugCallback::InfoType(type), std::string(data, size));
return 0;
}

View File

@ -12,46 +12,54 @@ class ReadCallback {
public:
ReadCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ReadCallback(std::function<bool(char* buffer, size_t& size)> p_callback)
: size{-1}, callback{std::move(p_callback)} {}
ReadCallback(cpr_off_t p_size, std::function<bool(char* buffer, size_t& size)> p_callback)
: size{p_size}, callback{std::move(p_callback)} {}
ReadCallback(std::function<bool(char* buffer, size_t& size, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), size{-1}, callback{std::move(p_callback)} {}
ReadCallback(cpr_off_t p_size, std::function<bool(char* buffer, size_t& size, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), size{p_size}, callback{std::move(p_callback)} {}
bool operator()(char* buffer, size_t& size) const {
return callback(buffer, size, userdata);
}
intptr_t userdata;
cpr_off_t size{};
std::function<bool(char* buffer, size_t& size)> callback;
std::function<bool(char* buffer, size_t& size, intptr_t userdata)> callback;
};
class HeaderCallback {
public:
HeaderCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
HeaderCallback(std::function<bool(std::string header)> p_callback)
: callback(std::move(p_callback)) {}
HeaderCallback(std::function<bool(std::string header, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {}
bool operator()(std::string header) const {
return callback(std::move(header), userdata);
}
std::function<bool(std::string header)> callback;
intptr_t userdata;
std::function<bool(std::string header, intptr_t userdata)> callback;
};
class WriteCallback {
public:
WriteCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
WriteCallback(std::function<bool(std::string data)> p_callback) : callback(std::move(p_callback)) {}
WriteCallback(std::function<bool(std::string data, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {}
bool operator()(std::string data) const {
return callback(std::move(data), userdata);
}
std::function<bool(std::string data)> callback;
intptr_t userdata;
std::function<bool(std::string data, intptr_t userdata)> callback;
};
class ProgressCallback {
public:
ProgressCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
ProgressCallback(std::function<bool(size_t downloadTotal, size_t downloadNow,
size_t uploadTotal, size_t uploadNow)>
p_callback)
: callback(std::move(p_callback)) {}
ProgressCallback(std::function<bool(cpr_off_t downloadTotal, cpr_off_t downloadNow, cpr_off_t uploadTotal, cpr_off_t uploadNow, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {}
bool operator()(cpr_off_t downloadTotal, cpr_off_t downloadNow, cpr_off_t uploadTotal, cpr_off_t uploadNow) const {
return callback(downloadTotal, downloadNow, uploadTotal, uploadNow, userdata);
}
std::function<bool(size_t downloadTotal, size_t downloadNow, size_t uploadTotal,
size_t uploadNow)>
callback;
intptr_t userdata;
std::function<bool(size_t downloadTotal, size_t downloadNow, size_t uploadTotal, size_t uploadNow, intptr_t userdata)> callback;
};
class DebugCallback {
@ -67,10 +75,13 @@ class DebugCallback {
};
DebugCallback() = default;
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
DebugCallback(std::function<void(InfoType type, std::string data)> p_callback)
: callback(std::move(p_callback)) {}
DebugCallback(std::function<void(InfoType type, std::string data, intptr_t userdata)> p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {}
void operator()(InfoType type, std::string data) const {
callback(type, std::move(data), userdata);
}
std::function<void(InfoType type, std::string data)> callback;
intptr_t userdata;
std::function<void(InfoType type, std::string data, intptr_t userdata)> callback;
};
} // namespace cpr

View File

@ -4,6 +4,8 @@
#include "cpr/api.h"
#include "cpr/auth.h"
#include "cpr/cprtypes.h"
#include "cpr/interface.h"
#include "cpr/redirect.h"
#include "cpr/response.h"
#include "cpr/session.h"
#include "cpr/status_codes.h"

32
vendor/CPR/include/cpr/interface.h vendored Normal file
View File

@ -0,0 +1,32 @@
#ifndef CPR_INTERFACE_H
#define CPR_INTERFACE_H
#include <initializer_list>
#include <string>
#include "cpr/cprtypes.h"
namespace cpr {
class Interface : public StringHolder<Interface> {
public:
Interface() : StringHolder<Interface>() {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Interface(const std::string& iface) : StringHolder<Interface>(iface) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Interface(std::string&& iface) : StringHolder<Interface>(std::move(iface)) {}
// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
Interface(const char* iface) : StringHolder<Interface>(iface) {}
Interface(const char* str, size_t len) : StringHolder<Interface>(str, len) {}
Interface(const std::initializer_list<std::string> args) : StringHolder<Interface>(args) {}
Interface(const Interface& other) = default;
Interface(Interface&& old) noexcept = default;
~Interface() override = default;
Interface& operator=(Interface&& old) noexcept = default;
Interface& operator=(const Interface& other) = default;
};
} // namespace cpr
#endif

View File

@ -1,18 +0,0 @@
#ifndef CPR_MAX_REDIRECTS_H
#define CPR_MAX_REDIRECTS_H
#include <cstdint>
namespace cpr {
class MaxRedirects {
public:
explicit MaxRedirects(const std::int32_t p_number_of_redirects)
: number_of_redirects(p_number_of_redirects) {}
std::int32_t number_of_redirects;
};
} // namespace cpr
#endif

77
vendor/CPR/include/cpr/redirect.h vendored Normal file
View File

@ -0,0 +1,77 @@
#ifndef CPR_REDIRECT_H
#define CPR_REDIRECT_H
#include <cstdint>
namespace cpr {
enum class PostRedirectFlags : uint8_t {
/**
* Respect RFC 7231 (section 6.4.2 to 6.4.4).
* Same as CURL_REDIR_POST_301 (https://curl.se/libcurl/c/CURLOPT_POSTREDIR.html).
**/
POST_301 = 0x1 << 0,
/**
* Maintain the request method after a 302 redirect.
* Same as CURL_REDIR_POST_302 (https://curl.se/libcurl/c/CURLOPT_POSTREDIR.html).
**/
POST_302 = 0x1 << 1,
/**
* Maintain the request method after a 303 redirect.
* Same as CURL_REDIR_POST_303 (https://curl.se/libcurl/c/CURLOPT_POSTREDIR.html).
**/
POST_303 = 0x1 << 2,
/**
* Default value.
* Convenience option to enable all flags.
* Same as CURL_REDIR_POST_ALL (https://curl.se/libcurl/c/CURLOPT_POSTREDIR.html).
**/
POST_ALL = POST_301 | POST_302 | POST_303,
/**
* * Convenience option to disable all flags.
**/
NONE = 0x0
};
PostRedirectFlags operator|(PostRedirectFlags lhs, PostRedirectFlags rhs);
PostRedirectFlags operator&(PostRedirectFlags lhs, PostRedirectFlags rhs);
PostRedirectFlags operator^(PostRedirectFlags lhs, PostRedirectFlags rhs);
PostRedirectFlags operator~(PostRedirectFlags flag);
PostRedirectFlags& operator|=(PostRedirectFlags& lhs, PostRedirectFlags rhs);
PostRedirectFlags& operator&=(PostRedirectFlags& lhs, PostRedirectFlags rhs);
PostRedirectFlags& operator^=(PostRedirectFlags& lhs, PostRedirectFlags rhs);
bool any(PostRedirectFlags flag);
class Redirect {
public:
/**
* The maximum number of redirects to follow.
* 0: Refuse any redirects.
* -1: Infinite number of redirects.
* Default: 50
* https://curl.se/libcurl/c/CURLOPT_MAXREDIRS.html
**/
// NOLINTNEXTLINE (cppcoreguidelines-avoid-magic-numbers, google-runtime-int)
long maximum{50L};
/**
* Follow 3xx redirects.
* Default: true
* https://curl.se/libcurl/c/CURLOPT_FOLLOWLOCATION.html
**/
bool follow{true};
/**
* Flags to control how to act after a redirect for a post request.
* Default: POST_ALL
**/
PostRedirectFlags post_flags{PostRedirectFlags::POST_ALL};
Redirect() = default;
// NOLINTNEXTLINE (google-runtime-int)
Redirect(long p_maximum, bool p_follow, PostRedirectFlags p_post_flags) : maximum(p_maximum), follow(p_follow), post_flags(p_post_flags){};
// NOLINTNEXTLINE (google-runtime-int)
explicit Redirect(long p_maximum) : maximum(p_maximum){};
explicit Redirect(bool p_follow) : follow(p_follow){};
explicit Redirect(PostRedirectFlags p_post_flags) : post_flags(p_post_flags){};
};
} // namespace cpr
#endif

View File

@ -14,15 +14,16 @@
#include "cpr/cprtypes.h"
#include "cpr/curlholder.h"
#include "cpr/digest.h"
#include "cpr/interface.h"
#include "cpr/limit_rate.h"
#include "cpr/low_speed.h"
#include "cpr/max_redirects.h"
#include "cpr/multipart.h"
#include "cpr/ntlm.h"
#include "cpr/parameters.h"
#include "cpr/payload.h"
#include "cpr/proxies.h"
#include "cpr/proxyauth.h"
#include "cpr/redirect.h"
#include "cpr/response.h"
#include "cpr/ssl_options.h"
#include "cpr/timeout.h"
@ -62,8 +63,7 @@ class Session {
void SetMultipart(Multipart&& multipart);
void SetMultipart(const Multipart& multipart);
void SetNTLM(const NTLM& auth);
void SetRedirect(const bool& redirect);
void SetMaxRedirects(const MaxRedirects& max_redirects);
void SetRedirect(const Redirect& redirect);
void SetCookies(const Cookies& cookies);
void SetBody(Body&& body);
void SetBody(const Body& body);
@ -77,6 +77,7 @@ class Session {
void SetProgressCallback(const ProgressCallback& progress);
void SetDebugCallback(const DebugCallback& debug);
void SetVerbose(const Verbose& verbose);
void SetInterface(const Interface& iface);
// Used in templated functions
void SetOption(const Url& url);
@ -103,8 +104,7 @@ class Session {
void SetOption(Multipart&& multipart);
void SetOption(const Multipart& multipart);
void SetOption(const NTLM& auth);
void SetOption(const bool& redirect);
void SetOption(const MaxRedirects& max_redirects);
void SetOption(const Redirect& redirect);
void SetOption(const Cookies& cookies);
void SetOption(Body&& body);
void SetOption(const Body& body);
@ -118,7 +118,9 @@ class Session {
void SetOption(const Verbose& verbose);
void SetOption(const UnixSocket& unix_socket);
void SetOption(const SslOptions& options);
void SetOption(const Interface& iface);
cpr_off_t GetDownloadFileLength();
Response Delete();
Response Download(const WriteCallback& write);
Response Download(std::ofstream& file);