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

Compare commits

...

4 Commits

Author SHA1 Message Date
Sandu Liviu Catalin
b67a637c61 Add xxHash library. 2021-08-22 22:27:08 +03:00
Sandu Liviu Catalin
c0fc1aea75 Add Levenshtein distance to string utilities. 2021-08-22 22:23:25 +03:00
Sandu Liviu Catalin
2a06a00e3e Update code for changes to CPR library. 2021-08-22 22:10:03 +03:00
Sandu Liviu Catalin
f23a2fe389 Update CPR to latest git. 2021-08-22 20:28:37 +03:00
25 changed files with 6000 additions and 303 deletions

View File

@ -133,7 +133,7 @@ if(WIN32 OR MINGW)
target_link_libraries(SqModule wsock32 ws2_32 shlwapi)
endif()
# Link to base libraries
target_link_libraries(SqModule Squirrel fmt::fmt SimpleINI TinyDir ConcurrentQueue SAJSON CPR PUGIXML maxminddb libzmq-static)
target_link_libraries(SqModule Squirrel fmt::fmt SimpleINI TinyDir xxHash ConcurrentQueue SAJSON CPR PUGIXML maxminddb libzmq-static)
# Link to POCO libraries
target_link_libraries(SqModule Poco::Foundation Poco::Crypto Poco::Data Poco::Net Poco::JSON Poco::XML)
# Does POCO have SQLite support?

View File

