aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/cpr/include
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/cpr/include
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/cpr/include')
-rw-r--r--Src/external_dependencies/cpr/include/CMakeLists.txt67
-rw-r--r--Src/external_dependencies/cpr/include/cpr/accept_encoding.h36
-rw-r--r--Src/external_dependencies/cpr/include/cpr/api.h321
-rw-r--r--Src/external_dependencies/cpr/include/cpr/async.h49
-rw-r--r--Src/external_dependencies/cpr/include/cpr/auth.h33
-rw-r--r--Src/external_dependencies/cpr/include/cpr/bearer.h36
-rw-r--r--Src/external_dependencies/cpr/include/cpr/body.h54
-rw-r--r--Src/external_dependencies/cpr/include/cpr/buffer.h35
-rw-r--r--Src/external_dependencies/cpr/include/cpr/callback.h89
-rw-r--r--Src/external_dependencies/cpr/include/cpr/cert_info.h35
-rw-r--r--Src/external_dependencies/cpr/include/cpr/connect_timeout.h18
-rw-r--r--Src/external_dependencies/cpr/include/cpr/cookies.h92
-rw-r--r--Src/external_dependencies/cpr/include/cpr/cpr.h46
-rw-r--r--Src/external_dependencies/cpr/include/cpr/cprtypes.h137
-rw-r--r--Src/external_dependencies/cpr/include/cpr/curl_container.h53
-rw-r--r--Src/external_dependencies/cpr/include/cpr/curlholder.h54
-rw-r--r--Src/external_dependencies/cpr/include/cpr/curlmultiholder.h18
-rw-r--r--Src/external_dependencies/cpr/include/cpr/error.h53
-rw-r--r--Src/external_dependencies/cpr/include/cpr/file.h55
-rw-r--r--Src/external_dependencies/cpr/include/cpr/filesystem.h19
-rw-r--r--Src/external_dependencies/cpr/include/cpr/http_version.h67
-rw-r--r--Src/external_dependencies/cpr/include/cpr/interceptor.h36
-rw-r--r--Src/external_dependencies/cpr/include/cpr/interface.h34
-rw-r--r--Src/external_dependencies/cpr/include/cpr/limit_rate.h18
-rw-r--r--Src/external_dependencies/cpr/include/cpr/local_port.h23
-rw-r--r--Src/external_dependencies/cpr/include/cpr/local_port_range.h23
-rw-r--r--Src/external_dependencies/cpr/include/cpr/low_speed.h18
-rw-r--r--Src/external_dependencies/cpr/include/cpr/multipart.h45
-rw-r--r--Src/external_dependencies/cpr/include/cpr/multiperform.h119
-rw-r--r--Src/external_dependencies/cpr/include/cpr/parameters.h18
-rw-r--r--Src/external_dependencies/cpr/include/cpr/payload.h23
-rw-r--r--Src/external_dependencies/cpr/include/cpr/proxies.h23
-rw-r--r--Src/external_dependencies/cpr/include/cpr/proxyauth.h44
-rw-r--r--Src/external_dependencies/cpr/include/cpr/range.h44
-rw-r--r--Src/external_dependencies/cpr/include/cpr/redirect.h84
-rw-r--r--Src/external_dependencies/cpr/include/cpr/reserve_size.h17
-rw-r--r--Src/external_dependencies/cpr/include/cpr/resolve.h23
-rw-r--r--Src/external_dependencies/cpr/include/cpr/response.h58
-rw-r--r--Src/external_dependencies/cpr/include/cpr/session.h297
-rw-r--r--Src/external_dependencies/cpr/include/cpr/singleton.h47
-rw-r--r--Src/external_dependencies/cpr/include/cpr/ssl_ctx.h26
-rw-r--r--Src/external_dependencies/cpr/include/cpr/ssl_options.h622
-rw-r--r--Src/external_dependencies/cpr/include/cpr/status_codes.h100
-rw-r--r--Src/external_dependencies/cpr/include/cpr/threadpool.h122
-rw-r--r--Src/external_dependencies/cpr/include/cpr/timeout.h27
-rw-r--r--Src/external_dependencies/cpr/include/cpr/unix_socket.h21
-rw-r--r--Src/external_dependencies/cpr/include/cpr/user_agent.h33
-rw-r--r--Src/external_dependencies/cpr/include/cpr/util.h45
-rw-r--r--Src/external_dependencies/cpr/include/cpr/verbose.h18
49 files changed, 3375 insertions, 0 deletions
diff --git a/Src/external_dependencies/cpr/include/CMakeLists.txt b/Src/external_dependencies/cpr/include/CMakeLists.txt
new file mode 100644
index 00000000..fbc657a2
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/CMakeLists.txt
@@ -0,0 +1,67 @@
+cmake_minimum_required(VERSION 3.15)
+
+target_include_directories(cpr PUBLIC
+ $<INSTALL_INTERFACE:include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+ $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/cpr_generated_includes/>)
+
+target_sources(cpr PRIVATE
+ # Header files (useful in IDEs)
+ cpr/accept_encoding.h
+ cpr/api.h
+ cpr/async.h
+ cpr/auth.h
+ cpr/bearer.h
+ cpr/body.h
+ cpr/buffer.h
+ cpr/cert_info.h
+ cpr/cookies.h
+ cpr/cpr.h
+ cpr/cprtypes.h
+ cpr/curlholder.h
+ cpr/curlholder.h
+ cpr/error.h
+ cpr/file.h
+ cpr/limit_rate.h
+ cpr/local_port.h
+ cpr/local_port_range.h
+ cpr/multipart.h
+ cpr/parameters.h
+ cpr/payload.h
+ cpr/proxies.h
+ cpr/proxyauth.h
+ cpr/response.h
+ cpr/session.h
+ cpr/singleton.h
+ cpr/ssl_ctx.h
+ cpr/ssl_options.h
+ cpr/threadpool.h
+ cpr/timeout.h
+ cpr/unix_socket.h
+ cpr/util.h
+ cpr/verbose.h
+ cpr/interface.h
+ cpr/redirect.h
+ cpr/http_version.h
+ cpr/interceptor.h
+ cpr/filesystem.h
+ cpr/curlmultiholder.h
+ cpr/multiperform.h
+ cpr/resolve.h
+ ${PROJECT_BINARY_DIR}/cpr_generated_includes/cpr/cprver.h
+)
+
+# Filesystem
+if(CPR_USE_BOOST_FILESYSTEM)
+ find_package(Boost 1.44 REQUIRED COMPONENTS filesystem)
+ if(Boost_FOUND)
+ target_link_libraries(cpr PUBLIC Boost::filesystem)
+ endif()
+endif()
+
+if (((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND NOT CPR_USE_BOOST_FILESYSTEM)
+ target_link_libraries(cpr PUBLIC stdc++fs)
+endif()
+
+install(DIRECTORY cpr DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+install(DIRECTORY ${PROJECT_BINARY_DIR}/cpr_generated_includes/cpr DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
diff --git a/Src/external_dependencies/cpr/include/cpr/accept_encoding.h b/Src/external_dependencies/cpr/include/cpr/accept_encoding.h
new file mode 100644
index 00000000..e09ad06b
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/accept_encoding.h
@@ -0,0 +1,36 @@
+#ifndef CPR_ACCEPT_ENCODING_H
+#define CPR_ACCEPT_ENCODING_H
+
+#include <curl/curlver.h>
+#include <initializer_list>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace cpr {
+
+enum class AcceptEncodingMethods {
+ identity,
+ deflate,
+ zlib,
+ gzip,
+};
+
+static const std::map<AcceptEncodingMethods, std::string> AcceptEncodingMethodsStringMap{{AcceptEncodingMethods::identity, "identity"}, {AcceptEncodingMethods::deflate, "deflate"}, {AcceptEncodingMethods::zlib, "zlib"}, {AcceptEncodingMethods::gzip, "gzip"}};
+
+class AcceptEncoding {
+ public:
+ AcceptEncoding() = default;
+ AcceptEncoding(const std::initializer_list<AcceptEncodingMethods>& methods);
+ AcceptEncoding(const std::initializer_list<std::string>& methods);
+
+ bool empty() const noexcept;
+ const std::string getString() const;
+
+ private:
+ std::vector<std::string> methods_;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/api.h b/Src/external_dependencies/cpr/include/cpr/api.h
new file mode 100644
index 00000000..7d335237
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/api.h
@@ -0,0 +1,321 @@
+#ifndef CPR_API_H
+#define CPR_API_H
+
+#include <fstream>
+#include <functional>
+#include <future>
+#include <string>
+#include <utility>
+
+#include "cpr/async.h"
+#include "cpr/auth.h"
+#include "cpr/bearer.h"
+#include "cpr/cprtypes.h"
+#include "cpr/multipart.h"
+#include "cpr/multiperform.h"
+#include "cpr/payload.h"
+#include "cpr/response.h"
+#include "cpr/session.h"
+#include <cpr/filesystem.h>
+#include <utility>
+
+namespace cpr {
+
+using AsyncResponse = std::future<Response>;
+
+namespace priv {
+
+template <bool processed_header, typename CurrentType>
+void set_option_internal(Session& session, CurrentType&& current_option) {
+ session.SetOption(std::forward<CurrentType>(current_option));
+}
+
+template <>
+inline void set_option_internal<true, Header>(Session& session, Header&& current_option) {
+ // Header option was already provided -> Update previous header
+ session.UpdateHeader(std::forward<Header>(current_option));
+}
+
+template <bool processed_header, typename CurrentType, typename... Ts>
+void set_option_internal(Session& session, CurrentType&& current_option, Ts&&... ts) {
+ set_option_internal<processed_header, CurrentType>(session, std::forward<CurrentType>(current_option));
+
+ if (std::is_same<CurrentType, Header>::value) {
+ set_option_internal<true, Ts...>(session, std::forward<Ts>(ts)...);
+ } else {
+ set_option_internal<processed_header, Ts...>(session, std::forward<Ts>(ts)...);
+ }
+}
+
+template <typename... Ts>
+void set_option(Session& session, Ts&&... ts) {
+ set_option_internal<false, Ts...>(session, std::forward<Ts>(ts)...);
+}
+
+// Idea: https://stackoverflow.com/a/19060157
+template <typename Tuple, std::size_t... I>
+void apply_set_option_internal(Session& session, Tuple&& t, std::index_sequence<I...>) {
+ set_option(session, std::get<I>(std::forward<Tuple>(t))...);
+}
+
+// Idea: https://stackoverflow.com/a/19060157
+template <typename Tuple>
+void apply_set_option(Session& session, Tuple&& t) {
+ using Indices = std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>;
+ apply_set_option_internal(session, std::forward<Tuple>(t), Indices());
+}
+
+template <typename T>
+void setup_multiperform_internal(MultiPerform& multiperform, T&& t) {
+ std::shared_ptr<Session> session = std::make_shared<Session>();
+ apply_set_option(*session, t);
+ multiperform.AddSession(session);
+}
+
+template <typename T, typename... Ts>
+void setup_multiperform_internal(MultiPerform& multiperform, T&& t, Ts&&... ts) {
+ std::shared_ptr<Session> session = std::make_shared<Session>();
+ apply_set_option(*session, t);
+ multiperform.AddSession(session);
+ setup_multiperform_internal<Ts...>(multiperform, std::forward<Ts>(ts)...);
+}
+
+template <typename... Ts>
+void setup_multiperform(MultiPerform& multiperform, Ts&&... ts) {
+ setup_multiperform_internal<Ts...>(multiperform, std::forward<Ts>(ts)...);
+}
+
+} // namespace priv
+
+// Get methods
+template <typename... Ts>
+Response Get(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Get();
+}
+
+// Get async methods
+template <typename... Ts>
+AsyncResponse GetAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Get(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Get callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto GetCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Get(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Post methods
+template <typename... Ts>
+Response Post(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Post();
+}
+
+// Post async methods
+template <typename... Ts>
+AsyncResponse PostAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Post(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Post callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto PostCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Post(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Put methods
+template <typename... Ts>
+Response Put(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Put();
+}
+
+// Put async methods
+template <typename... Ts>
+AsyncResponse PutAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Put(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Put callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto PutCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Put(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Head methods
+template <typename... Ts>
+Response Head(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Head();
+}
+
+// Head async methods
+template <typename... Ts>
+AsyncResponse HeadAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Head(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Head callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto HeadCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Head(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Delete methods
+template <typename... Ts>
+Response Delete(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Delete();
+}
+
+// Delete async methods
+template <typename... Ts>
+AsyncResponse DeleteAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Delete(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Delete callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto DeleteCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Delete(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Options methods
+template <typename... Ts>
+Response Options(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Options();
+}
+
+// Options async methods
+template <typename... Ts>
+AsyncResponse OptionsAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Options(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Options callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto OptionsCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Options(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Patch methods
+template <typename... Ts>
+Response Patch(Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Patch();
+}
+
+// Patch async methods
+template <typename... Ts>
+AsyncResponse PatchAsync(Ts... ts) {
+ return cpr::async([](Ts... ts_inner) { return Patch(std::move(ts_inner)...); }, std::move(ts)...);
+}
+
+// Patch callback methods
+template <typename Then, typename... Ts>
+// NOLINTNEXTLINE(fuchsia-trailing-return)
+auto PatchCallback(Then then, Ts... ts) {
+ return cpr::async([](Then then_inner, Ts... ts_inner) { return then_inner(Patch(std::move(ts_inner)...)); }, std::move(then), std::move(ts)...);
+}
+
+// Download methods
+template <typename... Ts>
+Response Download(std::ofstream& file, Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Download(file);
+}
+
+// Download async method
+template <typename... Ts>
+AsyncResponse DownloadAsync(fs::path local_path, Ts... ts) {
+ return std::async(
+ std::launch::async,
+ [](fs::path local_path_, Ts... ts_) {
+#ifdef CPR_USE_BOOST_FILESYSTEM
+ std::ofstream f(local_path_.string());
+#else
+ std::ofstream f(local_path_);
+#endif
+ return Download(f, std::move(ts_)...);
+ },
+ std::move(local_path), std::move(ts)...);
+}
+
+// Download with user callback
+template <typename... Ts>
+Response Download(const WriteCallback& write, Ts&&... ts) {
+ Session session;
+ priv::set_option(session, std::forward<Ts>(ts)...);
+ return session.Download(write);
+}
+
+// Multi requests
+template <typename... Ts>
+std::vector<Response> MultiGet(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Get();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiDelete(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Delete();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiPut(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Put();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiHead(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Head();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiOptions(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Options();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiPatch(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Patch();
+}
+
+template <typename... Ts>
+std::vector<Response> MultiPost(Ts&&... ts) {
+ MultiPerform multiperform;
+ priv::setup_multiperform<Ts...>(multiperform, std::forward<Ts>(ts)...);
+ return multiperform.Post();
+}
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/async.h b/Src/external_dependencies/cpr/include/cpr/async.h
new file mode 100644
index 00000000..6e7db4c1
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/async.h
@@ -0,0 +1,49 @@
+#ifndef CPR_ASYNC_H
+#define CPR_ASYNC_H
+
+#include "singleton.h"
+#include "threadpool.h"
+
+namespace cpr {
+
+class GlobalThreadPool : public ThreadPool {
+ CPR_SINGLETON_DECL(GlobalThreadPool)
+ protected:
+ GlobalThreadPool() = default;
+
+ public:
+ ~GlobalThreadPool() override = default;
+};
+
+/**
+ * Return a future, calling future.get() will wait task done and return RetType.
+ * async(fn, args...)
+ * async(std::bind(&Class::mem_fn, &obj))
+ * async(std::mem_fn(&Class::mem_fn, &obj))
+ **/
+template <class Fn, class... Args>
+auto async(Fn&& fn, Args&&... args) {
+ return GlobalThreadPool::GetInstance()->Submit(std::forward<Fn>(fn), std::forward<Args>(args)...);
+}
+
+class async {
+ public:
+ static void startup(size_t min_threads = CPR_DEFAULT_THREAD_POOL_MIN_THREAD_NUM, size_t max_threads = CPR_DEFAULT_THREAD_POOL_MAX_THREAD_NUM, std::chrono::milliseconds max_idle_ms = CPR_DEFAULT_THREAD_POOL_MAX_IDLE_TIME) {
+ GlobalThreadPool* gtp = GlobalThreadPool::GetInstance();
+ if (gtp->IsStarted()) {
+ return;
+ }
+ gtp->SetMinThreadNum(min_threads);
+ gtp->SetMaxThreadNum(max_threads);
+ gtp->SetMaxIdleTime(max_idle_ms);
+ gtp->Start();
+ }
+
+ static void cleanup() {
+ GlobalThreadPool::ExitInstance();
+ }
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/auth.h b/Src/external_dependencies/cpr/include/cpr/auth.h
new file mode 100644
index 00000000..3354565f
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/auth.h
@@ -0,0 +1,33 @@
+#ifndef CPR_AUTH_H
+#define CPR_AUTH_H
+
+#include <string>
+
+#include <utility>
+
+namespace cpr {
+
+enum class AuthMode { BASIC, DIGEST, NTLM };
+
+class Authentication {
+ public:
+ Authentication(const std::string& username, const std::string& password, const AuthMode& auth_mode) : auth_string_{username + ":" + password}, auth_mode_{auth_mode} {}
+ Authentication(std::string&& username, std::string&& password, AuthMode&& auth_mode) : auth_string_{std::move(username) + ":" + std::move(password)}, auth_mode_{std::move(auth_mode)} {}
+ Authentication(const Authentication& other) = default;
+ Authentication(Authentication&& old) noexcept = default;
+ ~Authentication() noexcept;
+
+ Authentication& operator=(Authentication&& old) noexcept = default;
+ Authentication& operator=(const Authentication& other) = default;
+
+ const char* GetAuthString() const noexcept;
+ AuthMode GetAuthMode() const noexcept;
+
+ private:
+ std::string auth_string_;
+ AuthMode auth_mode_;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/bearer.h b/Src/external_dependencies/cpr/include/cpr/bearer.h
new file mode 100644
index 00000000..3d254e2d
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/bearer.h
@@ -0,0 +1,36 @@
+#ifndef CPR_BEARER_H
+#define CPR_BEARER_H
+
+#include <curl/curlver.h>
+#include <string>
+
+#include <utility>
+
+namespace cpr {
+
+// Only supported with libcurl >= 7.61.0.
+// As an alternative use SetHeader and add the token manually.
+#if LIBCURL_VERSION_NUM >= 0x073D00
+class Bearer {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Bearer(const std::string& token) : token_string_{token} {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Bearer(std::string&& token) : token_string_{std::move(token)} {}
+ Bearer(const Bearer& other) = default;
+ Bearer(Bearer&& old) noexcept = default;
+ virtual ~Bearer() noexcept;
+
+ Bearer& operator=(Bearer&& old) noexcept = default;
+ Bearer& operator=(const Bearer& other) = default;
+
+ virtual const char* GetToken() const noexcept;
+
+ protected:
+ std::string token_string_;
+};
+#endif
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/body.h b/Src/external_dependencies/cpr/include/cpr/body.h
new file mode 100644
index 00000000..0c191c54
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/body.h
@@ -0,0 +1,54 @@
+#ifndef CPR_BODY_H
+#define CPR_BODY_H
+
+#include <exception>
+#include <initializer_list>
+#include <string>
+#include <vector>
+#include <fstream>
+
+#include "cpr/buffer.h"
+#include "cpr/cprtypes.h"
+#include "cpr/file.h"
+
+namespace cpr {
+
+class Body : public StringHolder<Body> {
+ public:
+ Body() : StringHolder<Body>() {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Body(const std::string& body) : StringHolder<Body>(body) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Body(std::string&& body) : StringHolder<Body>(std::move(body)) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Body(std::string_view body) : StringHolder<Body>(body) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Body(const char* body) : StringHolder<Body>(body) {}
+ Body(const char* str, size_t len) : StringHolder<Body>(str, len) {}
+ Body(const std::initializer_list<std::string> args) : StringHolder<Body>(args) {}
+ Body(const Buffer& buffer) : StringHolder<Body>(reinterpret_cast<const char*>(buffer.data), static_cast<size_t>(buffer.datalen)) {}
+ Body(const File& file) {
+ std::ifstream is(file.filepath, std::ifstream::binary);
+ if (!is) {
+ throw std::invalid_argument("Can't open the file for HTTP request body!");
+ }
+
+ is.seekg(0, std::ios::end);
+ const std::streampos length = is.tellg();
+ is.seekg(0, std::ios::beg);
+ std::string buffer;
+ buffer.resize(static_cast<size_t>(length));
+ is.read(&buffer[0], length);
+ str_ = std::move(buffer);
+ }
+ Body(const Body& other) = default;
+ Body(Body&& old) noexcept = default;
+ ~Body() override = default;
+
+ Body& operator=(Body&& old) noexcept = default;
+ Body& operator=(const Body& other) = default;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/buffer.h b/Src/external_dependencies/cpr/include/cpr/buffer.h
new file mode 100644
index 00000000..17065eba
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/buffer.h
@@ -0,0 +1,35 @@
+#ifndef CPR_BUFFER_H
+#define CPR_BUFFER_H
+
+#include <string>
+
+#include <cpr/filesystem.h>
+
+namespace cpr {
+
+struct Buffer {
+ using data_t = const unsigned char*;
+
+ template <typename Iterator>
+ Buffer(Iterator begin, Iterator end, fs::path&& p_filename)
+ // Ignored here since libcurl reqires a long.
+ // There is also no way around the reinterpret_cast.
+ // NOLINTNEXTLINE(google-runtime-int, cppcoreguidelines-pro-type-reinterpret-cast)
+ : data{reinterpret_cast<data_t>(&(*begin))}, datalen{static_cast<long>(std::distance(begin, end))}, filename(std::move(p_filename)) {
+ is_random_access_iterator(begin, end);
+ static_assert(sizeof(*begin) == 1, "Only byte buffers can be used");
+ }
+
+ template <typename Iterator>
+ typename std::enable_if<std::is_same<typename std::iterator_traits<Iterator>::iterator_category, std::random_access_iterator_tag>::value>::type is_random_access_iterator(Iterator /* begin */, Iterator /* end */) {}
+
+ data_t data;
+ // Ignored here since libcurl reqires a long:
+ // NOLINTNEXTLINE(google-runtime-int)
+ long datalen;
+ const fs::path filename;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/callback.h b/Src/external_dependencies/cpr/include/cpr/callback.h
new file mode 100644
index 00000000..e54c4fb1
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/callback.h
@@ -0,0 +1,89 @@
+#ifndef CPR_CALLBACK_H
+#define CPR_CALLBACK_H
+
+#include "cprtypes.h"
+
+#include <functional>
+#include <utility>
+
+namespace cpr {
+
+class ReadCallback {
+ public:
+ ReadCallback() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ 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& buffer_size) const {
+ return callback(buffer, buffer_size, userdata);
+ }
+
+ intptr_t userdata;
+ cpr_off_t size{};
+ 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, 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);
+ }
+
+ 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, 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);
+ }
+
+ 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(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);
+ }
+
+ intptr_t userdata;
+ std::function<bool(cpr_off_t downloadTotal, cpr_off_t downloadNow, cpr_off_t uploadTotal, cpr_off_t uploadNow, intptr_t userdata)> callback;
+};
+
+class DebugCallback {
+ public:
+ enum class InfoType {
+ TEXT = 0,
+ HEADER_IN = 1,
+ HEADER_OUT = 2,
+ DATA_IN = 3,
+ DATA_OUT = 4,
+ SSL_DATA_IN = 5,
+ SSL_DATA_OUT = 6,
+ };
+ DebugCallback() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ 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);
+ }
+
+ intptr_t userdata;
+ std::function<void(InfoType type, std::string data, intptr_t userdata)> callback;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/cert_info.h b/Src/external_dependencies/cpr/include/cpr/cert_info.h
new file mode 100644
index 00000000..6c328ee7
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/cert_info.h
@@ -0,0 +1,35 @@
+#ifndef CPR_CERT_INFO_H
+#define CPR_CERT_INFO_H
+
+#include <initializer_list>
+#include <string>
+#include <vector>
+
+namespace cpr {
+
+class CertInfo {
+ private:
+ std::vector<std::string> cert_info_;
+
+ public:
+ CertInfo() = default;
+ CertInfo(const std::initializer_list<std::string>& entry) : cert_info_{entry} {};
+ ~CertInfo() noexcept = default;
+
+ using iterator = std::vector<std::string>::iterator;
+ using const_iterator = std::vector<std::string>::const_iterator;
+
+ std::string& operator[](const size_t& pos);
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+ const_iterator cbegin() const;
+ const_iterator cend() const;
+ void emplace_back(const std::string& str);
+ void push_back(const std::string& str);
+ void pop_back();
+};
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/connect_timeout.h b/Src/external_dependencies/cpr/include/cpr/connect_timeout.h
new file mode 100644
index 00000000..546e8a58
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/connect_timeout.h
@@ -0,0 +1,18 @@
+#ifndef CPR_CONNECT_TIMEOUT_H
+#define CPR_CONNECT_TIMEOUT_H
+
+#include "cpr/timeout.h"
+
+namespace cpr {
+
+class ConnectTimeout : public Timeout {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ ConnectTimeout(const std::chrono::milliseconds& duration) : Timeout{duration} {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ ConnectTimeout(const std::int32_t& milliseconds) : Timeout{milliseconds} {}
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/cookies.h b/Src/external_dependencies/cpr/include/cpr/cookies.h
new file mode 100644
index 00000000..c018ea4a
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/cookies.h
@@ -0,0 +1,92 @@
+#ifndef CPR_COOKIES_H
+#define CPR_COOKIES_H
+
+#include "cpr/curlholder.h"
+#include <chrono>
+#include <initializer_list>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace cpr {
+/**
+ * EXPIRES_STRING_SIZE is an explicitly static and const variable that could be only accessed within the same namespace and is immutable.
+ * To be used for "std::array", the expression must have a constant value, so EXPIRES_STRING_SIZE must be a const value.
+ **/
+static const std::size_t EXPIRES_STRING_SIZE = 100;
+
+class Cookie {
+ public:
+ Cookie() = default;
+ /**
+ * Some notes for the default value used by expires:
+ * std::chrono::system_clock::time_point::min() won't work on Windows due to the min, max clash there.
+ * So we fall back to std::chrono::system_clock::from_time_t(0) for the minimum value here.
+ **/
+ Cookie(const std::string& name, const std::string& value, const std::string& domain = "", bool p_isIncludingSubdomains = false, const std::string& path = "/", bool p_isHttpsOnly = false, std::chrono::system_clock::time_point expires = std::chrono::system_clock::from_time_t(0)) : name_{name}, value_{value}, domain_{domain}, includeSubdomains_{p_isIncludingSubdomains}, path_{path}, httpsOnly_{p_isHttpsOnly}, expires_{expires} {};
+ const std::string GetDomain() const;
+ bool IsIncludingSubdomains() const;
+ const std::string GetPath() const;
+ bool IsHttpsOnly() const;
+ const std::chrono::system_clock::time_point GetExpires() const;
+ const std::string GetExpiresString() const;
+ const std::string GetName() const;
+ const std::string GetValue() const;
+
+ private:
+ std::string name_;
+ std::string value_;
+ std::string domain_;
+ bool includeSubdomains_{};
+ std::string path_;
+ bool httpsOnly_{};
+ /**
+ * TODO: Update the implementation using `std::chrono::utc_clock` of C++20
+ **/
+ std::chrono::system_clock::time_point expires_{};
+};
+
+class Cookies {
+ public:
+ /**
+ * Should we URL-encode cookies when making a request.
+ * Based on RFC6265, it is recommended but not mandatory to encode cookies.
+ *
+ * -------
+ * To maximize compatibility with user agents, servers that wish to
+ * store arbitrary data in a cookie-value SHOULD encode that data, for
+ * example, using Base64 [RFC4648].
+ * -------
+ * Source: RFC6265 (https://www.ietf.org/rfc/rfc6265.txt)
+ **/
+ bool encode{true};
+
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Cookies(bool p_encode = true) : encode{p_encode} {};
+ Cookies(const std::initializer_list<cpr::Cookie>& cookies, bool p_encode = true) : encode{p_encode}, cookies_{cookies} {};
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Cookies(const cpr::Cookie& cookie, bool p_encode = true) : encode{p_encode}, cookies_{cookie} {};
+
+ cpr::Cookie& operator[](size_t pos);
+ const std::string GetEncoded(const CurlHolder& holder) const;
+
+ using iterator = std::vector<cpr::Cookie>::iterator;
+ using const_iterator = std::vector<cpr::Cookie>::const_iterator;
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+ const_iterator cbegin() const;
+ const_iterator cend() const;
+ void emplace_back(const Cookie& str);
+ void push_back(const Cookie& str);
+ void pop_back();
+
+ private:
+ std::vector<cpr::Cookie> cookies_;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/cpr.h b/Src/external_dependencies/cpr/include/cpr/cpr.h
new file mode 100644
index 00000000..fbad1726
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/cpr.h
@@ -0,0 +1,46 @@
+#ifndef CPR_CPR_H
+#define CPR_CPR_H
+
+#include "cpr/api.h"
+#include "cpr/auth.h"
+#include "cpr/bearer.h"
+#include "cpr/callback.h"
+#include "cpr/cert_info.h"
+#include "cpr/connect_timeout.h"
+#include "cpr/cookies.h"
+#include "cpr/cprtypes.h"
+#include "cpr/cprver.h"
+#include "cpr/curl_container.h"
+#include "cpr/curlholder.h"
+#include "cpr/error.h"
+#include "cpr/http_version.h"
+#include "cpr/interceptor.h"
+#include "cpr/interface.h"
+#include "cpr/limit_rate.h"
+#include "cpr/local_port.h"
+#include "cpr/local_port_range.h"
+#include "cpr/low_speed.h"
+#include "cpr/multipart.h"
+#include "cpr/multiperform.h"
+#include "cpr/parameters.h"
+#include "cpr/payload.h"
+#include "cpr/proxies.h"
+#include "cpr/proxyauth.h"
+#include "cpr/range.h"
+#include "cpr/redirect.h"
+#include "cpr/reserve_size.h"
+#include "cpr/resolve.h"
+#include "cpr/response.h"
+#include "cpr/session.h"
+#include "cpr/ssl_ctx.h"
+#include "cpr/ssl_options.h"
+#include "cpr/status_codes.h"
+#include "cpr/timeout.h"
+#include "cpr/unix_socket.h"
+#include "cpr/user_agent.h"
+#include "cpr/util.h"
+#include "cpr/verbose.h"
+
+#define CPR_LIBCURL_VERSION_NUM LIBCURL_VERSION_NUM
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/cprtypes.h b/Src/external_dependencies/cpr/include/cpr/cprtypes.h
new file mode 100644
index 00000000..4ad9e29b
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/cprtypes.h
@@ -0,0 +1,137 @@
+#ifndef CPR_CPR_TYPES_H
+#define CPR_CPR_TYPES_H
+
+#include <curl/system.h>
+#include <initializer_list>
+#include <map>
+#include <memory>
+#include <numeric>
+#include <string>
+#include <string_view>
+
+namespace cpr {
+
+/**
+ * Wrapper around "curl_off_t" to prevent applications from having to link against libcurl.
+ **/
+using cpr_off_t = curl_off_t;
+
+template <class T>
+class StringHolder {
+ public:
+ StringHolder() = default;
+ explicit StringHolder(const std::string& str) : str_(str) {}
+ explicit StringHolder(std::string&& str) : str_(std::move(str)) {}
+ explicit StringHolder(std::string_view str) : str_(str) {}
+ explicit StringHolder(const char* str) : str_(str) {}
+ StringHolder(const char* str, size_t len) : str_(str, len) {}
+ StringHolder(const std::initializer_list<std::string> args) {
+ str_ = std::accumulate(args.begin(), args.end(), str_);
+ }
+ StringHolder(const StringHolder& other) = default;
+ StringHolder(StringHolder&& old) noexcept = default;
+ virtual ~StringHolder() = default;
+
+ StringHolder& operator=(StringHolder&& old) noexcept = default;
+
+ StringHolder& operator=(const StringHolder& other) = default;
+
+ explicit operator std::string() const {
+ return str_;
+ }
+
+ T operator+(const char* rhs) const {
+ return T(str_ + rhs);
+ }
+
+ T operator+(const std::string& rhs) const {
+ return T(str_ + rhs);
+ }
+
+ T operator+(const StringHolder<T>& rhs) const {
+ return T(str_ + rhs.str_);
+ }
+
+ void operator+=(const char* rhs) {
+ str_ += rhs;
+ }
+ void operator+=(const std::string& rhs) {
+ str_ += rhs;
+ }
+ void operator+=(const StringHolder<T>& rhs) {
+ str_ += rhs;
+ }
+
+ bool operator==(const char* rhs) const {
+ return str_ == rhs;
+ }
+ bool operator==(const std::string& rhs) const {
+ return str_ == rhs;
+ }
+ bool operator==(const StringHolder<T>& rhs) const {
+ return str_ == rhs.str_;
+ }
+
+ bool operator!=(const char* rhs) const {
+ return str_.c_str() != rhs;
+ }
+ bool operator!=(const std::string& rhs) const {
+ return str_ != rhs;
+ }
+ bool operator!=(const StringHolder<T>& rhs) const {
+ return str_ != rhs.str_;
+ }
+
+ const std::string& str() {
+ return str_;
+ }
+ const std::string& str() const {
+ return str_;
+ }
+ const char* c_str() const {
+ return str_.c_str();
+ }
+ const char* data() const {
+ return str_.data();
+ }
+
+ protected:
+ std::string str_{};
+};
+
+template <class T>
+std::ostream& operator<<(std::ostream& os, const StringHolder<T>& s) {
+ os << s.str();
+ return os;
+}
+
+class Url : public StringHolder<Url> {
+ public:
+ Url() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Url(const std::string& url) : StringHolder<Url>(url) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Url(std::string&& url) : StringHolder<Url>(std::move(url)) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Url(std::string_view url) : StringHolder<Url>(url) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Url(const char* url) : StringHolder<Url>(url) {}
+ Url(const char* str, size_t len) : StringHolder<Url>(std::string(str, len)) {}
+ Url(const std::initializer_list<std::string> args) : StringHolder<Url>(args) {}
+ Url(const Url& other) = default;
+ Url(Url&& old) noexcept = default;
+ ~Url() override = default;
+
+ Url& operator=(Url&& old) noexcept = default;
+ Url& operator=(const Url& other) = default;
+};
+
+struct CaseInsensitiveCompare {
+ bool operator()(const std::string& a, const std::string& b) const noexcept;
+};
+
+using Header = std::map<std::string, std::string, CaseInsensitiveCompare>;
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/curl_container.h b/Src/external_dependencies/cpr/include/cpr/curl_container.h
new file mode 100644
index 00000000..91a013b3
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/curl_container.h
@@ -0,0 +1,53 @@
+#ifndef CURL_CONTAINER_H
+#define CURL_CONTAINER_H
+
+#include <initializer_list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cpr/curlholder.h"
+
+
+namespace cpr {
+
+struct Parameter {
+ Parameter(const std::string& p_key, const std::string& p_value) : key{p_key}, value{p_value} {}
+ Parameter(std::string&& p_key, std::string&& p_value) : key{std::move(p_key)}, value{std::move(p_value)} {}
+
+ std::string key;
+ std::string value;
+};
+
+struct Pair {
+ Pair(const std::string& p_key, const std::string& p_value) : key(p_key), value(p_value) {}
+ Pair(std::string&& p_key, std::string&& p_value) : key(std::move(p_key)), value(std::move(p_value)) {}
+
+ std::string key;
+ std::string value;
+};
+
+
+template <class T>
+class CurlContainer {
+ public:
+ /**
+ * Enables or disables URL encoding for keys and values when calling GetContent(...).
+ **/
+ bool encode = true;
+
+ CurlContainer() = default;
+ CurlContainer(const std::initializer_list<T>&);
+
+ void Add(const std::initializer_list<T>&);
+ void Add(const T&);
+
+ const std::string GetContent(const CurlHolder&) const;
+
+ protected:
+ std::vector<T> containerList_;
+};
+
+} // namespace cpr
+
+#endif //
diff --git a/Src/external_dependencies/cpr/include/cpr/curlholder.h b/Src/external_dependencies/cpr/include/cpr/curlholder.h
new file mode 100644
index 00000000..e6913b81
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/curlholder.h
@@ -0,0 +1,54 @@
+#ifndef CPR_CURL_HOLDER_H
+#define CPR_CURL_HOLDER_H
+
+#include <array>
+#include <mutex>
+#include <string>
+
+#include <curl/curl.h>
+
+namespace cpr {
+struct CurlHolder {
+ private:
+ /**
+ * Mutex for curl_easy_init().
+ * curl_easy_init() is not thread save.
+ * References:
+ * https://curl.haxx.se/libcurl/c/curl_easy_init.html
+ * https://curl.haxx.se/libcurl/c/threadsafe.html
+ **/
+
+ // Avoids initalization order problems in a static build
+ static std::mutex& curl_easy_init_mutex_() {
+ static std::mutex curl_easy_init_mutex_;
+ return curl_easy_init_mutex_;
+ }
+
+ public:
+ CURL* handle{nullptr};
+ struct curl_slist* chunk{nullptr};
+ struct curl_slist* resolveCurlList{nullptr};
+ struct curl_httppost* formpost{nullptr};
+ std::array<char, CURL_ERROR_SIZE> error{};
+
+ CurlHolder();
+ CurlHolder(const CurlHolder& other) = default;
+ CurlHolder(CurlHolder&& old) noexcept = default;
+ ~CurlHolder();
+
+ CurlHolder& operator=(CurlHolder&& old) noexcept = default;
+ CurlHolder& operator=(const CurlHolder& other) = default;
+
+ /**
+ * Uses curl_easy_escape(...) for escaping the given string.
+ **/
+ std::string urlEncode(const std::string& s) const;
+
+ /**
+ * Uses curl_easy_unescape(...) for unescaping the given string.
+ **/
+ std::string urlDecode(const std::string& s) const;
+};
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/curlmultiholder.h b/Src/external_dependencies/cpr/include/cpr/curlmultiholder.h
new file mode 100644
index 00000000..ccd504b6
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/curlmultiholder.h
@@ -0,0 +1,18 @@
+#ifndef CPR_CURLMULTIHOLDER_H
+#define CPR_CURLMULTIHOLDER_H
+
+#include <curl/curl.h>
+
+namespace cpr {
+
+class CurlMultiHolder {
+ public:
+ CurlMultiHolder();
+ ~CurlMultiHolder();
+
+ CURLM* handle{nullptr};
+};
+
+} // namespace cpr
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/error.h b/Src/external_dependencies/cpr/include/cpr/error.h
new file mode 100644
index 00000000..bb59a4cc
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/error.h
@@ -0,0 +1,53 @@
+#ifndef CPR_ERROR_H
+#define CPR_ERROR_H
+
+#include <cstdint>
+#include <string>
+
+#include "cpr/cprtypes.h"
+#include <utility>
+
+namespace cpr {
+
+enum class ErrorCode {
+ OK = 0,
+ CONNECTION_FAILURE,
+ EMPTY_RESPONSE,
+ HOST_RESOLUTION_FAILURE,
+ INTERNAL_ERROR,
+ INVALID_URL_FORMAT,
+ NETWORK_RECEIVE_ERROR,
+ NETWORK_SEND_FAILURE,
+ OPERATION_TIMEDOUT,
+ PROXY_RESOLUTION_FAILURE,
+ SSL_CONNECT_ERROR,
+ SSL_LOCAL_CERTIFICATE_ERROR,
+ SSL_REMOTE_CERTIFICATE_ERROR,
+ SSL_CACERT_ERROR,
+ GENERIC_SSL_ERROR,
+ UNSUPPORTED_PROTOCOL,
+ REQUEST_CANCELLED,
+ TOO_MANY_REDIRECTS,
+ UNKNOWN_ERROR = 1000,
+};
+
+class Error {
+ public:
+ ErrorCode code = ErrorCode::OK;
+ std::string message{};
+
+ Error() = default;
+
+ Error(const std::int32_t& curl_code, std::string&& p_error_message) : code{getErrorCodeForCurlError(curl_code)}, message(std::move(p_error_message)) {}
+
+ explicit operator bool() const {
+ return code != ErrorCode::OK;
+ }
+
+ private:
+ static ErrorCode getErrorCodeForCurlError(std::int32_t curl_code);
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/file.h b/Src/external_dependencies/cpr/include/cpr/file.h
new file mode 100644
index 00000000..5c47b638
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/file.h
@@ -0,0 +1,55 @@
+#ifndef CPR_FILE_H
+#define CPR_FILE_H
+
+#include <initializer_list>
+#include <string>
+#include <vector>
+
+#include <cpr/filesystem.h>
+
+namespace cpr {
+
+struct File {
+ explicit File(std::string&& p_filepath, const std::string& p_overrided_filename = {}) : filepath(std::move(p_filepath)), overrided_filename(p_overrided_filename) {}
+ explicit File(const std::string& p_filepath, const std::string& p_overrided_filename = {}) : filepath(p_filepath), overrided_filename(p_overrided_filename) {}
+
+ const std::string filepath;
+ const std::string overrided_filename;
+
+ bool hasOverridedFilename() const noexcept {
+ return !overrided_filename.empty();
+ };
+};
+
+class Files {
+ public:
+ Files() = default;
+ Files(const File& p_file) : files{p_file} {};
+ Files(const std::initializer_list<File>& p_files) : files{p_files} {};
+ Files(const std::initializer_list<std::string>& p_filepaths) {
+ for (const std::string& filepath : p_filepaths) {
+ files.emplace_back(File(filepath));
+ }
+ };
+ ~Files() noexcept = default;
+
+ using iterator = std::vector<File>::iterator;
+ using const_iterator = std::vector<File>::const_iterator;
+
+ iterator begin();
+ iterator end();
+ const_iterator begin() const;
+ const_iterator end() const;
+ const_iterator cbegin() const;
+ const_iterator cend() const;
+ void emplace_back(const File& file);
+ void push_back(const File& file);
+ void pop_back();
+
+ private:
+ std::vector<File> files;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/filesystem.h b/Src/external_dependencies/cpr/include/cpr/filesystem.h
new file mode 100644
index 00000000..f498f80f
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/filesystem.h
@@ -0,0 +1,19 @@
+#ifndef CPR_FILESYSTEM_H
+#define CPR_FILESYSTEM_H
+
+// Include filesystem into the namespace "fs" from either "filesystem" or "experimental/filesystem" or "boost/filesystem"
+#if __has_include(<filesystem>)
+#include <filesystem>
+namespace fs = std::filesystem;
+#elif __has_include("experimental/filesystem")
+#include <experimental/filesystem>
+namespace fs = std::experimental::filesystem;
+//cppcheck-suppress preprocessorErrorDirective
+#elif defined(CPR_USE_BOOST_FILESYSTEM) && __has_include(<boost/filesystem.hpp>)
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+#else
+#error "Failed to include <filesystem> header!"
+#endif
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/http_version.h b/Src/external_dependencies/cpr/include/cpr/http_version.h
new file mode 100644
index 00000000..45b50287
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/http_version.h
@@ -0,0 +1,67 @@
+#ifndef CPR_HTTP_VERSION_H
+#define CPR_HTTP_VERSION_H
+
+#include <curl/curlver.h>
+
+namespace cpr {
+enum class HttpVersionCode {
+ /**
+ * Let libcurl decide which version is the best.
+ **/
+ VERSION_NONE,
+ /**
+ * Enforce HTTP 1.0 requests.
+ **/
+ VERSION_1_0,
+ /**
+ * Enforce HTTP 1.1 requests.
+ **/
+ VERSION_1_1,
+#if LIBCURL_VERSION_NUM >= 0x072100 // 7.33.0
+ /**
+ * Attempt HTTP 2.0 requests.
+ * Fallback to HTTP 1.1 if negotiation fails.
+ **/
+ VERSION_2_0,
+#endif
+#if LIBCURL_VERSION_NUM >= 0x072F00 // 7.47.0
+ /**
+ * Attempt HTTP 2.0 for HTTPS requests only.
+ * Fallback to HTTP 1.1 if negotiation fails.
+ * HTTP 1.1 will be used for HTTP connections.
+ **/
+ VERSION_2_0_TLS,
+#endif
+#if LIBCURL_VERSION_NUM >= 0x073100 // 7.49.0
+ /**
+ * Start HTTP 2.0 for HTTP requests.
+ * Requires prior knowledge that the server supports HTTP 2.0.
+ * For HTTPS requests we will negotiate the protocol version in the TLS handshake.
+ **/
+ VERSION_2_0_PRIOR_KNOWLEDGE,
+#endif
+#if LIBCURL_VERSION_NUM >= 0x074200 // 7.66.0
+ /**
+ * Attempt HTTP 3.0 requests.
+ * Requires prior knowledge that the server supports HTTP 3.0 since there is no gracefully downgrade.
+ * Fallback to HTTP 1.1 if negotiation fails.
+ **/
+ VERSION_3_0
+#endif
+};
+
+class HttpVersion {
+ public:
+ /**
+ * The HTTP version that should be used by libcurl when initiating a HTTP(S) connection.
+ * Default: HttpVersionCode::VERSION_NONE
+ **/
+ HttpVersionCode code = HttpVersionCode::VERSION_NONE;
+
+ HttpVersion() = default;
+ explicit HttpVersion(HttpVersionCode _code) : code(_code) {}
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/interceptor.h b/Src/external_dependencies/cpr/include/cpr/interceptor.h
new file mode 100644
index 00000000..fdfe69c2
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/interceptor.h
@@ -0,0 +1,36 @@
+#ifndef CPR_INTERCEPTOR_H
+#define CPR_INTERCEPTOR_H
+
+#include "cpr/response.h"
+#include "cpr/session.h"
+
+namespace cpr {
+
+class Interceptor {
+ public:
+ enum class ProceedHttpMethod {
+ GET_REQUEST = 0,
+ POST_REQUEST,
+ PUT_REQUEST,
+ DELETE_REQUEST,
+ PATCH_REQUEST,
+ HEAD_REQUEST,
+ OPTIONS_REQUEST,
+ DOWNLOAD_CALLBACK_REQUEST,
+ DOWNLOAD_FILE_REQUEST,
+ };
+
+ virtual ~Interceptor() = default;
+ virtual Response intercept(Session& session) = 0;
+
+ protected:
+ static Response proceed(Session& session);
+ static Response proceed(Session& session, ProceedHttpMethod httpMethod);
+ static Response proceed(Session& session, ProceedHttpMethod httpMethod, std::ofstream& file);
+ static Response proceed(Session& session, ProceedHttpMethod httpMethod, const WriteCallback& write);
+};
+
+} // namespace cpr
+
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/interface.h b/Src/external_dependencies/cpr/include/cpr/interface.h
new file mode 100644
index 00000000..ded2fda1
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/interface.h
@@ -0,0 +1,34 @@
+#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(std::string_view iface) : StringHolder<Interface>(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 \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/limit_rate.h b/Src/external_dependencies/cpr/include/cpr/limit_rate.h
new file mode 100644
index 00000000..2b0e8a24
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/limit_rate.h
@@ -0,0 +1,18 @@
+#ifndef CPR_SPEED_LIMIT_H
+#define CPR_SPEED_LIMIT_H
+
+#include <cstdint>
+
+namespace cpr {
+
+class LimitRate {
+ public:
+ LimitRate(const std::int64_t p_downrate, const std::int64_t p_uprate) : downrate(p_downrate), uprate(p_uprate) {}
+
+ std::int64_t downrate = 0;
+ std::int64_t uprate = 0;
+};
+
+} // namespace cpr
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/local_port.h b/Src/external_dependencies/cpr/include/cpr/local_port.h
new file mode 100644
index 00000000..e853425a
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/local_port.h
@@ -0,0 +1,23 @@
+#ifndef CPR_LOCAL_PORT_H
+#define CPR_LOCAL_PORT_H
+
+#include <cstdint>
+
+namespace cpr {
+
+class LocalPort {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ LocalPort(const std::uint16_t p_localport) : localport_(p_localport) {}
+
+ operator std::uint16_t() const {
+ return localport_;
+ }
+
+ private:
+ std::uint16_t localport_ = 0;
+};
+
+} // namespace cpr
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/local_port_range.h b/Src/external_dependencies/cpr/include/cpr/local_port_range.h
new file mode 100644
index 00000000..cc2d7e25
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/local_port_range.h
@@ -0,0 +1,23 @@
+#ifndef CPR_LOCAL_PORT_RANGE_H
+#define CPR_LOCAL_PORT_RANGE_H
+
+#include <cstdint>
+
+namespace cpr {
+
+class LocalPortRange {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor)
+ LocalPortRange(const std::uint16_t p_localportrange) : localportrange_(p_localportrange) {}
+
+ operator std::uint16_t() const {
+ return localportrange_;
+ }
+
+ private:
+ std::uint16_t localportrange_ = 0;
+};
+
+} // namespace cpr
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/low_speed.h b/Src/external_dependencies/cpr/include/cpr/low_speed.h
new file mode 100644
index 00000000..ff77fd2e
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/low_speed.h
@@ -0,0 +1,18 @@
+#ifndef CPR_LOW_SPEED_H
+#define CPR_LOW_SPEED_H
+
+#include <cstdint>
+
+namespace cpr {
+
+class LowSpeed {
+ public:
+ LowSpeed(const std::int32_t p_limit, const std::int32_t p_time) : limit(p_limit), time(p_time) {}
+
+ std::int32_t limit;
+ std::int32_t time;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/multipart.h b/Src/external_dependencies/cpr/include/cpr/multipart.h
new file mode 100644
index 00000000..1c4c9dbf
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/multipart.h
@@ -0,0 +1,45 @@
+#ifndef CPR_MULTIPART_H
+#define CPR_MULTIPART_H
+
+#include <cstdint>
+#include <initializer_list>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "buffer.h"
+#include "file.h"
+
+namespace cpr {
+
+struct Part {
+ Part(const std::string& p_name, const std::string& p_value, const std::string& p_content_type = {}) : name{p_name}, value{p_value}, content_type{p_content_type}, is_file{false}, is_buffer{false} {}
+ Part(const std::string& p_name, const std::int32_t& p_value, const std::string& p_content_type = {}) : name{p_name}, value{std::to_string(p_value)}, content_type{p_content_type}, is_file{false}, is_buffer{false} {}
+ Part(const std::string& p_name, const Files& p_files, const std::string& p_content_type = {}) : name{p_name}, value{}, content_type{p_content_type}, is_file{true}, is_buffer{false}, files{p_files} {}
+ Part(const std::string& p_name, Files&& p_files, const std::string& p_content_type = {}) : name{p_name}, value{}, content_type{p_content_type}, is_file{true}, is_buffer{false}, files{std::move(p_files)} {}
+ Part(const std::string& p_name, const Buffer& buffer, const std::string& p_content_type = {}) : name{p_name}, value{buffer.filename.string()}, content_type{p_content_type}, data{buffer.data}, datalen{buffer.datalen}, is_file{false}, is_buffer{true} {}
+
+ std::string name;
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string value;
+ std::string content_type;
+ Buffer::data_t data{nullptr};
+ // Ignored here since libcurl reqires a long:
+ // NOLINTNEXTLINE(google-runtime-int)
+ long datalen{0};
+ bool is_file;
+ bool is_buffer;
+
+ Files files;
+};
+
+class Multipart {
+ public:
+ Multipart(const std::initializer_list<Part>& parts);
+
+ std::vector<Part> parts;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/multiperform.h b/Src/external_dependencies/cpr/include/cpr/multiperform.h
new file mode 100644
index 00000000..67f1637c
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/multiperform.h
@@ -0,0 +1,119 @@
+#ifndef CPR_MULTIPERFORM_H
+#define CPR_MULTIPERFORM_H
+
+#include <functional>
+#include <memory>
+#include <stdexcept>
+#include <vector>
+
+#include "cpr/curlmultiholder.h"
+#include "cpr/response.h"
+#include "cpr/session.h"
+
+namespace cpr {
+
+class MultiPerform {
+ public:
+ enum class HttpMethod {
+ UNDEFINED = 0,
+ GET_REQUEST,
+ POST_REQUEST,
+ PUT_REQUEST,
+ DELETE_REQUEST,
+ PATCH_REQUEST,
+ HEAD_REQUEST,
+ OPTIONS_REQUEST,
+ DOWNLOAD_REQUEST,
+ };
+
+ MultiPerform();
+ ~MultiPerform();
+
+ std::vector<Response> Get();
+ std::vector<Response> Delete();
+ template <typename... DownloadArgTypes>
+ std::vector<Response> Download(DownloadArgTypes... args);
+ std::vector<Response> Put();
+ std::vector<Response> Head();
+ std::vector<Response> Options();
+ std::vector<Response> Patch();
+ std::vector<Response> Post();
+
+ std::vector<Response> Perform();
+ template <typename... DownloadArgTypes>
+ std::vector<Response> PerformDownload(DownloadArgTypes... args);
+
+ void AddSession(std::shared_ptr<Session>& session, HttpMethod method = HttpMethod::UNDEFINED);
+ void RemoveSession(const std::shared_ptr<Session>& session);
+
+ private:
+ void SetHttpMethod(HttpMethod method);
+
+ void PrepareSessions();
+ template <typename CurrentDownloadArgType, typename... DownloadArgTypes>
+ void PrepareDownloadSessions(size_t sessions_index, CurrentDownloadArgType current_arg, DownloadArgTypes... args);
+ template <typename CurrentDownloadArgType>
+ void PrepareDownloadSessions(size_t sessions_index, CurrentDownloadArgType current_arg);
+ void PrepareDownloadSession(size_t sessions_index, std::ofstream& file);
+ void PrepareDownloadSession(size_t sessions_index, const WriteCallback& write);
+
+ void PrepareGet();
+ void PrepareDelete();
+ void PreparePut();
+ void PreparePatch();
+ void PrepareHead();
+ void PrepareOptions();
+ void PreparePost();
+ template <typename... DownloadArgTypes>
+ void PrepareDownload(DownloadArgTypes... args);
+
+ std::vector<Response> MakeRequest();
+ std::vector<Response> MakeDownloadRequest();
+
+ void DoMultiPerform();
+ std::vector<Response> ReadMultiInfo(std::function<Response(Session&, CURLcode)>&& complete_function);
+
+ std::vector<std::pair<std::shared_ptr<Session>, HttpMethod>> sessions_;
+ std::unique_ptr<CurlMultiHolder> multicurl_;
+ bool is_download_multi_perform{false};
+};
+
+template <typename CurrentDownloadArgType>
+void MultiPerform::PrepareDownloadSessions(size_t sessions_index, CurrentDownloadArgType current_arg) {
+ PrepareDownloadSession(sessions_index, current_arg);
+}
+
+template <typename CurrentDownloadArgType, typename... DownloadArgTypes>
+void MultiPerform::PrepareDownloadSessions(size_t sessions_index, CurrentDownloadArgType current_arg, DownloadArgTypes... args) {
+ PrepareDownloadSession(sessions_index, current_arg);
+ PrepareDownloadSessions<DownloadArgTypes...>(sessions_index + 1, args...);
+}
+
+
+template <typename... DownloadArgTypes>
+void MultiPerform::PrepareDownload(DownloadArgTypes... args) {
+ SetHttpMethod(HttpMethod::DOWNLOAD_REQUEST);
+ PrepareDownloadSessions<DownloadArgTypes...>(0, args...);
+}
+
+template <typename... DownloadArgTypes>
+std::vector<Response> MultiPerform::Download(DownloadArgTypes... args) {
+ if (sizeof...(args) != sessions_.size()) {
+ throw std::invalid_argument("Number of download arguments has to match the number of sessions added to the multiperform!");
+ }
+ PrepareDownload(args...);
+ return MakeDownloadRequest();
+}
+
+template <typename... DownloadArgTypes>
+std::vector<Response> MultiPerform::PerformDownload(DownloadArgTypes... args) {
+ if (sizeof...(args) != sessions_.size()) {
+ throw std::invalid_argument("Number of download arguments has to match the number of sessions added to the multiperform!");
+ }
+ PrepareDownloadSessions<DownloadArgTypes...>(0, args...);
+ return MakeDownloadRequest();
+}
+
+} // namespace cpr
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/parameters.h b/Src/external_dependencies/cpr/include/cpr/parameters.h
new file mode 100644
index 00000000..0e34d4d7
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/parameters.h
@@ -0,0 +1,18 @@
+#ifndef CPR_PARAMETERS_H
+#define CPR_PARAMETERS_H
+
+#include <initializer_list>
+
+#include "cpr/curl_container.h"
+
+namespace cpr {
+
+class Parameters : public CurlContainer<Parameter> {
+ public:
+ Parameters() = default;
+ Parameters(const std::initializer_list<Parameter>& parameters);
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/payload.h b/Src/external_dependencies/cpr/include/cpr/payload.h
new file mode 100644
index 00000000..686b540e
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/payload.h
@@ -0,0 +1,23 @@
+#ifndef CPR_PAYLOAD_H
+#define CPR_PAYLOAD_H
+
+#include <initializer_list>
+
+#include "cpr/curl_container.h"
+
+
+namespace cpr {
+class Payload : public CurlContainer<Pair> {
+ public:
+ template <class It>
+ Payload(const It begin, const It end) {
+ for (It pair = begin; pair != end; ++pair) {
+ Add(*pair);
+ }
+ }
+ Payload(const std::initializer_list<Pair>& pairs);
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/proxies.h b/Src/external_dependencies/cpr/include/cpr/proxies.h
new file mode 100644
index 00000000..6970442d
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/proxies.h
@@ -0,0 +1,23 @@
+#ifndef CPR_PROXIES_H
+#define CPR_PROXIES_H
+
+#include <initializer_list>
+#include <map>
+#include <string>
+
+namespace cpr {
+class Proxies {
+ public:
+ Proxies() = default;
+ Proxies(const std::initializer_list<std::pair<const std::string, std::string>>& hosts);
+ Proxies(const std::map<std::string, std::string>& hosts);
+
+ bool has(const std::string& protocol) const;
+ const std::string& operator[](const std::string& protocol);
+
+ private:
+ std::map<std::string, std::string> hosts_;
+};
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/proxyauth.h b/Src/external_dependencies/cpr/include/cpr/proxyauth.h
new file mode 100644
index 00000000..16369ff1
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/proxyauth.h
@@ -0,0 +1,44 @@
+#ifndef CPR_PROXYAUTH_H
+#define CPR_PROXYAUTH_H
+
+#include <initializer_list>
+#include <map>
+
+#include "cpr/auth.h"
+#include "cpr/util.h"
+
+namespace cpr {
+class EncodedAuthentication {
+ public:
+ EncodedAuthentication() : auth_string_{""} {}
+ EncodedAuthentication(const std::string& username, const std::string& password) : auth_string_{cpr::util::urlEncode(username) + ":" + cpr::util::urlEncode(password)} {}
+ EncodedAuthentication(std::string&& username, std::string&& password) : auth_string_{cpr::util::urlEncode(std::move(username)) + ":" + cpr::util::urlEncode(std::move(password))} {}
+ EncodedAuthentication(const EncodedAuthentication& other) = default;
+ EncodedAuthentication(EncodedAuthentication&& old) noexcept = default;
+ virtual ~EncodedAuthentication() noexcept;
+
+ EncodedAuthentication& operator=(EncodedAuthentication&& old) noexcept = default;
+ EncodedAuthentication& operator=(const EncodedAuthentication& other) = default;
+
+ const char* GetAuthString() const noexcept;
+
+ protected:
+ std::string auth_string_;
+};
+
+class ProxyAuthentication {
+ public:
+ ProxyAuthentication() = default;
+ ProxyAuthentication(const std::initializer_list<std::pair<const std::string, EncodedAuthentication>>& auths) : proxyAuth_{auths} {}
+ ProxyAuthentication(const std::map<std::string, EncodedAuthentication>& auths) : proxyAuth_{auths} {}
+
+ bool has(const std::string& protocol) const;
+ const char* operator[](const std::string& protocol);
+
+ private:
+ std::map<std::string, EncodedAuthentication> proxyAuth_;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/range.h b/Src/external_dependencies/cpr/include/cpr/range.h
new file mode 100644
index 00000000..2c5a145d
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/range.h
@@ -0,0 +1,44 @@
+#ifndef CPR_RANGE_H
+#define CPR_RANGE_H
+
+#include <cstdint>
+#include <optional>
+
+namespace cpr {
+
+class Range {
+ public:
+ Range(const std::optional<std::int64_t> p_resume_from = std::nullopt, const std::optional<std::int64_t> p_finish_at = std::nullopt) {
+ resume_from = p_resume_from.value_or(0);
+ finish_at = p_finish_at.value_or(-1);
+ }
+
+ std::int64_t resume_from;
+ std::int64_t finish_at;
+
+ const std::string str() const {
+ std::string from_str = (resume_from < 0U) ? "" : std::to_string(resume_from);
+ std::string to_str = (finish_at < 0U) ? "" : std::to_string(finish_at);
+ return from_str + "-" + to_str;
+ }
+};
+
+class MultiRange {
+ public:
+ MultiRange(std::initializer_list<Range> rs) : ranges{rs} {}
+
+ const std::string str() const {
+ std::string multi_range_string{};
+ for (Range range : ranges) {
+ multi_range_string += ((multi_range_string.empty()) ? "" : ", ") + range.str();
+ }
+ return multi_range_string;
+ }
+
+ private:
+ std::vector<Range> ranges;
+}; // namespace cpr
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/redirect.h b/Src/external_dependencies/cpr/include/cpr/redirect.h
new file mode 100644
index 00000000..32b4372c
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/redirect.h
@@ -0,0 +1,84 @@
+#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 (google-runtime-int)
+ long maximum{50L};
+ /**
+ * Follow 3xx redirects.
+ * Default: true
+ * https://curl.se/libcurl/c/CURLOPT_FOLLOWLOCATION.html
+ **/
+ bool follow{true};
+ /**
+ * Continue to send authentication (user+password) credentials when following locations, even when hostname changed.
+ * Default: false
+ * https://curl.se/libcurl/c/CURLOPT_UNRESTRICTED_AUTH.html
+ **/
+ bool cont_send_cred{false};
+ /**
+ * 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, bool p_cont_send_cred, PostRedirectFlags p_post_flags) : maximum(p_maximum), follow(p_follow), cont_send_cred(p_cont_send_cred), 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){};
+ Redirect(bool p_follow, bool p_cont_send_cred) : follow(p_follow), cont_send_cred(p_cont_send_cred){};
+ explicit Redirect(PostRedirectFlags p_post_flags) : post_flags(p_post_flags){};
+};
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/reserve_size.h b/Src/external_dependencies/cpr/include/cpr/reserve_size.h
new file mode 100644
index 00000000..5eae4c80
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/reserve_size.h
@@ -0,0 +1,17 @@
+#ifndef CPR_RESERVE_SIZE_H
+#define CPR_RESERVE_SIZE_H
+
+#include <cstdint>
+
+namespace cpr {
+
+class ReserveSize {
+ public:
+ ReserveSize(const size_t _size) : size(_size) {}
+
+ size_t size = 0;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/resolve.h b/Src/external_dependencies/cpr/include/cpr/resolve.h
new file mode 100644
index 00000000..86a7c892
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/resolve.h
@@ -0,0 +1,23 @@
+#ifndef CPR_RESOLVE_H
+#define CPR_RESOLVE_H
+
+#include <string>
+#include <set>
+
+namespace cpr {
+ class Resolve {
+ public:
+ std::string host;
+ std::string addr;
+ std::set<uint16_t> ports;
+
+ Resolve(const std::string& host_param, const std::string& addr_param, const std::set<uint16_t>& ports_param = std::set<uint16_t>{80U, 443U}): host(host_param), addr(addr_param), ports(ports_param) {
+ if (this->ports.empty()) {
+ this->ports.insert(80U);
+ this->ports.insert(443U);
+ }
+ }
+ };
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/response.h b/Src/external_dependencies/cpr/include/cpr/response.h
new file mode 100644
index 00000000..5c296daa
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/response.h
@@ -0,0 +1,58 @@
+#ifndef CPR_RESPONSE_H
+#define CPR_RESPONSE_H
+
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cpr/cert_info.h"
+#include "cpr/cookies.h"
+#include "cpr/cprtypes.h"
+#include "cpr/error.h"
+#include "cpr/ssl_options.h"
+#include "cpr/util.h"
+
+namespace cpr {
+
+class MultiPerform;
+
+class Response {
+ private:
+ friend MultiPerform;
+ std::shared_ptr<CurlHolder> curl_{nullptr};
+
+ public:
+ // Ignored here since libcurl uses a long for this.
+ // NOLINTNEXTLINE(google-runtime-int)
+ long status_code{};
+ std::string text{};
+ Header header{};
+ Url url{};
+ double elapsed{};
+ Cookies cookies{};
+ Error error{};
+ std::string raw_header{};
+ std::string status_line{};
+ std::string reason{};
+ cpr_off_t uploaded_bytes{};
+ cpr_off_t downloaded_bytes{};
+ // Ignored here since libcurl uses a long for this.
+ // NOLINTNEXTLINE(google-runtime-int)
+ long redirect_count{};
+
+ Response() = default;
+ Response(std::shared_ptr<CurlHolder> curl, std::string&& p_text, std::string&& p_header_string, Cookies&& p_cookies, Error&& p_error);
+ std::vector<CertInfo> GetCertInfos();
+ Response(const Response& other) = default;
+ Response(Response&& old) noexcept = default;
+ ~Response() noexcept = default;
+
+ Response& operator=(Response&& old) noexcept = default;
+ Response& operator=(const Response& other) = default;
+};
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/session.h b/Src/external_dependencies/cpr/include/cpr/session.h
new file mode 100644
index 00000000..7b500926
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/session.h
@@ -0,0 +1,297 @@
+#ifndef CPR_SESSION_H
+#define CPR_SESSION_H
+
+#include <cstdint>
+#include <fstream>
+#include <future>
+#include <memory>
+#include <queue>
+
+#include "cpr/accept_encoding.h"
+#include "cpr/auth.h"
+#include "cpr/bearer.h"
+#include "cpr/body.h"
+#include "cpr/callback.h"
+#include "cpr/connect_timeout.h"
+#include "cpr/cookies.h"
+#include "cpr/cprtypes.h"
+#include "cpr/curlholder.h"
+#include "cpr/http_version.h"
+#include "cpr/interface.h"
+#include "cpr/limit_rate.h"
+#include "cpr/local_port.h"
+#include "cpr/local_port_range.h"
+#include "cpr/low_speed.h"
+#include "cpr/multipart.h"
+#include "cpr/parameters.h"
+#include "cpr/payload.h"
+#include "cpr/proxies.h"
+#include "cpr/proxyauth.h"
+#include "cpr/range.h"
+#include "cpr/redirect.h"
+#include "cpr/reserve_size.h"
+#include "cpr/resolve.h"
+#include "cpr/response.h"
+#include "cpr/ssl_options.h"
+#include "cpr/timeout.h"
+#include "cpr/unix_socket.h"
+#include "cpr/user_agent.h"
+#include "cpr/verbose.h"
+
+namespace cpr {
+
+using AsyncResponse = std::future<Response>;
+
+class Interceptor;
+class MultiPerform;
+
+class Session : public std::enable_shared_from_this<Session> {
+ public:
+ Session();
+ Session(const Session& other) = delete;
+ Session(Session&& old) = default;
+
+ ~Session() = default;
+
+ Session& operator=(Session&& old) noexcept = default;
+ Session& operator=(const Session& other) = delete;
+
+ void SetUrl(const Url& url);
+ void SetParameters(const Parameters& parameters);
+ void SetParameters(Parameters&& parameters);
+ void SetHeader(const Header& header);
+ void UpdateHeader(const Header& header);
+ void SetTimeout(const Timeout& timeout);
+ void SetConnectTimeout(const ConnectTimeout& timeout);
+ void SetAuth(const Authentication& auth);
+// Only supported with libcurl >= 7.61.0.
+// As an alternative use SetHeader and add the token manually.
+#if LIBCURL_VERSION_NUM >= 0x073D00
+ void SetBearer(const Bearer& token);
+#endif
+ void SetUserAgent(const UserAgent& ua);
+ void SetPayload(Payload&& payload);
+ void SetPayload(const Payload& payload);
+ void SetProxies(Proxies&& proxies);
+ void SetProxies(const Proxies& proxies);
+ void SetProxyAuth(ProxyAuthentication&& proxy_auth);
+ void SetProxyAuth(const ProxyAuthentication& proxy_auth);
+ void SetMultipart(Multipart&& multipart);
+ void SetMultipart(const Multipart& multipart);
+ void SetRedirect(const Redirect& redirect);
+ void SetCookies(const Cookies& cookies);
+ void SetBody(Body&& body);
+ void SetBody(const Body& body);
+ void SetLowSpeed(const LowSpeed& low_speed);
+ void SetVerifySsl(const VerifySsl& verify);
+ void SetUnixSocket(const UnixSocket& unix_socket);
+ void SetSslOptions(const SslOptions& options);
+ void SetReadCallback(const ReadCallback& read);
+ void SetHeaderCallback(const HeaderCallback& header);
+ void SetWriteCallback(const WriteCallback& write);
+ void SetProgressCallback(const ProgressCallback& progress);
+ void SetDebugCallback(const DebugCallback& debug);
+ void SetVerbose(const Verbose& verbose);
+ void SetInterface(const Interface& iface);
+ void SetLocalPort(const LocalPort& local_port);
+ void SetLocalPortRange(const LocalPortRange& local_port_range);
+ void SetHttpVersion(const HttpVersion& version);
+ void SetRange(const Range& range);
+ void SetResolve(const Resolve& resolve);
+ void SetResolves(const std::vector<Resolve>& resolves);
+ void SetMultiRange(const MultiRange& multi_range);
+ void SetReserveSize(const ReserveSize& reserve_size);
+ void SetAcceptEncoding(const AcceptEncoding& accept_encoding);
+ void SetAcceptEncoding(AcceptEncoding&& accept_encoding);
+ void SetLimitRate(const LimitRate& limit_rate);
+
+ // Used in templated functions
+ void SetOption(const Url& url);
+ void SetOption(const Parameters& parameters);
+ void SetOption(Parameters&& parameters);
+ void SetOption(const Header& header);
+ void SetOption(const Timeout& timeout);
+ void SetOption(const ConnectTimeout& timeout);
+ void SetOption(const Authentication& auth);
+// Only supported with libcurl >= 7.61.0.
+// As an alternative use SetHeader and add the token manually.
+#if LIBCURL_VERSION_NUM >= 0x073D00
+ void SetOption(const Bearer& auth);
+#endif
+ void SetOption(const UserAgent& ua);
+ void SetOption(Payload&& payload);
+ void SetOption(const Payload& payload);
+ void SetOption(const LimitRate& limit_rate);
+ void SetOption(Proxies&& proxies);
+ void SetOption(const Proxies& proxies);
+ void SetOption(ProxyAuthentication&& proxy_auth);
+ void SetOption(const ProxyAuthentication& proxy_auth);
+ void SetOption(Multipart&& multipart);
+ void SetOption(const Multipart& multipart);
+ void SetOption(const Redirect& redirect);
+ void SetOption(const Cookies& cookies);
+ void SetOption(Body&& body);
+ void SetOption(const Body& body);
+ void SetOption(const ReadCallback& read);
+ void SetOption(const HeaderCallback& header);
+ void SetOption(const WriteCallback& write);
+ void SetOption(const ProgressCallback& progress);
+ void SetOption(const DebugCallback& debug);
+ void SetOption(const LowSpeed& low_speed);
+ void SetOption(const VerifySsl& verify);
+ void SetOption(const Verbose& verbose);
+ void SetOption(const UnixSocket& unix_socket);
+ void SetOption(const SslOptions& options);
+ void SetOption(const Interface& iface);
+ void SetOption(const LocalPort& local_port);
+ void SetOption(const LocalPortRange& local_port_range);
+ void SetOption(const HttpVersion& version);
+ void SetOption(const Range& range);
+ void SetOption(const MultiRange& multi_range);
+ void SetOption(const ReserveSize& reserve_size);
+ void SetOption(const AcceptEncoding& accept_encoding);
+ void SetOption(AcceptEncoding&& accept_encoding);
+ void SetOption(const Resolve& resolve);
+ void SetOption(const std::vector<Resolve>& resolves);
+
+ cpr_off_t GetDownloadFileLength();
+ /**
+ * Attempt to preallocate enough memory for specified number of characters in the response string.
+ * Pass 0 to disable this behavior and let the response string be allocated dynamically on demand.
+ *
+ * Example:
+ * cpr::Session session;
+ * session.SetUrl(cpr::Url{"http://xxx/file"});
+ * session.ResponseStringReserve(1024 * 512); // Reserve space for at least 1024 * 512 characters
+ * cpr::Response r = session.Get();
+ **/
+ void ResponseStringReserve(size_t size);
+ Response Delete();
+ Response Download(const WriteCallback& write);
+ Response Download(std::ofstream& file);
+ Response Get();
+ Response Head();
+ Response Options();
+ Response Patch();
+ Response Post();
+ Response Put();
+
+ AsyncResponse GetAsync();
+ AsyncResponse DeleteAsync();
+ AsyncResponse DownloadAsync(const WriteCallback& write);
+ AsyncResponse DownloadAsync(std::ofstream& file);
+ AsyncResponse HeadAsync();
+ AsyncResponse OptionsAsync();
+ AsyncResponse PatchAsync();
+ AsyncResponse PostAsync();
+ AsyncResponse PutAsync();
+
+ template <typename Then>
+ auto GetCallback(Then then);
+ template <typename Then>
+ auto PostCallback(Then then);
+ template <typename Then>
+ auto PutCallback(Then then);
+ template <typename Then>
+ auto HeadCallback(Then then);
+ template <typename Then>
+ auto DeleteCallback(Then then);
+ template <typename Then>
+ auto OptionsCallback(Then then);
+ template <typename Then>
+ auto PatchCallback(Then then);
+
+ std::shared_ptr<CurlHolder> GetCurlHolder();
+ std::string GetFullRequestUrl();
+
+ void PrepareDelete();
+ void PrepareGet();
+ void PrepareHead();
+ void PrepareOptions();
+ void PreparePatch();
+ void PreparePost();
+ void PreparePut();
+ void PrepareDownload(const WriteCallback& write);
+ void PrepareDownload(std::ofstream& file);
+ Response Complete(CURLcode curl_error);
+ Response CompleteDownload(CURLcode curl_error);
+
+ void AddInterceptor(const std::shared_ptr<Interceptor>& pinterceptor);
+
+ private:
+ // Interceptors should be able to call the private procceed() function
+ friend Interceptor;
+ friend MultiPerform;
+
+ bool hasBodyOrPayload_{false};
+ bool chunkedTransferEncoding_{false};
+ std::shared_ptr<CurlHolder> curl_;
+ Url url_;
+ Parameters parameters_;
+ Proxies proxies_;
+ ProxyAuthentication proxyAuth_;
+ Header header_;
+ AcceptEncoding acceptEncoding_;
+ /**
+ * Will be set by the read callback.
+ * Ensures that the "Transfer-Encoding" is set to "chunked", if not overriden in header_.
+ **/
+ ReadCallback readcb_;
+ HeaderCallback headercb_;
+ WriteCallback writecb_;
+ ProgressCallback progresscb_;
+ DebugCallback debugcb_;
+ size_t response_string_reserve_size_{0};
+ std::string response_string_;
+ std::string header_string_;
+ std::queue<std::shared_ptr<Interceptor>> interceptors_;
+ bool isUsedInMultiPerform{false};
+
+ Response makeDownloadRequest();
+ Response makeRequest();
+ Response proceed();
+ void prepareCommon();
+ void prepareCommonDownload();
+ void SetHeaderInternal();
+ std::shared_ptr<Session> GetSharedPtrFromThis();
+ CURLcode DoEasyPerform();
+};
+
+template <typename Then>
+auto Session::GetCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Get()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::PostCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Post()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::PutCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Put()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::HeadCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Head()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::DeleteCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Delete()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::OptionsCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Options()); }, std::move(then));
+}
+
+template <typename Then>
+auto Session::PatchCallback(Then then) {
+ return async([shared_this = GetSharedPtrFromThis()](Then then_inner) { return then_inner(shared_this->Patch()); }, std::move(then));
+}
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/singleton.h b/Src/external_dependencies/cpr/include/cpr/singleton.h
new file mode 100644
index 00000000..e2ea13bb
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/singleton.h
@@ -0,0 +1,47 @@
+#ifndef CPR_SINGLETON_H
+#define CPR_SINGLETON_H
+
+#include <mutex>
+
+#ifndef CPR_DISABLE_COPY
+#define CPR_DISABLE_COPY(Class) \
+ Class(const Class&) = delete; \
+ Class& operator=(const Class&) = delete;
+#endif
+
+#ifndef CPR_SINGLETON_DECL
+#define CPR_SINGLETON_DECL(Class) \
+ public: \
+ static Class* GetInstance(); \
+ static void ExitInstance(); \
+ private: \
+ CPR_DISABLE_COPY(Class) \
+ static Class* s_pInstance; \
+ static std::mutex s_mutex;
+#endif
+
+#ifndef CPR_SINGLETON_IMPL
+#define CPR_SINGLETON_IMPL(Class) \
+ Class* Class::s_pInstance = nullptr; \
+ std::mutex Class::s_mutex; \
+ Class* Class::GetInstance() { \
+ if (s_pInstance == nullptr) { \
+ s_mutex.lock(); \
+ if (s_pInstance == nullptr) { \
+ s_pInstance = new Class; \
+ } \
+ s_mutex.unlock(); \
+ } \
+ return s_pInstance; \
+ } \
+ void Class::ExitInstance() { \
+ s_mutex.lock(); \
+ if (s_pInstance) { \
+ delete s_pInstance; \
+ s_pInstance = nullptr; \
+ } \
+ s_mutex.unlock(); \
+ }
+#endif
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/ssl_ctx.h b/Src/external_dependencies/cpr/include/cpr/ssl_ctx.h
new file mode 100644
index 00000000..d495fb2b
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/ssl_ctx.h
@@ -0,0 +1,26 @@
+#ifndef CPR_SSL_CTX_H
+#define CPR_SSL_CTX_H
+
+#include "cpr/ssl_options.h"
+#include <curl/curl.h>
+
+#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
+
+namespace cpr {
+
+/**
+ * This callback function loads a CA certificate from raw_cert_buf and gets called by libcurl
+ * just before the initialization of an SSL connection.
+ * The raw_cert_buf argument is set with the CURLOPT_SSL_CTX_DATA option and has to be a nul
+ * terminated buffer.
+ *
+ * Sources: https://curl.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html
+ * https://curl.se/libcurl/c/CURLOPT_SSL_CTX_DATA.html
+ */
+CURLcode sslctx_function_load_ca_cert_from_buffer(CURL* curl, void* sslctx, void* raw_cert_buf);
+
+} // Namespace cpr
+
+#endif
+
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/ssl_options.h b/Src/external_dependencies/cpr/include/cpr/ssl_options.h
new file mode 100644
index 00000000..7a1784ef
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/ssl_options.h
@@ -0,0 +1,622 @@
+#ifndef CPR_SSLOPTIONS_H
+#define CPR_SSLOPTIONS_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cpr/filesystem.h>
+#include <curl/curl.h>
+
+#include "cpr/util.h"
+#include <utility>
+
+#define __LIBCURL_VERSION_GTE(major, minor) ((LIBCURL_VERSION_MAJOR > (major)) || ((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR >= (minor))))
+#define __LIBCURL_VERSION_LT(major, minor) ((LIBCURL_VERSION_MAJOR < (major)) || ((LIBCURL_VERSION_MAJOR == (major)) && (LIBCURL_VERSION_MINOR < (minor))))
+
+#ifndef SUPPORT_ALPN
+#define SUPPORT_ALPN __LIBCURL_VERSION_GTE(7, 36)
+#endif
+#ifndef SUPPORT_NPN
+#define SUPPORT_NPN __LIBCURL_VERSION_GTE(7, 36)
+#endif
+
+#ifndef SUPPORT_SSLv2
+#define SUPPORT_SSLv2 __LIBCURL_VERSION_LT(7, 19)
+#endif
+#ifndef SUPPORT_SSLv3
+#define SUPPORT_SSLv3 __LIBCURL_VERSION_LT(7, 39)
+#endif
+#ifndef SUPPORT_TLSv1_0
+#define SUPPORT_TLSv1_0 __LIBCURL_VERSION_GTE(7, 34)
+#endif
+#ifndef SUPPORT_TLSv1_1
+#define SUPPORT_TLSv1_1 __LIBCURL_VERSION_GTE(7, 34)
+#endif
+#ifndef SUPPORT_TLSv1_2
+#define SUPPORT_TLSv1_2 __LIBCURL_VERSION_GTE(7, 34)
+#endif
+#ifndef SUPPORT_TLSv1_3
+#define SUPPORT_TLSv1_3 __LIBCURL_VERSION_GTE(7, 52)
+#endif
+#ifndef SUPPORT_MAX_TLS_VERSION
+#define SUPPORT_MAX_TLS_VERSION __LIBCURL_VERSION_GTE(7, 54)
+#endif
+#ifndef SUPPORT_MAX_TLSv1_1
+#define SUPPORT_MAX_TLSv1_1 __LIBCURL_VERSION_GTE(7, 54)
+#endif
+#ifndef SUPPORT_MAX_TLSv1_2
+#define SUPPORT_MAX_TLSv1_2 __LIBCURL_VERSION_GTE(7, 54)
+#endif
+#ifndef SUPPORT_MAX_TLSv1_3
+#define SUPPORT_MAX_TLSv1_3 __LIBCURL_VERSION_GTE(7, 54)
+#endif
+#ifndef SUPPORT_TLSv13_CIPHERS
+#define SUPPORT_TLSv13_CIPHERS __LIBCURL_VERSION_GTE(7, 61)
+#endif
+#ifndef SUPPORT_SESSIONID_CACHE
+#define SUPPORT_SESSIONID_CACHE __LIBCURL_VERSION_GTE(7, 16)
+#endif
+#ifndef SUPPORT_SSL_FALSESTART
+#define SUPPORT_SSL_FALSESTART __LIBCURL_VERSION_GTE(7, 42)
+#endif
+#ifndef SUPPORT_SSL_NO_REVOKE
+#define SUPPORT_SSL_NO_REVOKE __LIBCURL_VERSION_GTE(7, 44)
+#endif
+#ifndef SUPPORT_CURLOPT_SSLKEY_BLOB
+#define SUPPORT_CURLOPT_SSLKEY_BLOB __LIBCURL_VERSION_GTE(7, 71)
+#endif
+#ifndef SUPPORT_CURLOPT_SSL_CTX_FUNCTION
+#define SUPPORT_CURLOPT_SSL_CTX_FUNCTION __LIBCURL_VERSION_GTE(7, 11)
+#endif
+
+namespace cpr {
+
+class VerifySsl {
+ public:
+ VerifySsl() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ VerifySsl(bool p_verify) : verify(p_verify) {}
+
+ explicit operator bool() const {
+ return verify;
+ }
+
+ bool verify = true;
+};
+
+namespace ssl {
+
+// set SSL client certificate
+class CertFile {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ CertFile(fs::path&& p_filename) : filename(std::move(p_filename)) {}
+
+ virtual ~CertFile() = default;
+
+ const fs::path filename;
+
+ virtual const char* GetCertType() const {
+ return "PEM";
+ }
+};
+
+using PemCert = CertFile;
+
+class DerCert : public CertFile {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ DerCert(fs::path&& p_filename) : CertFile(std::move(p_filename)) {}
+
+ virtual ~DerCert() = default;
+
+ const char* GetCertType() const override {
+ return "DER";
+ }
+};
+
+// specify private keyfile for TLS and SSL client cert
+class KeyFile {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ KeyFile(fs::path&& p_filename) : filename(std::move(p_filename)) {}
+
+ template <typename FileType, typename PassType>
+ KeyFile(FileType&& p_filename, PassType p_password) : filename(std::forward<FileType>(p_filename)), password(std::move(p_password)) {}
+
+ virtual ~KeyFile() {
+ util::secureStringClear(password);
+ }
+
+ fs::path filename;
+ std::string password;
+
+ virtual const char* GetKeyType() const {
+ return "PEM";
+ }
+};
+
+#if SUPPORT_CURLOPT_SSLKEY_BLOB
+class KeyBlob {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ KeyBlob(std::string&& p_blob) : blob(std::move(p_blob)) {}
+
+ template <typename BlobType, typename PassType>
+ KeyBlob(BlobType&& p_blob, PassType p_password) : blob(std::forward<BlobType>(p_blob)), password(std::move(p_password)) {}
+
+ virtual ~KeyBlob() {
+ util::secureStringClear(password);
+ }
+
+ std::string blob;
+ std::string password;
+
+ virtual const char* GetKeyType() const {
+ return "PEM";
+ }
+};
+#endif
+
+using PemKey = KeyFile;
+
+class DerKey : public KeyFile {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ DerKey(fs::path&& p_filename) : KeyFile(std::move(p_filename)) {}
+
+ template <typename FileType, typename PassType>
+ DerKey(FileType&& p_filename, PassType p_password) : KeyFile(std::forward<FileType>(p_filename), std::move(p_password)) {}
+
+ virtual ~DerKey() = default;
+
+ const char* GetKeyType() const override {
+ return "DER";
+ }
+};
+
+class PinnedPublicKey {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ PinnedPublicKey(std::string&& p_pinned_public_key) : pinned_public_key(std::move(p_pinned_public_key)) {}
+
+ const std::string pinned_public_key;
+};
+
+#if SUPPORT_ALPN
+// This option enables/disables ALPN in the SSL handshake (if the SSL backend libcurl is built to
+// use supports it), which can be used to negotiate http2.
+class ALPN {
+ public:
+ ALPN() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ ALPN(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = true;
+};
+#endif // SUPPORT_ALPN
+
+#if SUPPORT_NPN
+// This option enables/disables NPN in the SSL handshake (if the SSL backend libcurl is built to
+// use supports it), which can be used to negotiate http2.
+class NPN {
+ public:
+ NPN() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ NPN(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = true;
+};
+#endif // SUPPORT_NPN
+
+// This option determines whether libcurl verifies that the server cert is for the server it is
+// known as.
+class VerifyHost {
+ public:
+ VerifyHost() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ VerifyHost(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = true;
+};
+
+// This option determines whether libcurl verifies the authenticity of the peer's certificate.
+class VerifyPeer {
+ public:
+ VerifyPeer() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ VerifyPeer(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = true;
+};
+
+// This option determines whether libcurl verifies the status of the server cert using the
+// "Certificate Status Request" TLS extension (aka. OCSP stapling).
+class VerifyStatus {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ VerifyStatus(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = false;
+};
+
+// TLS v1.0 or later
+struct TLSv1 {};
+#if SUPPORT_SSLv2
+// SSL v2 (but not SSLv3)
+struct SSLv2 {};
+#endif
+#if SUPPORT_SSLv3
+// SSL v3 (but not SSLv2)
+struct SSLv3 {};
+#endif
+#if SUPPORT_TLSv1_0
+// TLS v1.0 or later (Added in 7.34.0)
+struct TLSv1_0 {};
+#endif
+#if SUPPORT_TLSv1_1
+// TLS v1.1 or later (Added in 7.34.0)
+struct TLSv1_1 {};
+#endif
+#if SUPPORT_TLSv1_2
+// TLS v1.2 or later (Added in 7.34.0)
+struct TLSv1_2 {};
+#endif
+#if SUPPORT_TLSv1_3
+// TLS v1.3 or later (Added in 7.52.0)
+struct TLSv1_3 {};
+#endif
+#if SUPPORT_MAX_TLS_VERSION
+// The flag defines the maximum supported TLS version by libcurl, or the default value from the SSL
+// library is used.
+struct MaxTLSVersion {};
+#endif
+#if SUPPORT_MAX_TLSv1_0
+// The flag defines maximum supported TLS version as TLSv1.0. (Added in 7.54.0)
+struct MaxTLSv1_0 {};
+#endif
+#if SUPPORT_MAX_TLSv1_1
+// The flag defines maximum supported TLS version as TLSv1.1. (Added in 7.54.0)
+struct MaxTLSv1_1 {};
+#endif
+#if SUPPORT_MAX_TLSv1_2
+// The flag defines maximum supported TLS version as TLSv1.2. (Added in 7.54.0)
+struct MaxTLSv1_2 {};
+#endif
+#if SUPPORT_MAX_TLSv1_3
+// The flag defines maximum supported TLS version as TLSv1.3. (Added in 7.54.0)
+struct MaxTLSv1_3 {};
+#endif
+
+// path to Certificate Authority (CA) bundle
+class CaInfo {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ CaInfo(fs::path&& p_filename) : filename(std::move(p_filename)) {}
+
+ fs::path filename;
+};
+
+// specify directory holding CA certificates
+class CaPath {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ CaPath(fs::path&& p_filename) : filename(std::move(p_filename)) {}
+
+ fs::path filename;
+};
+
+#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
+class CaBuffer {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ CaBuffer(std::string&& p_buffer) : buffer(std::move(p_buffer)) {}
+
+ const std::string buffer;
+};
+#endif
+
+// specify a Certificate Revocation List file
+class Crl {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Crl(fs::path&& p_filename) : filename(std::move(p_filename)) {}
+
+ fs::path filename;
+};
+
+// specify ciphers to use for TLS
+class Ciphers {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {}
+
+ std::string ciphers;
+};
+
+#if SUPPORT_TLSv13_CIPHERS
+// specify ciphers suites to use for TLS 1.3
+class TLS13_Ciphers {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ TLS13_Ciphers(std::string&& p_ciphers) : ciphers(std::move(p_ciphers)) {}
+
+ std::string ciphers;
+};
+#endif
+
+#if SUPPORT_SESSIONID_CACHE
+// enable/disable use of the SSL session-ID cache
+class SessionIdCache {
+ public:
+ SessionIdCache() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ SessionIdCache(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = true;
+};
+#endif
+
+#if SUPPORT_SSL_FALSESTART
+class SslFastStart {
+ public:
+ SslFastStart() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ SslFastStart(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = false;
+};
+#endif
+
+class NoRevoke {
+ public:
+ NoRevoke() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ NoRevoke(bool p_enabled) : enabled(p_enabled) {}
+
+ explicit operator bool() const {
+ return enabled;
+ }
+
+ bool enabled = false;
+};
+
+} // namespace ssl
+
+struct SslOptions {
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string cert_file;
+ std::string cert_type;
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string key_file;
+#if SUPPORT_CURLOPT_SSLKEY_BLOB
+ std::string key_blob;
+#endif
+ std::string key_type;
+ std::string key_pass;
+ std::string pinned_public_key;
+#if SUPPORT_ALPN
+ bool enable_alpn = true;
+#endif // SUPPORT_ALPN
+#if SUPPORT_NPN
+ bool enable_npn = true;
+#endif // SUPPORT_ALPN
+ bool verify_host = true;
+ bool verify_peer = true;
+ bool verify_status = false;
+ int ssl_version = CURL_SSLVERSION_DEFAULT;
+#if SUPPORT_SSL_NO_REVOKE
+ bool ssl_no_revoke = false;
+#endif
+#if SUPPORT_MAX_TLS_VERSION
+ int max_version = CURL_SSLVERSION_MAX_DEFAULT;
+#endif
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string ca_info;
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string ca_path;
+#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
+ std::string ca_buffer;
+#endif
+ // We don't use fs::path here, as this leads to problems using windows
+ std::string crl_file;
+ std::string ciphers;
+#if SUPPORT_TLSv13_CIPHERS
+ std::string tls13_ciphers;
+#endif
+#if SUPPORT_SESSIONID_CACHE
+ bool session_id_cache = true;
+#endif
+
+ ~SslOptions() noexcept {
+#if SUPPORT_CURLOPT_SSLKEY_BLOB
+ util::secureStringClear(key_blob);
+#endif
+ util::secureStringClear(key_pass);
+ }
+
+ void SetOption(const ssl::CertFile& opt) {
+ cert_file = opt.filename.string();
+ cert_type = opt.GetCertType();
+ }
+ void SetOption(const ssl::KeyFile& opt) {
+ key_file = opt.filename.string();
+ key_type = opt.GetKeyType();
+ key_pass = opt.password;
+ }
+#if SUPPORT_CURLOPT_SSLKEY_BLOB
+ void SetOption(const ssl::KeyBlob& opt) {
+ key_blob = opt.blob;
+ key_type = opt.GetKeyType();
+ key_pass = opt.password;
+ }
+#endif
+ void SetOption(const ssl::PinnedPublicKey& opt) {
+ pinned_public_key = opt.pinned_public_key;
+ }
+
+#if SUPPORT_ALPN
+ void SetOption(const ssl::ALPN& opt) {
+ enable_alpn = opt.enabled;
+ }
+#endif // SUPPORT_ALPN
+#if SUPPORT_NPN
+ void SetOption(const ssl::NPN& opt) {
+ enable_npn = opt.enabled;
+ }
+#endif // SUPPORT_NPN
+ void SetOption(const ssl::VerifyHost& opt) {
+ verify_host = opt.enabled;
+ }
+ void SetOption(const ssl::VerifyPeer& opt) {
+ verify_peer = opt.enabled;
+ }
+ void SetOption(const ssl::VerifyStatus& opt) {
+ verify_status = opt.enabled;
+ }
+ void SetOption(const ssl::TLSv1& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_TLSv1;
+ }
+#if SUPPORT_SSL_NO_REVOKE
+ void SetOption(const ssl::NoRevoke& opt) {
+ ssl_no_revoke = opt.enabled;
+ }
+#endif
+#if SUPPORT_SSLv2
+ void SetOption(const ssl::SSLv2& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_SSLv2;
+ }
+#endif
+#if SUPPORT_SSLv3
+ void SetOption(const ssl::SSLv3& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_SSLv3;
+ }
+#endif
+#if SUPPORT_TLSv1_0
+ void SetOption(const ssl::TLSv1_0& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_TLSv1_0;
+ }
+#endif
+#if SUPPORT_TLSv1_1
+ void SetOption(const ssl::TLSv1_1& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_TLSv1_1;
+ }
+#endif
+#if SUPPORT_TLSv1_2
+ void SetOption(const ssl::TLSv1_2& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_TLSv1_2;
+ }
+#endif
+#if SUPPORT_TLSv1_3
+ void SetOption(const ssl::TLSv1_3& /*opt*/) {
+ ssl_version = CURL_SSLVERSION_TLSv1_3;
+ }
+#endif
+#if SUPPORT_MAX_TLS_VERSION
+ void SetOption(const ssl::MaxTLSVersion& /*opt*/) {
+ max_version = CURL_SSLVERSION_DEFAULT;
+ }
+#endif
+#if SUPPORT_MAX_TLSv1_0
+ void SetOption(const ssl::MaxTLSv1_0& opt) {
+ max_version = CURL_SSLVERSION_MAX_TLSv1_0;
+ }
+#endif
+#if SUPPORT_MAX_TLSv1_1
+ void SetOption(const ssl::MaxTLSv1_1& /*opt*/) {
+ max_version = CURL_SSLVERSION_MAX_TLSv1_1;
+ }
+#endif
+#if SUPPORT_MAX_TLSv1_2
+ void SetOption(const ssl::MaxTLSv1_2& /*opt*/) {
+ max_version = CURL_SSLVERSION_MAX_TLSv1_2;
+ }
+#endif
+#if SUPPORT_MAX_TLSv1_3
+ void SetOption(const ssl::MaxTLSv1_3& /*opt*/) {
+ max_version = CURL_SSLVERSION_MAX_TLSv1_3;
+ }
+#endif
+ void SetOption(const ssl::CaInfo& opt) {
+ ca_info = opt.filename.string();
+ }
+ void SetOption(const ssl::CaPath& opt) {
+ ca_path = opt.filename.string();
+ }
+#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
+ void SetOption(const ssl::CaBuffer& opt) {
+ ca_buffer = opt.buffer;
+ }
+#endif
+ void SetOption(const ssl::Crl& opt) {
+ crl_file = opt.filename.string();
+ }
+ void SetOption(const ssl::Ciphers& opt) {
+ ciphers = opt.ciphers;
+ }
+#if SUPPORT_TLSv13_CIPHERS
+ void SetOption(const ssl::TLS13_Ciphers& opt) {
+ tls13_ciphers = opt.ciphers;
+ }
+#endif
+#if SUPPORT_SESSIONID_CACHE
+ void SetOption(const ssl::SessionIdCache& opt) {
+ session_id_cache = opt.enabled;
+ }
+#endif
+};
+
+namespace priv {
+
+template <typename T>
+void set_ssl_option(SslOptions& opts, T&& t) {
+ opts.SetOption(std::forward<T>(t));
+}
+
+template <typename T, typename... Ts>
+void set_ssl_option(SslOptions& opts, T&& t, Ts&&... ts) {
+ set_ssl_option(opts, std::forward<T>(t));
+ set_ssl_option(opts, std::move(ts)...);
+}
+
+} // namespace priv
+
+template <typename... Ts>
+SslOptions Ssl(Ts&&... ts) {
+ SslOptions opts;
+ priv::set_ssl_option(opts, std::move(ts)...);
+ return opts;
+}
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/status_codes.h b/Src/external_dependencies/cpr/include/cpr/status_codes.h
new file mode 100644
index 00000000..6c7acd6b
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/status_codes.h
@@ -0,0 +1,100 @@
+#ifndef _CPR_STATUS_CODES
+#define _CPR_STATUS_CODES
+#include <cstdint>
+namespace cpr {
+namespace status {
+// Information responses
+constexpr std::int32_t HTTP_CONTINUE = 100;
+constexpr std::int32_t HTTP_SWITCHING_PROTOCOL = 101;
+constexpr std::int32_t HTTP_PROCESSING = 102;
+constexpr std::int32_t HTTP_EARLY_HINTS = 103;
+// Successful responses
+constexpr std::int32_t HTTP_OK = 200;
+constexpr std::int32_t HTTP_CREATED = 201;
+constexpr std::int32_t HTTP_ACCEPTED = 202;
+constexpr std::int32_t HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
+constexpr std::int32_t HTTP_NO_CONTENT = 204;
+constexpr std::int32_t HTTP_RESET_CONTENT = 205;
+constexpr std::int32_t HTTP_PARTIAL_CONTENT = 206;
+constexpr std::int32_t HTTP_MULTI_STATUS = 207;
+constexpr std::int32_t HTTP_ALREADY_REPORTED = 208;
+constexpr std::int32_t HTTP_IM_USED = 226;
+// Redirection messages
+constexpr std::int32_t HTTP_MULTIPLE_CHOICE = 300;
+constexpr std::int32_t HTTP_MOVED_PERMANENTLY = 301;
+constexpr std::int32_t HTTP_FOUND = 302;
+constexpr std::int32_t HTTP_SEE_OTHER = 303;
+constexpr std::int32_t HTTP_NOT_MODIFIED = 304;
+constexpr std::int32_t HTTP_USE_PROXY = 305;
+constexpr std::int32_t HTTP_UNUSED = 306;
+constexpr std::int32_t HTTP_TEMPORARY_REDIRECT = 307;
+constexpr std::int32_t HTTP_PERMANENT_REDIRECT = 308;
+// Client error responses
+constexpr std::int32_t HTTP_BAD_REQUEST = 400;
+constexpr std::int32_t HTTP_UNAUTHORIZED = 401;
+constexpr std::int32_t HTTP_PAYMENT_REQUIRED = 402;
+constexpr std::int32_t HTTP_FORBIDDEN = 403;
+constexpr std::int32_t HTTP_NOT_FOUND = 404;
+constexpr std::int32_t HTTP_METHOD_NOT_ALLOWED = 405;
+constexpr std::int32_t HTTP_NOT_ACCEPTABLE = 406;
+constexpr std::int32_t HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
+constexpr std::int32_t HTTP_REQUEST_TIMEOUT = 408;
+constexpr std::int32_t HTTP_CONFLICT = 409;
+constexpr std::int32_t HTTP_GONE = 410;
+constexpr std::int32_t HTTP_LENGTH_REQUIRED = 411;
+constexpr std::int32_t HTTP_PRECONDITION_FAILED = 412;
+constexpr std::int32_t HTTP_PAYLOAD_TOO_LARGE = 413;
+constexpr std::int32_t HTTP_URI_TOO_LONG = 414;
+constexpr std::int32_t HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
+constexpr std::int32_t HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+constexpr std::int32_t HTTP_EXPECTATION_FAILED = 417;
+constexpr std::int32_t HTTP_IM_A_TEAPOT = 418;
+constexpr std::int32_t HTTP_MISDIRECTED_REQUEST = 421;
+constexpr std::int32_t HTTP_UNPROCESSABLE_ENTITY = 422;
+constexpr std::int32_t HTTP_LOCKED = 423;
+constexpr std::int32_t HTTP_FAILED_DEPENDENCY = 424;
+constexpr std::int32_t HTTP_TOO_EARLY = 425;
+constexpr std::int32_t HTTP_UPGRADE_REQUIRED = 426;
+constexpr std::int32_t HTTP_PRECONDITION_REQUIRED = 428;
+constexpr std::int32_t HTTP_TOO_MANY_REQUESTS = 429;
+constexpr std::int32_t HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
+constexpr std::int32_t HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
+// Server response errors
+constexpr std::int32_t HTTP_INTERNAL_SERVER_ERROR = 500;
+constexpr std::int32_t HTTP_NOT_IMPLEMENTED = 501;
+constexpr std::int32_t HTTP_BAD_GATEWAY = 502;
+constexpr std::int32_t HTTP_SERVICE_UNAVAILABLE = 503;
+constexpr std::int32_t HTTP_GATEWAY_TIMEOUT = 504;
+constexpr std::int32_t HTTP_HTTP_VERSION_NOT_SUPPORTED = 505;
+constexpr std::int32_t HTTP_VARIANT_ALSO_NEGOTIATES = 506;
+constexpr std::int32_t HTTP_INSUFFICIENT_STORAGE = 507;
+constexpr std::int32_t HTTP_LOOP_DETECTED = 508;
+constexpr std::int32_t HTTP_NOT_EXTENDED = 510;
+constexpr std::int32_t HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;
+
+constexpr std::int32_t INFO_CODE_OFFSET = 100;
+constexpr std::int32_t SUCCESS_CODE_OFFSET = 200;
+constexpr std::int32_t REDIRECT_CODE_OFFSET = 300;
+constexpr std::int32_t CLIENT_ERROR_CODE_OFFSET = 400;
+constexpr std::int32_t SERVER_ERROR_CODE_OFFSET = 500;
+constexpr std::int32_t MISC_CODE_OFFSET = 600;
+
+constexpr bool is_informational(const std::int32_t code) {
+ return (code >= INFO_CODE_OFFSET && code < SUCCESS_CODE_OFFSET);
+}
+constexpr bool is_success(const std::int32_t code) {
+ return (code >= SUCCESS_CODE_OFFSET && code < REDIRECT_CODE_OFFSET);
+}
+constexpr bool is_redirect(const std::int32_t code) {
+ return (code >= REDIRECT_CODE_OFFSET && code < CLIENT_ERROR_CODE_OFFSET);
+}
+constexpr bool is_client_error(const std::int32_t code) {
+ return (code >= CLIENT_ERROR_CODE_OFFSET && code < SERVER_ERROR_CODE_OFFSET);
+}
+constexpr bool is_server_error(const std::int32_t code) {
+ return (code >= SERVER_ERROR_CODE_OFFSET && code < MISC_CODE_OFFSET);
+}
+
+} // namespace status
+} // namespace cpr
+#endif \ No newline at end of file
diff --git a/Src/external_dependencies/cpr/include/cpr/threadpool.h b/Src/external_dependencies/cpr/include/cpr/threadpool.h
new file mode 100644
index 00000000..bb7e7f21
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/threadpool.h
@@ -0,0 +1,122 @@
+#ifndef CPR_THREAD_POOL_H
+#define CPR_THREAD_POOL_H
+
+#include <atomic>
+#include <chrono>
+#include <condition_variable>
+#include <functional>
+#include <future>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <thread>
+#include <utility>
+
+#define CPR_DEFAULT_THREAD_POOL_MAX_THREAD_NUM std::thread::hardware_concurrency()
+
+constexpr size_t CPR_DEFAULT_THREAD_POOL_MIN_THREAD_NUM = 1;
+constexpr std::chrono::milliseconds CPR_DEFAULT_THREAD_POOL_MAX_IDLE_TIME{60000};
+
+namespace cpr {
+
+class ThreadPool {
+ public:
+ using Task = std::function<void()>;
+
+ explicit ThreadPool(size_t min_threads = CPR_DEFAULT_THREAD_POOL_MIN_THREAD_NUM, size_t max_threads = CPR_DEFAULT_THREAD_POOL_MAX_THREAD_NUM, std::chrono::milliseconds max_idle_ms = CPR_DEFAULT_THREAD_POOL_MAX_IDLE_TIME);
+
+ virtual ~ThreadPool();
+
+ void SetMinThreadNum(size_t min_threads) {
+ min_thread_num = min_threads;
+ }
+ void SetMaxThreadNum(size_t max_threads) {
+ max_thread_num = max_threads;
+ }
+ void SetMaxIdleTime(std::chrono::milliseconds ms) {
+ max_idle_time = ms;
+ }
+ size_t GetCurrentThreadNum() {
+ return cur_thread_num;
+ }
+ size_t GetIdleThreadNum() {
+ return idle_thread_num;
+ }
+ bool IsStarted() {
+ return status != STOP;
+ }
+ bool IsStopped() {
+ return status == STOP;
+ }
+
+ int Start(size_t start_threads = 0);
+ int Stop();
+ int Pause();
+ int Resume();
+ int Wait();
+
+ /**
+ * Return a future, calling future.get() will wait task done and return RetType.
+ * Submit(fn, args...)
+ * Submit(std::bind(&Class::mem_fn, &obj))
+ * Submit(std::mem_fn(&Class::mem_fn, &obj))
+ **/
+ template <class Fn, class... Args>
+ auto Submit(Fn&& fn, Args&&... args) {
+ if (status == STOP) {
+ Start();
+ }
+ if (idle_thread_num <= 0 && cur_thread_num < max_thread_num) {
+ CreateThread();
+ }
+ using RetType = decltype(fn(args...));
+ auto task = std::make_shared<std::packaged_task<RetType()> >(std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...));
+ std::future<RetType> future = task->get_future();
+ {
+ std::lock_guard<std::mutex> locker(task_mutex);
+ tasks.emplace([task] { (*task)(); });
+ }
+
+ task_cond.notify_one();
+ return future;
+ }
+
+ private:
+ bool CreateThread();
+ void AddThread(std::thread* thread);
+ void DelThread(std::thread::id id);
+
+ public:
+ size_t min_thread_num;
+ size_t max_thread_num;
+ std::chrono::milliseconds max_idle_time;
+
+ private:
+ enum Status {
+ STOP,
+ RUNNING,
+ PAUSE,
+ };
+
+ struct ThreadData {
+ std::shared_ptr<std::thread> thread;
+ std::thread::id id;
+ Status status;
+ time_t start_time;
+ time_t stop_time;
+ };
+
+ std::atomic<Status> status;
+ std::atomic<size_t> cur_thread_num;
+ std::atomic<size_t> idle_thread_num;
+ std::list<ThreadData> threads;
+ std::mutex thread_mutex;
+ std::queue<Task> tasks;
+ std::mutex task_mutex;
+ std::condition_variable task_cond;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/timeout.h b/Src/external_dependencies/cpr/include/cpr/timeout.h
new file mode 100644
index 00000000..492470ec
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/timeout.h
@@ -0,0 +1,27 @@
+#ifndef CPR_TIMEOUT_H
+#define CPR_TIMEOUT_H
+
+#include <chrono>
+#include <cstdint>
+
+namespace cpr {
+
+class Timeout {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Timeout(const std::chrono::milliseconds& duration) : ms{duration} {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Timeout(const std::int32_t& milliseconds) : Timeout{std::chrono::milliseconds(milliseconds)} {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Timeout(const std::chrono::seconds& duration) : ms{1000 * duration.count()} {}
+
+ // No way around since curl uses a long here.
+ // NOLINTNEXTLINE(google-runtime-int)
+ long Milliseconds() const;
+
+ std::chrono::milliseconds ms;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/unix_socket.h b/Src/external_dependencies/cpr/include/cpr/unix_socket.h
new file mode 100644
index 00000000..9d4d77c0
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/unix_socket.h
@@ -0,0 +1,21 @@
+#ifndef CPR_UNIX_SOCKET_H
+#define CPR_UNIX_SOCKET_H
+
+#include <string>
+
+namespace cpr {
+
+class UnixSocket {
+ public:
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ UnixSocket(std::string&& unix_socket) : unix_socket_(std::move(unix_socket)) {}
+
+ const char* GetUnixSocketString() const noexcept;
+
+ private:
+ const std::string unix_socket_;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/user_agent.h b/Src/external_dependencies/cpr/include/cpr/user_agent.h
new file mode 100644
index 00000000..369a80d9
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/user_agent.h
@@ -0,0 +1,33 @@
+#ifndef CPR_USERAGENT_H
+#define CPR_USERAGENT_H
+
+#include <initializer_list>
+#include <string>
+
+#include "cpr/cprtypes.h"
+
+namespace cpr {
+class UserAgent : public StringHolder<UserAgent> {
+ public:
+ UserAgent() : StringHolder<UserAgent>() {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ UserAgent(const std::string& useragent) : StringHolder<UserAgent>(useragent) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ UserAgent(std::string&& useragent) : StringHolder<UserAgent>(std::move(useragent)) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ UserAgent(std::string_view useragent) : StringHolder<UserAgent>(useragent) {}
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ UserAgent(const char* useragent) : StringHolder<UserAgent>(useragent) {}
+ UserAgent(const char* str, size_t len) : StringHolder<UserAgent>(str, len) {}
+ UserAgent(const std::initializer_list<std::string> args) : StringHolder<UserAgent>(args) {}
+ UserAgent(const UserAgent& other) = default;
+ UserAgent(UserAgent&& old) noexcept = default;
+ ~UserAgent() override = default;
+
+ UserAgent& operator=(UserAgent&& old) noexcept = default;
+ UserAgent& operator=(const UserAgent& other) = default;
+};
+
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/util.h b/Src/external_dependencies/cpr/include/cpr/util.h
new file mode 100644
index 00000000..f35ad473
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/util.h
@@ -0,0 +1,45 @@
+#ifndef CPR_UTIL_H
+#define CPR_UTIL_H
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "cpr/callback.h"
+#include "cpr/cookies.h"
+#include "cpr/cprtypes.h"
+#include "cpr/curlholder.h"
+
+namespace cpr {
+namespace util {
+
+Header parseHeader(const std::string& headers, std::string* status_line = nullptr, std::string* reason = nullptr);
+Cookies parseCookies(curl_slist* raw_cookies);
+size_t readUserFunction(char* ptr, size_t size, size_t nitems, const ReadCallback* read);
+size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCallback* header);
+size_t writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data);
+size_t writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* file);
+size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write);
+#if LIBCURL_VERSION_NUM < 0x072000
+int progressUserFunction(const ProgressCallback* progress, double dltotal, double dlnow, double ultotal, double ulnow);
+#else
+int progressUserFunction(const ProgressCallback* progress, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
+#endif
+int debugUserFunction(CURL* handle, curl_infotype type, char* data, size_t size, const DebugCallback* debug);
+std::vector<std::string> split(const std::string& to_split, char delimiter);
+std::string urlEncode(const std::string& s);
+std::string urlDecode(const std::string& s);
+
+/**
+ * Override the content of the provided string to hide sensitive data. The
+ * string content after invocation is undefined. The string size is reset to zero.
+ * impl. based on:
+ * https://github.com/ojeda/secure_clear/blob/master/example-implementation/secure_clear.h
+ **/
+void secureStringClear(std::string& s);
+bool isTrue(const std::string& s);
+
+} // namespace util
+} // namespace cpr
+
+#endif
diff --git a/Src/external_dependencies/cpr/include/cpr/verbose.h b/Src/external_dependencies/cpr/include/cpr/verbose.h
new file mode 100644
index 00000000..2bf0df8f
--- /dev/null
+++ b/Src/external_dependencies/cpr/include/cpr/verbose.h
@@ -0,0 +1,18 @@
+#ifndef CPR_VERBOSE_H_
+#define CPR_VERBOSE_H_
+
+namespace cpr {
+
+class Verbose {
+ public:
+ Verbose() = default;
+ // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
+ Verbose(const bool p_verbose) : verbose{p_verbose} {}
+
+ bool verbose = true;
+};
+
+} // namespace cpr
+
+
+#endif /* CPR_VERBOSE_H_ */