@ -16,6 +16,7 @@ SQMOD_DECL_TYPENAME(SqCpResponse, _SC("SqCprResponse"))
SQMOD_DECL_TYPENAME(SqCpParameters, _SC("SqCprParameters"))
SQMOD_DECL_TYPENAME(SqCpPayload, _SC("SqCprPayload"))
SQMOD_DECL_TYPENAME(SqCpProxies, _SC("SqCprProxies"))
SQMOD_DECL_TYPENAME(SqCpRedirect, _SC("SqCprRedirect"))
SQMOD_DECL_TYPENAME(SqCpSession, _SC("SqCprSession"))
/* ------------------------------------------------------------------------------------------------
@ -404,10 +405,20 @@ static const EnumElement g_StatusCodes[] = {
{_SC("MISC_CODE_OFFSET"), cpr::status::MISC_CODE_OFFSET}
};
// ------------------------------------------------------------------------------------------------
static const EnumElement g_PostRedirectFlags[] = {
{_SC("Post301"), static_cast< SQInteger >(cpr::PostRedirectFlags::POST_301)},
{_SC("Post302"), static_cast< SQInteger >(cpr::PostRedirectFlags::POST_302)},
{_SC("Post303"), static_cast< SQInteger >(cpr::PostRedirectFlags::POST_303)},
{_SC("Postall"), static_cast< SQInteger >(cpr::PostRedirectFlags::POST_ALL)},
{_SC("None"), static_cast< SQInteger >(cpr::PostRedirectFlags::NONE)},
};
// ------------------------------------------------------------------------------------------------
static const EnumElements g_EnumList[] = {
{_SC("SqCprErrorCode"), g_ErrorCodes},
{_SC("SqCprStatusCode"), g_StatusCodes}
{_SC("SqCprErrorCode"), g_ErrorCodes},
{_SC("SqCprStatusCode"), g_StatusCodes},
{_SC("SqCprPostRedirectFlags"), g_PostRedirectFlags}
};
// ================================================================================================
@ -605,6 +616,26 @@ void Register_CURL(HSQUIRRELVM vm)
.CbFunc(_SC("While"), &CpProxies::While)
);
// --------------------------------------------------------------------------------------------
cpns.Bind(_SC("Redirect"),
Class< CpRedirect >(vm, SqCpRedirect::Str)
// Constructors
.Ctor()
.Ctor< SQInteger >()
.Ctor< SQInteger, bool >()
.Ctor< SQInteger, bool, SQInteger >()
// Meta-methods
.SquirrelFunc(_SC("_typename"), &SqCpRedirect::Fn)
// Properties
.Prop(_SC("Maximum"), &CpRedirect::GetMaximum, &CpRedirect::SetMaximum)
.Prop(_SC("Follow"), &CpRedirect::GetFollow, &CpRedirect::SetFollow)
.Prop(_SC("Flags"), &CpRedirect::GetFlags, &CpRedirect::SetFlags)
// Member Methods
.Func(_SC("SetMaximum"), &CpRedirect::ApplyMaximum)
.Func(_SC("SetFollow"), &CpRedirect::ApplyFollow)
.Func(_SC("SetFlags"), &CpRedirect::ApplyFlags)
);
// --------------------------------------------------------------------------------------------
cpns.Bind(_SC("Session"),
Class< CpSession, NoCopy< CpSession > >(vm, SqCpSession::Str)
@ -631,7 +662,6 @@ void Register_CURL(HSQUIRRELVM vm)
.Func(_SC("YieldProxies"), &CpSession::YieldProxies)
.FmtFunc(_SC("SetNTLM"), &CpSession::SetNTLM_)
.Func(_SC("SetRedirect"), &CpSession::SetRedirect_)
.Func(_SC("SetMaxRedirects"), &CpSession::SetMaxRedirects_)
.Func(_SC("SetCookies"), &CpSession::SetCookies_)
.FmtFunc(_SC("SetBody"), &CpSession::SetBody_)
.Func(_SC("SetLowSpeed"), &CpSession::SetLowSpeed_)

View File

@ -888,7 +888,7 @@ struct CpResponse : public cpr::Response
*/
void SetStatusCode(SQInteger value)
{
cpr::Response::status_code = value;
cpr::Response::status_code = static_cast< long >(value);
}
/* --------------------------------------------------------------------------------------------
@ -1604,6 +1604,152 @@ struct CpProxies : public cpr::Proxies
}
};
/* ------------------------------------------------------------------------------------------------
* Wrapper for cpr::Redirect that can be bound to the script engine.
*/
struct CpRedirect : public cpr::Redirect
{
using cpr::Redirect::Redirect;
/* --------------------------------------------------------------------------------------------
* Default constructor.
*/
CpRedirect() = default;
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
explicit CpRedirect(SQInteger maximum)
: cpr::Redirect(static_cast< long >(maximum), true, cpr::PostRedirectFlags::POST_ALL)
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
CpRedirect(SQInteger maximum, bool follow)
: cpr::Redirect(static_cast< long >(maximum), follow, cpr::PostRedirectFlags::POST_ALL)
{
}
/* --------------------------------------------------------------------------------------------
* Explicit constructor.
*/
CpRedirect(SQInteger maximum, bool follow, SQInteger post_flags)
: cpr::Redirect(static_cast< long >(maximum), follow, static_cast< cpr::PostRedirectFlags >(post_flags))
{
}
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
explicit CpRedirect(const cpr::Redirect & e) : cpr::Redirect(e) { }
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
explicit CpRedirect(cpr::Redirect && e) : cpr::Redirect(e) { }
/* --------------------------------------------------------------------------------------------
* Copy constructor.
*/
CpRedirect(const CpRedirect &) = default;
/* --------------------------------------------------------------------------------------------
* Move constructor.
*/
CpRedirect(CpRedirect &&) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Destructor.
*/
~CpRedirect() = default;
/* --------------------------------------------------------------------------------------------
* Copy assignment operator.
*/
CpRedirect & operator = (const CpRedirect &) = default;
/* --------------------------------------------------------------------------------------------
* Move assignment operator.
*/
CpRedirect & operator = (CpRedirect &&) noexcept = default;
/* --------------------------------------------------------------------------------------------
* Retrieve the maximum number of redirects to follow. 0: Refuse any redirects. -1: Infinite number of redirects.
*/
SQMOD_NODISCARD SQInteger GetMaximum() const noexcept
{
return static_cast< SQInteger >(cpr::Redirect::maximum);
}
/* --------------------------------------------------------------------------------------------
* Modify the maximum number of redirects to follow. 0: Refuse any redirects. -1: Infinite number of redirects.
*/
void SetMaximum(SQInteger value) noexcept
{
cpr::Redirect::maximum = static_cast< long >(value);
}
/* --------------------------------------------------------------------------------------------
* Modify the maximum number of redirects to follow. 0: Refuse any redirects. -1: Infinite number of redirects.
*/
CpRedirect & ApplyMaximum(SQInteger value) noexcept
{
SetMaximum(value);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve whether to follow 3xx redirects.
*/
SQMOD_NODISCARD bool GetFollow() const noexcept
{
return cpr::Redirect::follow;
}
/* --------------------------------------------------------------------------------------------
* Modify whether to follow 3xx redirects.
*/
void SetFollow(bool value) noexcept
{
cpr::Redirect::follow = value;
}
/* --------------------------------------------------------------------------------------------
* Modify whether to follow 3xx redirects.
*/
CpRedirect & ApplyFollow(bool value) noexcept
{
SetMaximum(value);
return *this;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the flags to control how to act after a redirect for a post request.
*/
SQMOD_NODISCARD bool GetFlags() const noexcept
{
return cpr::Redirect::follow;
}
/* --------------------------------------------------------------------------------------------
* Modify the flags to control how to act after a redirect for a post request.
*/
void SetFlags(bool value) noexcept
{
cpr::Redirect::follow = value;
}
/* --------------------------------------------------------------------------------------------
* Modify the flags to control how to act after a redirect for a post request.
*/
CpRedirect & ApplyFlags(bool value) noexcept
{
SetMaximum(value);
return *this;
}
};
/* ------------------------------------------------------------------------------------------------
* Wrapper for cpr::Session that can be bound to the script engine.
*/
@ -1620,7 +1766,7 @@ struct CpSession : public cpr::Session
/* --------------------------------------------------------------------------------------------
* URL constructor.
*/
CpSession(StackStrF & url)
explicit CpSession(StackStrF & url)
: cpr::Session()
{
cpr::Session::SetUrl(cpr::Url(url.mPtr, url.GetSize()));
@ -1654,7 +1800,7 @@ struct CpSession : public cpr::Session
/* --------------------------------------------------------------------------------------------
* Throw exception if the session is locked.
*/
void LockCheck()
void LockCheck() const
{
if (mPending)
{
@ -1827,23 +1973,13 @@ struct CpSession : public cpr::Session
/* --------------------------------------------------------------------------------------------
* Modify redirect option.
*/
CpSession & SetRedirect_(bool redirect)
CpSession & SetRedirect_(CpRedirect & redirect)
{
LockCheck();
cpr::Session::SetRedirect(redirect);
return *this; // Allow chaining
}
/* --------------------------------------------------------------------------------------------
* Modify max-redirects option.
*/
CpSession & SetMaxRedirects_(SQInteger max_redirects)
{
LockCheck();
cpr::Session::SetMaxRedirects(cpr::MaxRedirects(static_cast< int32_t >(max_redirects)));
return *this; // Allow chaining
}
/* --------------------------------------------------------------------------------------------
* Modify cookies option.
*/

View File

@ -189,7 +189,7 @@ static LightObj SqCenterStr(SQChar f, uint32_t w, StackStrF & s)
else
{
// Calculate the insert position
const int32_t p = ((w/2) - (s.mLen/2));
const auto p = ((w/2) - (s.mLen/2));
// Insert only the fill character first
std::memset(b.Data(), f, w);
// Overwrite with the specified string
@ -287,7 +287,7 @@ static Buffer StrToLowercaseImpl(const SQChar * str, uint32_t len)
while (*str != '\0')
{
// Convert it and move to the next one
b.At(n++) = std::tolower(*(str++));
b.At(n++) = static_cast< char >(std::tolower(*(str++)));
}
// End the resulted string
b.At(n) = '\0';
@ -349,7 +349,7 @@ static Buffer StrToUppercaseImpl(const SQChar * str, uint32_t len)
while (*str != '\0')
{
// Convert it and move to the next one
b.At(n++) = std::toupper(*(str++));
b.At(n++) = static_cast< char >(std::toupper(*(str++)));
}
// End the resulted string
b.At(n) = '\0';
@ -594,7 +594,7 @@ static bool OnlyDelimiter(const SQChar * str, SQChar chr)
// ------------------------------------------------------------------------------------------------
static SQInteger SqStrExplode(HSQUIRRELVM vm)
{
const int32_t top = sq_gettop(vm);
const auto top = sq_gettop(vm);
// Was the delimiter character specified?
if (top <= 1)
{
@ -898,6 +898,68 @@ static String StrCharacterSwap(SQInteger a, SQInteger b, StackStrF & val)
return str;
}
// ------------------------------------------------------------------------------------------------
// Returns a size_t, depicting the difference between `a` and `b`. See: https://github.com/wooorm/levenshtein.c
// See <https://en.wikipedia.org/wiki/Levenshtein_distance> for more information.
SQMOD_NODISCARD static size_t Levenshtein_n(const char * a, const size_t a_length, const char * b, const size_t b_length) noexcept
{
// Shortcut optimizations / degenerate cases.
if (a == b)
{
return 0;
}
else if (a_length == 0)
{
return b_length;
}
else if (b_length == 0)
{
return a_length;
}
auto cache = reinterpret_cast< size_t * >(calloc(a_length, sizeof(size_t)));
size_t index = 0;
size_t b_index = 0;
size_t distance;
size_t b_distance;
size_t result;
char code;
// initialize the vector.
while (index < a_length)
{
cache[index] = index + 1;
index++;
}
// Loop
while (b_index < b_length)
{
code = b[b_index];
result = distance = b_index++;
index = SIZE_MAX;
while (++index < a_length)
{
b_distance = code == a[index] ? distance : distance + 1;
distance = cache[index];
cache[index] = result = distance > result
? b_distance > result
? result + 1
: b_distance
: b_distance > distance
? distance + 1
: b_distance;
}
}
free(cache);
return result;
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqLevenshtein(StackStrF & a, StackStrF & b)
{
return static_cast< SQInteger >(Levenshtein_n(a.mPtr, static_cast< size_t >(a.mLen), b.mPtr, static_cast< size_t >(b.mLen)));
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqStrToI(SQInteger base, StackStrF & s)
{
@ -940,6 +1002,7 @@ void Register_String(HSQUIRRELVM vm)
.FmtFunc(_SC("JustAlnum"), &SqJustAlphaNum)
.FmtFunc(_SC("ToInt"), &SqStrToI)
.FmtFunc(_SC("ToFloat"), &SqStrToF)
.FmtFunc(_SC("Levenshtein"), &SqLevenshtein)
.FmtFunc(_SC("AreAllSpace"), &SqAllChars< std::isspace >)
.FmtFunc(_SC("AreAllPrint"), &SqAllChars< std::isprint >)
.FmtFunc(_SC("AreAllCntrl"), &SqAllChars< std::iscntrl >)

View File

@ -1,5 +1,6 @@
add_subdirectory(ConcurrentQueue)
add_subdirectory(Fmt)
add_subdirectory(xxHash)
add_subdirectory(Squirrel)
add_subdirectory(SimpleIni)
add_subdirectory(TinyDir)

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);
@ -525,7 +557,7 @@ void Session::Impl::PrepareGet() {
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1L);
}
prepareCommon();
prepareCommon();
}
Response Session::Impl::Get() {
@ -536,7 +568,7 @@ Response Session::Impl::Get() {
void Session::Impl::PrepareHead() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 1L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
prepareCommon();
prepareCommon();
}
Response Session::Impl::Head() {
@ -587,7 +619,7 @@ Response Session::Impl::Post() {
void Session::Impl::PreparePut() {
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "PUT");
prepareCommon();
prepareCommon();
}
Response Session::Impl::Put() {
@ -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);

13
vendor/xxHash/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,13 @@
# Create the xxHash library
add_library(xxHash STATIC
xxhash.h
xxhash.c
)
# Set speciffic options
target_compile_options(xxHash PRIVATE -fvisibility=hidden)
# Includes
target_include_directories(xxHash PRIVATE ${CMAKE_CURRENT_LIST_DIR})
# Private library defines
#target_compile_definitions(xxHash PRIVATE )
# Public library defines
# target_compile_definitions(xxHash PUBLIC )

48
vendor/xxHash/LICENSE vendored Normal file
View File

@ -0,0 +1,48 @@
xxHash Library
Copyright (c) 2012-2020 Yann Collet
All rights reserved.
BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------
xxhsum command line interface
Copyright (c) 2013-2020 Yann Collet
All rights reserved.
GPL v2 License
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

43
vendor/xxHash/xxhash.c vendored Normal file
View File

@ -0,0 +1,43 @@
/*
* xxHash - Extremely Fast Hash algorithm
* Copyright (C) 2012-2020 Yann Collet
*
* BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You can contact the author at:
* - xxHash homepage: https://www.xxhash.com
* - xxHash source repository: https://github.com/Cyan4973/xxHash
*/
/*
* xxhash.c instantiates functions defined in xxhash.h
*/
#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */
#define XXH_IMPLEMENTATION /* access definitions */
#include "xxhash.h"

5360
vendor/xxHash/xxhash.h vendored Normal file

File diff suppressed because it is too large Load Diff