mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 10:55:45 -04:00
Initial community commit
This commit is contained in:
59
Src/external_dependencies/cpr/.clang-format
Normal file
59
Src/external_dependencies/cpr/.clang-format
Normal file
@ -0,0 +1,59 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: Google
|
||||
AccessModifierOffset: -2
|
||||
AlignAfterOpenBracket: true
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AlwaysBreakAfterDefinitionReturnType: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: true
|
||||
BinPackArguments: true
|
||||
ColumnLimit: 500
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
DerivePointerAlignment: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
IndentCaseLabels: true
|
||||
IndentWrappedFunctionNames: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
MaxEmptyLinesToKeep: 2
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
NamespaceIndentation: None
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Left
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
Standard: Auto
|
||||
IndentWidth: 4
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Attach
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpaceAfterCStyleCast: true
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 8
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
SpaceBeforeParens: ControlStatements
|
||||
...
|
40
Src/external_dependencies/cpr/.clang-tidy
Normal file
40
Src/external_dependencies/cpr/.clang-tidy
Normal file
@ -0,0 +1,40 @@
|
||||
---
|
||||
Checks: '*,
|
||||
-cppcoreguidelines-pro-type-static-cast-downcast,
|
||||
-fuchsia-default-arguments-calls,
|
||||
-fuchsia-default-arguments,
|
||||
-fuchsia-default-arguments-declarations,
|
||||
-fuchsia-overloaded-operator,
|
||||
-fuchsia-statically-constructed-objects,
|
||||
-hicpp-use-auto,
|
||||
-modernize-use-auto,
|
||||
-modernize-use-trailing-return-type,
|
||||
-readability-implicit-bool-conversion,
|
||||
-readability-const-return-type,
|
||||
-google-runtime-references,
|
||||
-misc-non-private-member-variables-in-classes,
|
||||
-llvm-include-order,
|
||||
-cppcoreguidelines-non-private-member-variables-in-classes,
|
||||
-cppcoreguidelines-pro-type-vararg,
|
||||
-hicpp-vararg,
|
||||
-cppcoreguidelines-owning-memory,
|
||||
-llvmlibc-callee-namespace,
|
||||
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||
-hicpp-no-array-decay,
|
||||
-modernize-pass-by-value,
|
||||
-cppcoreguidelines-pro-bounds-constant-array-index,
|
||||
-hicpp-signed-bitwise,
|
||||
-llvmlibc-implementation-in-namespace,
|
||||
-llvmlibc-restrict-system-libc-headers,
|
||||
-readability-function-cognitive-complexity,
|
||||
-readability-identifier-length,
|
||||
-altera-unroll-loops,
|
||||
-altera-id-dependent-backward-branch,
|
||||
-bugprone-easily-swappable-parameters,
|
||||
-modernize-return-braced-init-list,
|
||||
-cppcoreguidelines-avoid-magic-numbers,
|
||||
-readability-magic-numbers
|
||||
'
|
||||
WarningsAsErrors: '*'
|
||||
HeaderFilterRegex: 'src/*.hpp'
|
||||
FormatStyle: file
|
56
Src/external_dependencies/cpr/.gitignore
vendored
Normal file
56
Src/external_dependencies/cpr/.gitignore
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# CMake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
|
||||
# Custom
|
||||
build/
|
||||
!nuget/build
|
||||
|
||||
# Jekyll stuff
|
||||
_includes/
|
||||
_site/
|
||||
|
||||
# Vim
|
||||
.ycm_extra_conf.py*
|
||||
|
||||
# VSCode
|
||||
.vscode/
|
||||
.vs/
|
||||
|
||||
# clangd
|
||||
.cache/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
386
Src/external_dependencies/cpr/CMakeLists.txt
Normal file
386
Src/external_dependencies/cpr/CMakeLists.txt
Normal file
@ -0,0 +1,386 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(cpr VERSION 1.9.0 LANGUAGES CXX)
|
||||
|
||||
math(EXPR cpr_VERSION_NUM "${cpr_VERSION_MAJOR} * 0x10000 + ${cpr_VERSION_MINOR} * 0x100 + ${cpr_VERSION_PATCH}" OUTPUT_FORMAT HEXADECIMAL)
|
||||
configure_file("${cpr_SOURCE_DIR}/cmake/cprver.h.in" "${cpr_BINARY_DIR}/cpr_generated_includes/cpr/cprver.h")
|
||||
|
||||
# Only change the folder behaviour if cpr is not a subproject
|
||||
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMake")
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
||||
else()
|
||||
# Check required c++ standard of parent project
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
set(PARENT_CXX_STANDARD ${CMAKE_CXX_STANDARD})
|
||||
message(STATUS "CXX standard of parent project: ${PARENT_CXX_STANDARD}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Avoid the dll boilerplate code for windows
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
if (PARENT_CXX_STANDARD)
|
||||
# Don't set CMAKE_CXX_STANDARD if it is already set by parent project
|
||||
if (PARENT_CXX_STANDARD LESS 17)
|
||||
message(FATAL_ERROR "cpr ${cpr_VERSION} does not support ${PARENT_CXX_STANDARD}. Please use cpr <= 1.9.x")
|
||||
endif()
|
||||
else()
|
||||
# Set standard version if not already set by potential parent project
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
message(STATUS "CXX standard: ${CMAKE_CXX_STANDARD}")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CPR_LIBRARIES cpr CACHE INTERNAL "")
|
||||
|
||||
macro(cpr_option OPTION_NAME OPTION_TEXT OPTION_DEFAULT)
|
||||
option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT})
|
||||
if(DEFINED ENV{${OPTION_NAME}})
|
||||
# Allow overriding the option through an environment variable
|
||||
set(${OPTION_NAME} $ENV{${OPTION_NAME}})
|
||||
endif()
|
||||
if(${OPTION_NAME})
|
||||
add_definitions(-D${OPTION_NAME})
|
||||
endif()
|
||||
message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}")
|
||||
endmacro()
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build libraries as shared libraries" ON)
|
||||
message(STATUS "C++ Requests CMake Options")
|
||||
message(STATUS "=======================================================")
|
||||
cpr_option(CPR_GENERATE_COVERAGE "Set to ON to generate coverage reports." OFF)
|
||||
cpr_option(CPR_CURL_NOSIGNAL "Set to ON to disable use of signals in libcurl." OFF)
|
||||
cpr_option(CURL_VERBOSE_LOGGING "Curl verbose logging during building curl" OFF)
|
||||
cpr_option(CPR_USE_SYSTEM_GTEST "If ON, this project will look in the system paths for an installed gtest library. If none is found it will use the build in one." OFF)
|
||||
cpr_option(CPR_USE_SYSTEM_CURL "If enabled we will use the curl lib already installed on this system." OFF)
|
||||
cpr_option(CPR_ENABLE_SSL "Enables or disables the SSL backend. Required to perform HTTPS requests." ON)
|
||||
cpr_option(CPR_FORCE_OPENSSL_BACKEND "Force to use the OpenSSL backend. If CPR_FORCE_OPENSSL_BACKEND, CPR_FORCE_DARWINSSL_BACKEND, CPR_FORCE_MBEDTLS_BACKEND, and CPR_FORCE_WINSSL_BACKEND are set to to OFF, cpr will try to automatically detect the best available SSL backend (WinSSL - Windows, OpenSSL - Linux, DarwinSSL - Mac ...)." OFF)
|
||||
cpr_option(CPR_FORCE_WINSSL_BACKEND "Force to use the WinSSL backend. If CPR_FORCE_OPENSSL_BACKEND, CPR_FORCE_DARWINSSL_BACKEND, CPR_FORCE_MBEDTLS_BACKEND, and CPR_FORCE_WINSSL_BACKEND are set to to OFF, cpr will try to automatically detect the best available SSL backend (WinSSL - Windows, OpenSSL - Linux, DarwinSSL - Mac ...)." OFF)
|
||||
cpr_option(CPR_FORCE_DARWINSSL_BACKEND "Force to use the DarwinSSL backend. If CPR_FORCE_OPENSSL_BACKEND, CPR_FORCE_DARWINSSL_BACKEND, CPR_FORCE_MBEDTLS_BACKEND, and CPR_FORCE_WINSSL_BACKEND are set to to OFF, cpr will try to automatically detect the best available SSL backend (WinSSL - Windows, OpenSSL - Linux, DarwinSSL - Mac ...)." OFF)
|
||||
cpr_option(CPR_FORCE_MBEDTLS_BACKEND "Force to use the Mbed TLS backend. If CPR_FORCE_OPENSSL_BACKEND, CPR_FORCE_DARWINSSL_BACKEND, CPR_FORCE_MBEDTLS_BACKEND, and CPR_FORCE_WINSSL_BACKEND are set to to OFF, cpr will try to automatically detect the best available SSL backend (WinSSL - Windows, OpenSSL - Linux, DarwinSSL - Mac ...)." OFF)
|
||||
cpr_option(CPR_ENABLE_LINTING "Set to ON to enable clang linting." OFF)
|
||||
cpr_option(CPR_ENABLE_CPPCHECK "Set to ON to enable Cppcheck static analysis. Requires CPR_BUILD_TESTS and CPR_BUILD_TESTS_SSL to be OFF to prevent checking google tests source code." OFF)
|
||||
cpr_option(CPR_BUILD_TESTS "Set to ON to build cpr tests." OFF)
|
||||
cpr_option(CPR_BUILD_TESTS_SSL "Set to ON to build cpr ssl tests" ${CPR_BUILD_TESTS})
|
||||
cpr_option(CPR_BUILD_TESTS_PROXY "Set to ON to build proxy tests. They fail in case there is no valid proxy server available in proxy_tests.cpp" OFF)
|
||||
cpr_option(CPR_SKIP_CA_BUNDLE_SEARCH "Skip searching for Certificate Authority certs. Turn ON systems like iOS where file access is restricted and prevents https from working." OFF)
|
||||
cpr_option(CPR_USE_BOOST_FILESYSTEM "Set to ON to use the Boost.Filesystem library on OSX." OFF)
|
||||
message(STATUS "=======================================================")
|
||||
|
||||
if (CPR_FORCE_USE_SYSTEM_CURL)
|
||||
message(WARNING "The variable CPR_FORCE_USE_SYSTEM_CURL is deprecated, please use CPR_USE_SYSTEM_CURL instead")
|
||||
set(CPR_USE_SYSTEM_CURL ${CPR_FORCE_USE_SYSTEM_CURL})
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(FetchContent)
|
||||
include(cmake/code_coverage.cmake)
|
||||
include(cmake/sanitizer.cmake)
|
||||
include(cmake/clear_variable.cmake)
|
||||
|
||||
# So CMake can find FindMbedTLS.cmake
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
|
||||
|
||||
# Linting
|
||||
if(CPR_ENABLE_LINTING)
|
||||
include(cmake/clang-tidy.cmake)
|
||||
endif()
|
||||
|
||||
# Cppcheck
|
||||
if(CPR_ENABLE_CPPCHECK)
|
||||
if(CPR_BUILD_TESTS OR CPR_BUILD_TESTS_SSL)
|
||||
message(FATAL_ERROR "Cppcheck is incompatible with building tests. Make sure to disable CPR_ENABLE_CPPCHECK or disable tests by setting CPR_BUILD_TESTS and CPR_BUILD_TESTS_SSL to OFF. This is because Cppcheck would try to check the google tests source code and then fail. ")
|
||||
endif()
|
||||
include(cmake/cppcheck.cmake)
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Werror")
|
||||
endif()
|
||||
|
||||
# SSL
|
||||
if(CPR_ENABLE_SSL)
|
||||
if(CPR_FORCE_OPENSSL_BACKEND OR CPR_FORCE_WINSSL_BACKEND OR CPR_FORCE_DARWINSSL_BACKEND OR CPR_FORCE_MBEDTLS_BACKEND)
|
||||
message(STATUS "Disabled SSL backend auto detect since either CPR_FORCE_OPENSSL_BACKEND, CPR_FORCE_DARWINSSL_BACKEND, CPR_FORCE_MBEDTLS_BACKEND, or CPR_FORCE_WINSSL_BACKEND is enabled.")
|
||||
set(DETECT_SSL_BACKEND OFF CACHE INTERNAL "" FORCE)
|
||||
else()
|
||||
message(STATUS "Automatically detecting SSL backend.")
|
||||
set(DETECT_SSL_BACKEND ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(CPR_FORCE_WINSSL_BACKEND AND (NOT WIN32))
|
||||
message(FATAL_ERROR "WinSSL is only available on Windows! Use either OpenSSL (CPR_FORCE_OPENSSL_BACKEND) or DarwinSSL (CPR_FORCE_DARWINSSL_BACKEND) instead.")
|
||||
endif()
|
||||
|
||||
if(DETECT_SSL_BACKEND)
|
||||
message(STATUS "Detecting SSL backend...")
|
||||
if(WIN32)
|
||||
message(STATUS "SSL auto detect: Using WinSSL.")
|
||||
set(SSL_BACKEND_USED "WinSSL")
|
||||
elseif(APPLE)
|
||||
message(STATUS "SSL auto detect: Using DarwinSSL.")
|
||||
set(CPR_BUILD_TESTS_SSL OFF)
|
||||
set(SSL_BACKEND_USED "DarwinSSL")
|
||||
else()
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
message(STATUS "SSL auto detect: Using OpenSSL.")
|
||||
set(SSL_BACKEND_USED "OpenSSL")
|
||||
else()
|
||||
find_package(MbedTLS)
|
||||
if(MBEDTLS_FOUND)
|
||||
set(SSL_BACKEND_USED "MbedTLS")
|
||||
else()
|
||||
message(FATAL_ERROR "No valid SSL backend found! Please install OpenSSL, Mbed TLS or disable SSL by setting CPR_ENABLE_SSL to OFF.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
if(CPR_FORCE_OPENSSL_BACKEND)
|
||||
find_package(OpenSSL)
|
||||
if(OPENSSL_FOUND)
|
||||
message(STATUS "Using OpenSSL.")
|
||||
set(SSL_BACKEND_USED "OpenSSL")
|
||||
else()
|
||||
message(FATAL_ERROR "CPR_FORCE_OPENSSL_BACKEND enabled but we were not able to find OpenSSL!")
|
||||
endif()
|
||||
elseif(CPR_FORCE_WINSSL_BACKEND)
|
||||
message(STATUS "Using WinSSL.")
|
||||
set(SSL_BACKEND_USED "WinSSL")
|
||||
elseif(CPR_FORCE_DARWINSSL_BACKEND)
|
||||
message(STATUS "Using DarwinSSL.")
|
||||
set(CPR_BUILD_TESTS_SSL OFF)
|
||||
set(SSL_BACKEND_USED "DarwinSSL")
|
||||
elseif(CPR_FORCE_MBEDTLS_BACKEND)
|
||||
message(STATUS "Using Mbed TLS.")
|
||||
set(CPR_BUILD_TESTS_SSL OFF)
|
||||
set(SSL_BACKEND_USED "MbedTLS")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(SSL_BACKEND_USED STREQUAL "OpenSSL")
|
||||
# Fix missing OpenSSL includes for Windows since in 'ssl_ctx.cpp' we include OpenSSL directly
|
||||
find_package(OpenSSL REQUIRED)
|
||||
add_compile_definitions(OPENSSL_BACKEND_USED)
|
||||
endif()
|
||||
|
||||
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if (NOT isMultiConfig)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${ALLOWED_BUILD_TYPES}")
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
|
||||
elseif(NOT CMAKE_BUILD_TYPE IN_LIST ALLOWED_BUILD_TYPES)
|
||||
message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
|
||||
endif()
|
||||
else ()
|
||||
unset(CMAKE_BUILD_TYPE)
|
||||
foreach(TYPE ${ALLOWED_BUILD_TYPES})
|
||||
if (NOT ${TYPE} IN_LIST CMAKE_CONFIGURATION_TYPES)
|
||||
list(APPEND CMAKE_CONFIGURATION_TYPES ${TYPE})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Curl configuration
|
||||
if(CPR_USE_SYSTEM_CURL)
|
||||
if(CPR_ENABLE_SSL)
|
||||
find_package(CURL COMPONENTS HTTP HTTPS)
|
||||
if(CURL_FOUND)
|
||||
message(STATUS "Curl ${CURL_VERSION_STRING} found on this system.")
|
||||
# To be able to load certificates under Windows when using OpenSSL:
|
||||
if(CMAKE_USE_OPENSSL AND WIN32 AND (NOT (CURL_VERSION_STRING VERSION_GREATER_EQUAL "7.71.0")))
|
||||
message(FATAL_ERROR "Your system curl version (${CURL_VERSION_STRING}) is too old to support OpenSSL on Windows which requires curl >= 7.71.0. Update your curl version, use WinSSL, disable SSL or use the build in version of curl.")
|
||||
endif()
|
||||
else()
|
||||
find_package(CURL COMPONENTS HTTP)
|
||||
if(CURL_FOUND)
|
||||
message(FATAL_ERROR "Curl found on this system but WITHOUT HTTPS/SSL support. Either disable SSL by setting CPR_ENABLE_SSL to OFF or use the build in version of curl by setting CPR_USE_SYSTEM_CURL to OFF.")
|
||||
else()
|
||||
message(FATAL_ERROR "Curl not found on this system. To use the build in version set CPR_USE_SYSTEM_CURL to OFF.")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_package(CURL COMPONENTS HTTP)
|
||||
if(CURL_FOUND)
|
||||
message(STATUS "Curl found on this system.")
|
||||
else()
|
||||
message(FATAL_ERROR "Curl not found on this system. To use the build in version set CPR_USE_SYSTEM_CURL to OFF.")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Configuring build in curl...")
|
||||
|
||||
# ZLIB is optional for curl
|
||||
# to disable it:
|
||||
# * from command line:
|
||||
# -DCURL_ZLIB=OFF
|
||||
# * from CMake script:
|
||||
# SET(CURL_ZLIB OFF CACHE STRING "" FORCE)
|
||||
if (CURL_ZLIB OR CURL_ZLIB STREQUAL AUTO OR NOT DEFINED CACHE{CURL_ZLIB})
|
||||
include(cmake/zlib_external.cmake)
|
||||
endif()
|
||||
|
||||
# We only need HTTP (and HTTPS) support:
|
||||
set(HTTP_ONLY ON CACHE INTERNAL "" FORCE)
|
||||
set(BUILD_CURL_EXE OFF CACHE INTERNAL "" FORCE)
|
||||
set(BUILD_TESTING OFF)
|
||||
|
||||
if (CURL_VERBOSE_LOGGING)
|
||||
message(STATUS "Enabled curl debug features")
|
||||
set(ENABLE_DEBUG ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
if (CPR_ENABLE_SSL)
|
||||
set(SSL_ENABLED ON CACHE INTERNAL "" FORCE)
|
||||
if(ANDROID)
|
||||
set(CURL_CA_PATH "/system/etc/security/cacerts" CACHE INTERNAL "")
|
||||
elseif(CPR_SKIP_CA_BUNDLE_SEARCH)
|
||||
set(CURL_CA_PATH "none" CACHE INTERNAL "")
|
||||
else()
|
||||
set(CURL_CA_PATH "auto" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
if(CPR_SKIP_CA_BUNDLE_SEARCH)
|
||||
set(CURL_CA_BUNDLE "none" CACHE INTERNAL "")
|
||||
elseif(NOT DEFINED CURL_CA_BUNDLE)
|
||||
set(CURL_CA_BUNDLE "auto" CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
if(SSL_BACKEND_USED STREQUAL "WinSSL")
|
||||
set(CMAKE_USE_SCHANNEL ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(SSL_BACKEND_USED STREQUAL "OpenSSL")
|
||||
set(CMAKE_USE_OPENSSL ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(SSL_BACKEND_USED STREQUAL "DarwinSSL")
|
||||
set(CMAKE_USE_SECTRANSP ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
if(SSL_BACKEND_USED STREQUAL "MbedTLS")
|
||||
set(CMAKE_USE_MBEDTLS ON CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
message(STATUS "Enabled curl SSL")
|
||||
else()
|
||||
set(SSL_ENABLED OFF CACHE INTERNAL "" FORCE)
|
||||
set(CURL_CA_PATH "none" CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_USE_SCHANNEL OFF CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_USE_OPENSSL OFF CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_USE_SECTRANSP OFF CACHE INTERNAL "" FORCE)
|
||||
set(CMAKE_USE_MBEDTLS OFF CACHE INTERNAL "" FORCE)
|
||||
message(STATUS "Disabled curl SSL")
|
||||
endif()
|
||||
# Disable linting for curl
|
||||
clear_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
|
||||
FetchContent_Declare(curl
|
||||
URL https://github.com/curl/curl/releases/download/curl-7_80_0/curl-7.80.0.tar.xz
|
||||
URL_HASH SHA256=a132bd93188b938771135ac7c1f3ac1d3ce507c1fcbef8c471397639214ae2ab # the file hash for curl-7.80.0.tar.xz
|
||||
USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
|
||||
FetchContent_MakeAvailable(curl)
|
||||
|
||||
restore_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
|
||||
# Group under the "external" project folder in IDEs such as Visual Studio.
|
||||
if(BUILD_CURL_EXE)
|
||||
set_property(TARGET curl PROPERTY FOLDER "external")
|
||||
endif()
|
||||
|
||||
set_property(TARGET libcurl PROPERTY FOLDER "external")
|
||||
endif()
|
||||
|
||||
# GTest configuration
|
||||
if(CPR_BUILD_TESTS)
|
||||
if(CPR_USE_SYSTEM_GTEST)
|
||||
find_package(GTest)
|
||||
endif()
|
||||
if(NOT CPR_USE_SYSTEM_GTEST OR NOT GTEST_FOUND)
|
||||
message(STATUS "Not using system gtest, using built-in googletest project instead.")
|
||||
if(MSVC)
|
||||
# By default, GTest compiles on Windows in CRT static linkage mode. We use this
|
||||
# variable to force it into using the CRT in dynamic linkage (DLL), just as CPR
|
||||
# does.
|
||||
set(gtest_force_shared_crt ON CACHE BOOL "Force gtest to use the shared c runtime")
|
||||
endif()
|
||||
|
||||
# Disable linting for google test
|
||||
clear_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
|
||||
FetchContent_Declare(googletest
|
||||
URL https://github.com/google/googletest/archive/release-1.11.0.tar.gz
|
||||
URL_HASH SHA256=b4870bf121ff7795ba20d20bcdd8627b8e088f2d1dab299a031c1034eddc93d5 # the file hash for release-1.11.0.tar.gz
|
||||
USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
restore_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
|
||||
add_library(gtest_int INTERFACE)
|
||||
target_link_libraries(gtest_int INTERFACE gtest)
|
||||
target_include_directories(gtest_int INTERFACE ${googletest_SOURCE_DIR}/include)
|
||||
|
||||
add_library(GTest::GTest ALIAS gtest_int)
|
||||
|
||||
# Group under the "tests/gtest" project folder in IDEs such as Visual Studio.
|
||||
set_property(TARGET gtest PROPERTY FOLDER "tests/gtest")
|
||||
set_property(TARGET gtest_main PROPERTY FOLDER "tests/gtest")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Mongoose configuration
|
||||
if(CPR_BUILD_TESTS)
|
||||
message(STATUS "Building mongoose project for test support.")
|
||||
|
||||
if(CPR_BUILD_TESTS_SSL)
|
||||
if(NOT CPR_ENABLE_SSL)
|
||||
message(FATAL_ERROR "OpenSSL is required to build SSL test but CPR_ENABLE_SSL is disabled. Either set CPR_ENABLE_SSL to ON or disable CPR_BUILD_TESTS_SSL.")
|
||||
endif()
|
||||
|
||||
if(NOT(SSL_BACKEND_USED STREQUAL "OpenSSL"))
|
||||
message(FATAL_ERROR "OpenSSL is required for SSL test, but it seams like OpenSSL is not being used as SSL backend. Either set CPR_BUILD_TESTS_SSL to OFF or set CPR_FORCE_OPENSSL_BACKEND to ON and try again.")
|
||||
endif()
|
||||
|
||||
set(ENABLE_SSL_TESTS ON CACHE INTERNAL "")
|
||||
else()
|
||||
set(ENABLE_SSL_TESTS OFF CACHE INTERNAL "")
|
||||
endif()
|
||||
|
||||
# Disable linting for mongoose
|
||||
clear_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
|
||||
FetchContent_Declare(mongoose
|
||||
URL https://github.com/cesanta/mongoose/archive/7.7.tar.gz
|
||||
URL_HASH SHA256=4e5733dae31c3a81156af63ca9aa3a6b9b736547f21f23c3ab2f8e3f1ecc16c0 # the hash for 7.7.tar.gz
|
||||
USES_TERMINAL_DOWNLOAD TRUE) # <---- This is needed only for Ninja to show download progress
|
||||
# We can not use FetchContent_MakeAvailable, since we need to patch mongoose to use CMake
|
||||
if (NOT mongoose_POPULATED)
|
||||
FetchContent_POPULATE(mongoose)
|
||||
|
||||
file(INSTALL cmake/mongoose.CMakeLists.txt DESTINATION ${mongoose_SOURCE_DIR})
|
||||
file(RENAME ${mongoose_SOURCE_DIR}/mongoose.CMakeLists.txt ${mongoose_SOURCE_DIR}/CMakeLists.txt)
|
||||
add_subdirectory(${mongoose_SOURCE_DIR} ${mongoose_BINARY_DIR})
|
||||
|
||||
endif()
|
||||
# Group under the "external" project folder in IDEs such as Visual Studio.
|
||||
set_property(TARGET mongoose PROPERTY FOLDER "external")
|
||||
restore_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(cpr)
|
||||
add_subdirectory(include)
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND CPR_BUILD_TESTS)
|
||||
# Disable linting for tests since they are currently not up to the standard
|
||||
clear_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
enable_testing()
|
||||
add_subdirectory(test)
|
||||
restore_variable(DESTINATION CMAKE_CXX_CLANG_TIDY BACKUP CMAKE_CXX_CLANG_TIDY_BKP)
|
||||
endif()
|
128
Src/external_dependencies/cpr/CODE_OF_CONDUCT.md
Normal file
128
Src/external_dependencies/cpr/CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
cc@libcpr.org.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
27
Src/external_dependencies/cpr/CONTRIBUTING.md
Normal file
27
Src/external_dependencies/cpr/CONTRIBUTING.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Contributing to C++ Requests
|
||||
|
||||
Please fork this repository and contribute back using [pull requests](https://github.com/whoshuu/cpr/pulls). Features can be requested using [issues](https://github.com/whoshuu/cpr/issues). All code, comments, and critiques are greatly appreciated.
|
||||
|
||||
## Formatting
|
||||
|
||||
To avoid unproductive debates on formatting, this project uses `clang-format` to ensure a consistent style across all source files. Currently, `clang-format` 3.8 is the version of `clang-format` we use. The format file can be found [here](https://github.com/whoshuu/cpr/blob/master/.clang-format). To install `clang-format` on Ubuntu, run this:
|
||||
|
||||
```
|
||||
apt-get install clang-format-3.8
|
||||
```
|
||||
|
||||
To install `clang-format` on OS X, run this:
|
||||
|
||||
```
|
||||
brew install clang-format
|
||||
```
|
||||
|
||||
Note that `brew` might install a later version of `clang-format`, but it should be mostly compatible with what's run on the Travis servers.
|
||||
|
||||
To run `clang-format` on every source file, run this in the root directory:
|
||||
|
||||
```
|
||||
./format-check.sh
|
||||
```
|
||||
|
||||
This should indicate which files need formatting and also show a diff of the requested changes. More specific usage instructions can be found on the official [LLVM website](http://releases.llvm.org/3.8.0/tools/clang/docs/ClangFormat.html).
|
2
Src/external_dependencies/cpr/CppCheckSuppressions.txt
Normal file
2
Src/external_dependencies/cpr/CppCheckSuppressions.txt
Normal file
@ -0,0 +1,2 @@
|
||||
noExplicitConstructor
|
||||
ConfigurationNotChecked
|
25
Src/external_dependencies/cpr/LICENSE
Normal file
25
Src/external_dependencies/cpr/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
This license applies to everything except the contents of the "test"
|
||||
directory and its subdirectories.
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2021 Huu Nguyen
|
||||
Copyright (c) 2022 libcpr and many other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
162
Src/external_dependencies/cpr/README.md
Normal file
162
Src/external_dependencies/cpr/README.md
Normal file
@ -0,0 +1,162 @@
|
||||
# C++ Requests: Curl for People <img align="right" height="40" src="http://i.imgur.com/d9Xtyts.png">
|
||||
|
||||
[](https://docs.libcpr.org/)
|
||||

|
||||
[](https://gitter.im/libcpr/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
## Announcements
|
||||
|
||||
* Like you probably have noticed, `cpr` moved to a new home from https://github.com/whoshuu/cpr to https://github.com/libcpr/cpr. Read more [here](https://github.com/libcpr/cpr/issues/636).
|
||||
* This project is being maintained by [Fabian Sauter](https://github.com/com8) and [Kilian Traub](https://github.com/KingKili).
|
||||
* For quick help, and discussion libcpr also offer a [gitter](https://gitter.im/libcpr/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link) chat.
|
||||
|
||||
## TLDR
|
||||
|
||||
C++ Requests is a simple wrapper around [libcurl](http://curl.haxx.se/libcurl) inspired by the excellent [Python Requests](https://github.com/kennethreitz/requests) project.
|
||||
|
||||
Despite its name, libcurl's easy interface is anything but, and making mistakes, misusing it is a common source of error and frustration. Using the more expressive language facilities of `C++17` (or `C++11` in case you use cpr < 1.10.0), this library captures the essence of making network calls into a few concise idioms.
|
||||
|
||||
Here's a quick GET request:
|
||||
|
||||
```c++
|
||||
#include <cpr/cpr.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
cpr::Response r = cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
|
||||
cpr::Authentication{"user", "pass", cpr::AuthMode::BASIC},
|
||||
cpr::Parameters{{"anon", "true"}, {"key", "value"}});
|
||||
r.status_code; // 200
|
||||
r.header["content-type"]; // application/json; charset=utf-8
|
||||
r.text; // JSON text string
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
And here's [less functional, more complicated code, without cpr](https://gist.github.com/whoshuu/2dc858b8730079602044).
|
||||
|
||||
## Documentation
|
||||
|
||||
[](https://docs.libcpr.org/)
|
||||
You can find the latest documentation [here](https://docs.libcpr.org/). It's a work in progress, but it should give you a better idea of how to use the library than the [tests](https://github.com/libcpr/cpr/tree/master/test) currently do.
|
||||
|
||||
## Features
|
||||
|
||||
C++ Requests currently supports:
|
||||
|
||||
* Custom headers
|
||||
* Url encoded parameters
|
||||
* Url encoded POST values
|
||||
* Multipart form POST upload
|
||||
* File POST upload
|
||||
* Basic authentication
|
||||
* Bearer authentication
|
||||
* Digest authentication
|
||||
* NTLM authentication
|
||||
* Connection and request timeout specification
|
||||
* Timeout for low speed connection
|
||||
* Asynchronous requests
|
||||
* :cookie: support!
|
||||
* Proxy support
|
||||
* Callback interfaces
|
||||
* PUT methods
|
||||
* DELETE methods
|
||||
* HEAD methods
|
||||
* OPTIONS methods
|
||||
* PATCH methods
|
||||
* Thread Safe access to [libCurl](https://curl.haxx.se/libcurl/c/threadsafe.html)
|
||||
* OpenSSL and WinSSL support for HTTPS requests
|
||||
|
||||
## Planned
|
||||
|
||||
For a quick overview about the planed features, have a look at the next [Milestones](https://github.com/libcpr/cpr/milestones).
|
||||
|
||||
## Usage
|
||||
|
||||
### CMake
|
||||
|
||||
#### fetch_content:
|
||||
If you already have a CMake project you need to integrate C++ Requests with, the primary way is to use `fetch_content`.
|
||||
Add the following to your `CMakeLists.txt`.
|
||||
|
||||
|
||||
```cmake
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
|
||||
GIT_TAG 871ed52d350214a034f6ef8a3b8f51c5ce1bd400) # The commit hash for 1.9.0. Replace with the latest from: https://github.com/libcpr/cpr/releases
|
||||
FetchContent_MakeAvailable(cpr)
|
||||
```
|
||||
|
||||
This will produce the target `cpr::cpr` which you can link against the typical way:
|
||||
|
||||
```cmake
|
||||
target_link_libraries(your_target_name PRIVATE cpr::cpr)
|
||||
```
|
||||
|
||||
That should do it!
|
||||
There's no need to handle `libcurl` yourself. All dependencies are taken care of for you.
|
||||
All of this can be found in an example [**here**](https://github.com/libcpr/example-cmake-fetch-content).
|
||||
|
||||
#### find_package():
|
||||
If you prefer not to use `fetch_content`, you can download, build, and install the library and then use CMake `find_package()` function to integrate it into a project.
|
||||
|
||||
**Note:** this feature is feasible only if CPR_USE_SYSTEM_CURL is set. (see [#645](https://github.com/libcpr/cpr/pull/645))
|
||||
```Bash
|
||||
$ git clone https://github.com/libcpr/cpr.git
|
||||
$ cd cpr && mkdir build && cd build
|
||||
$ cmake .. -DCPR_USE_SYSTEM_CURL=ON
|
||||
$ cmake --build .
|
||||
$ sudo cmake --install .
|
||||
```
|
||||
In your `CMakeLists.txt`:
|
||||
```cmake
|
||||
find_package(cpr REQUIRED)
|
||||
add_executable(your_target_name your_target_name.cpp)
|
||||
target_link_libraries(your_target_name PRIVATE cpr::cpr)
|
||||
```
|
||||
|
||||
### Bazel
|
||||
|
||||
Please refer to [hedronvision/bazel-make-cc-https-easy](https://github.com/hedronvision/bazel-make-cc-https-easy).
|
||||
|
||||
### Packages for Linux Distributions
|
||||
|
||||
Alternatively, you may install a package specific to your Linux distribution. Since so few distributions currently have a package for cpr, most users will not be able to run your program with this approach.
|
||||
|
||||
Currently, we are aware of packages for the following distributions:
|
||||
|
||||
* [Arch Linux (AUR)](https://aur.archlinux.org/packages/cpr)
|
||||
|
||||
If there's no package for your distribution, try making one! If you do, and it is added to your distribution's repositories, please submit a pull request to add it to the list above. However, please only do this if you plan to actively maintain the package.
|
||||
|
||||
### NuGet Package
|
||||
|
||||
For Windows, there is also a libcpr NuGet package available. Currently, x86 and x64 builds are supported with release and debug configuration.
|
||||
|
||||
The package can be found here: [NuGet.org](https://www.nuget.org/packages/libcpr/)
|
||||
|
||||
## Requirements
|
||||
|
||||
The only explicit requirements are:
|
||||
|
||||
* a `C++17` compatible compiler such as Clang or GCC. The minimum required version of GCC is unknown, so if anyone has trouble building this library with a specific version of GCC, do let me know
|
||||
* in case you only have a `C++11` compatible compiler available, all versions below cpr 1.9.x are for you. With the upcoming release of cpr 1.10.0, we are switching to `C++17` as a requirement.
|
||||
* If you would like to perform https requests `OpenSSL` and its development libraries are required.
|
||||
|
||||
## Building cpr - Using vcpkg
|
||||
|
||||
You can download and install cpr using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
```Bash
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install cpr
|
||||
```
|
||||
The `cpr` port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Building cpr - Using Conan
|
||||
|
||||
You can download and install `cpr` using the [Conan](https://conan.io/) package manager. Setup your CMakeLists.txt (see [Conan documentation](https://docs.conan.io/en/latest/integrations/build_system.html) on how to use MSBuild, Meson and others).
|
||||
An example can be found [**here**](https://github.com/libcpr/example-cmake-conan).
|
||||
|
||||
The `cpr` package in Conan is kept up to date by Conan contributors. If the version is out of date, please [create an issue or pull request](https://github.com/conan-io/conan-center-index) on the `conan-center-index` repository.
|
14
Src/external_dependencies/cpr/cmake/FindMbedTLS.cmake
Normal file
14
Src/external_dependencies/cpr/cmake/FindMbedTLS.cmake
Normal file
@ -0,0 +1,14 @@
|
||||
# Source: https://github.com/curl/curl/blob/curl-7_82_0/CMake/FindMbedTLS.cmake
|
||||
find_path(MBEDTLS_INCLUDE_DIRS mbedtls/ssl.h)
|
||||
|
||||
find_library(MBEDTLS_LIBRARY mbedtls)
|
||||
find_library(MBEDX509_LIBRARY mbedx509)
|
||||
find_library(MBEDCRYPTO_LIBRARY mbedcrypto)
|
||||
|
||||
set(MBEDTLS_LIBRARIES "${MBEDTLS_LIBRARY}" "${MBEDX509_LIBRARY}" "${MBEDCRYPTO_LIBRARY}")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(MbedTLS DEFAULT_MSG
|
||||
MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
||||
|
||||
mark_as_advanced(MBEDTLS_INCLUDE_DIRS MBEDTLS_LIBRARY MBEDX509_LIBRARY MBEDCRYPTO_LIBRARY)
|
13
Src/external_dependencies/cpr/cmake/clang-tidy.cmake
Normal file
13
Src/external_dependencies/cpr/cmake/clang-tidy.cmake
Normal file
@ -0,0 +1,13 @@
|
||||
if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy)
|
||||
mark_as_advanced(CLANG_TIDY_EXECUTABLE)
|
||||
|
||||
if (${CLANG_TIDY_EXECUTABLE})
|
||||
message(FATAL_ERROR "Clang-tidy not found")
|
||||
else()
|
||||
message(STATUS "Enabling clang-tidy")
|
||||
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXECUTABLE};-warnings-as-errors=*")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "Clang-tidy is not supported when building for windows")
|
||||
endif()
|
11
Src/external_dependencies/cpr/cmake/clear_variable.cmake
Normal file
11
Src/external_dependencies/cpr/cmake/clear_variable.cmake
Normal file
@ -0,0 +1,11 @@
|
||||
macro(clear_variable)
|
||||
cmake_parse_arguments(CLEAR_VAR "" "DESTINATION;BACKUP;REPLACE" "" ${ARGN})
|
||||
set(${CLEAR_VAR_BACKUP} ${${CLEAR_VAR_DESTINATION}})
|
||||
set(${CLEAR_VAR_DESTINATION} ${CLEAR_VAR_REPLACE})
|
||||
endmacro()
|
||||
|
||||
macro(restore_variable)
|
||||
cmake_parse_arguments(CLEAR_VAR "" "DESTINATION;BACKUP" "" ${ARGN})
|
||||
set(${CLEAR_VAR_DESTINATION} ${${CLEAR_VAR_BACKUP}})
|
||||
unset(${CLEAR_VAR_BACKUP})
|
||||
endmacro()
|
29
Src/external_dependencies/cpr/cmake/code_coverage.cmake
Normal file
29
Src/external_dependencies/cpr/cmake/code_coverage.cmake
Normal file
@ -0,0 +1,29 @@
|
||||
# Code coverage
|
||||
if(CPR_BUILD_TESTS AND CPR_GENERATE_COVERAGE)
|
||||
set(CMAKE_BUILD_TYPE COVERAGE CACHE INTERNAL "Coverage enabled build")
|
||||
message(STATUS "Enabling gcov support")
|
||||
if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(COVERAGE_FLAG "--coverage")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_COVERAGE
|
||||
"-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the C++ compiler during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_C_FLAGS_COVERAGE
|
||||
"-g -O0 ${COVERAGE_FLAG} -fprofile-arcs -ftest-coverage"
|
||||
CACHE STRING "Flags used by the C compiler during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used for linking binaries during coverage builds."
|
||||
FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
|
||||
""
|
||||
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
|
||||
FORCE)
|
||||
mark_as_advanced(
|
||||
CMAKE_CXX_FLAGS_COVERAGE
|
||||
CMAKE_C_FLAGS_COVERAGE
|
||||
CMAKE_EXE_LINKER_FLAGS_COVERAGE
|
||||
CMAKE_SHARED_LINKER_FLAGS_COVERAGE)
|
||||
endif()
|
10
Src/external_dependencies/cpr/cmake/cppcheck.cmake
Normal file
10
Src/external_dependencies/cpr/cmake/cppcheck.cmake
Normal file
@ -0,0 +1,10 @@
|
||||
find_program(CMAKE_CXX_CPPCHECK NAMES cppcheck)
|
||||
if(CMAKE_CXX_CPPCHECK)
|
||||
list(APPEND CMAKE_CXX_CPPCHECK
|
||||
"--error-exitcode=1"
|
||||
"--enable=warning,style"
|
||||
"--force"
|
||||
"--inline-suppr"
|
||||
"--std=c++${CMAKE_CXX_STANDARD}"
|
||||
"--suppressions-list=${CMAKE_SOURCE_DIR}/CppCheckSuppressions.txt")
|
||||
endif()
|
8
Src/external_dependencies/cpr/cmake/cprConfig.cmake.in
Normal file
8
Src/external_dependencies/cpr/cmake/cprConfig.cmake.in
Normal file
@ -0,0 +1,8 @@
|
||||
include(CMakeFindDependencyMacro)
|
||||
@PACKAGE_INIT@
|
||||
|
||||
find_dependency(CURL REQUIRED)
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cprTargets.cmake)
|
||||
|
||||
check_required_components(cpr)
|
30
Src/external_dependencies/cpr/cmake/cprver.h.in
Normal file
30
Src/external_dependencies/cpr/cmake/cprver.h.in
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CPR_CPRVER_H
|
||||
#define CPR_CPRVER_H
|
||||
|
||||
/**
|
||||
* CPR version as a string.
|
||||
**/
|
||||
#define CPR_VERSION "${cpr_VERSION}"
|
||||
|
||||
/**
|
||||
* CPR version split up into parts.
|
||||
**/
|
||||
#define CPR_VERSION_MAJOR ${cpr_VERSION_MAJOR}
|
||||
#define CPR_VERSION_MINOR ${cpr_VERSION_MINOR}
|
||||
#define CPR_VERSION_PATCH ${cpr_VERSION_PATCH}
|
||||
|
||||
/**
|
||||
* CPR version as a single hex digit.
|
||||
* it can be split up into three parts:
|
||||
* 0xAABBCC
|
||||
* AA: The current CPR major version number in a hex format.
|
||||
* BB: The current CPR minor version number in a hex format.
|
||||
* CC: The current CPR patch version number in a hex format.
|
||||
*
|
||||
* Examples:
|
||||
* '0x010702' -> 01.07.02 -> CPR_VERSION: 1.7.2
|
||||
* '0xA13722' -> A1.37.22 -> CPR_VERSION: 161.55.34
|
||||
**/
|
||||
#define CPR_VERSION_NUM ${cpr_VERSION_NUM}
|
||||
|
||||
#endif
|
12
Src/external_dependencies/cpr/cmake/mongoose.CMakeLists.txt
Normal file
12
Src/external_dependencies/cpr/cmake/mongoose.CMakeLists.txt
Normal file
@ -0,0 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(mongoose C)
|
||||
|
||||
|
||||
add_library(mongoose STATIC mongoose.c)
|
||||
target_include_directories(mongoose PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(ENABLE_SSL_TESTS)
|
||||
# Enable mongoose SSL
|
||||
target_compile_definitions(mongoose PUBLIC MG_ENABLE_OPENSSL)
|
||||
target_link_libraries(mongoose PRIVATE OpenSSL::SSL)
|
||||
endif()
|
73
Src/external_dependencies/cpr/cmake/sanitizer.cmake
Normal file
73
Src/external_dependencies/cpr/cmake/sanitizer.cmake
Normal file
@ -0,0 +1,73 @@
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
set(ALLOWED_BUILD_TYPES Debug Release RelWithDebInfo MinSizeRel)
|
||||
set(ALL_SAN_FLAGS "")
|
||||
|
||||
# No sanitizers when cross compiling to prevent stuff like this: https://github.com/whoshuu/cpr/issues/582
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
# Thread sanitizer
|
||||
set(THREAD_SAN_FLAGS "-fsanitize=thread")
|
||||
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${THREAD_SAN_FLAGS}")
|
||||
check_cxx_source_runs("int main() { return 0; }" THREAD_SANITIZER_AVAILABLE)
|
||||
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
|
||||
if(THREAD_SANITIZER_AVAILABLE)
|
||||
list(APPEND ALLOWED_BUILD_TYPES ThreadSan)
|
||||
# Do not add Thread sanitizer to all sanitizer because it is incompatible with other sanitizer
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_THREADSAN "${CMAKE_C_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during thread sanitizer builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_THREADSAN "${CMAKE_CXX_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during thread sanitizer builds." FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_THREADSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during thread sanitizer builds" FORCE)
|
||||
|
||||
# Address sanitizer
|
||||
set(ADDR_SAN_FLAGS "-fsanitize=address")
|
||||
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${ADDR_SAN_FLAGS}")
|
||||
check_cxx_source_runs("int main() { return 0; }" ADDRESS_SANITIZER_AVAILABLE)
|
||||
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
|
||||
if(ADDRESS_SANITIZER_AVAILABLE)
|
||||
list(APPEND ALLOWED_BUILD_TYPES AddrSan)
|
||||
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${ADDR_SAN_FLAGS}")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_ADDRSAN "${CMAKE_C_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during address sanitizer builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_ADDRSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during address sanitizer builds." FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_ADDRSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during address sanitizer builds" FORCE)
|
||||
|
||||
# Leak sanitizer
|
||||
set(LEAK_SAN_FLAGS "-fsanitize=leak")
|
||||
check_cxx_compiler_flag(${LEAK_SAN_FLAGS} LEAK_SANITIZER_AVAILABLE)
|
||||
if(LEAK_SANITIZER_AVAILABLE)
|
||||
list(APPEND ALLOWED_BUILD_TYPES LeakSan)
|
||||
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${LEAK_SAN_FLAGS}")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_LEAKSAN "${CMAKE_C_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C compiler during leak sanitizer builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_LEAKSAN "${CMAKE_CXX_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C++ compiler during leak sanitizer builds." FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_LEAKSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during leak sanitizer builds" FORCE)
|
||||
|
||||
# Undefined behavior sanitizer
|
||||
set(UDEF_SAN_FLAGS "-fsanitize=undefined")
|
||||
check_cxx_compiler_flag(${UDEF_SAN_FLAGS} UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
|
||||
if(UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
|
||||
list(APPEND ALLOWED_BUILD_TYPES UdefSan)
|
||||
set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${UDEF_SAN_FLAGS}")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_UDEFSAN "${CMAKE_C_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during undefined behaviour sanitizer builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_UDEFSAN "${CMAKE_CXX_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during undefined behaviour sanitizer builds." FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_UDEFSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during undefined behaviour sanitizer builds" FORCE)
|
||||
|
||||
# All sanitizer (without thread sanitizer)
|
||||
if(NOT ALL_SAN_FLAGS STREQUAL "")
|
||||
set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
|
||||
set(CMAKE_REQUIRED_FLAGS "${ALL_SAN_FLAGS}")
|
||||
check_cxx_source_runs("int main() { return 0; }" ALL_SANITIZERS_AVAILABLE)
|
||||
set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
|
||||
if(ALL_SANITIZERS_AVAILABLE)
|
||||
list(APPEND ALLOWED_BUILD_TYPES AllSan)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS_ALLSAN "${CMAKE_C_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during most possible sanitizer builds." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_ALLSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during most possible sanitizer builds." FORCE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_ALLSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during most possible sanitizer builds" FORCE)
|
||||
endif()
|
22
Src/external_dependencies/cpr/cmake/zlib_external.cmake
Normal file
22
Src/external_dependencies/cpr/cmake/zlib_external.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
# ZLIB
|
||||
|
||||
# Fix Windows missing "zlib.dll":
|
||||
if(WIN32 AND (${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}))
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}/$<CONFIG> CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
set(ZLIB_COMPAT ON CACHE INTERNAL "" FORCE)
|
||||
set(ZLIB_ENABLE_TESTS OFF CACHE INTERNAL "" FORCE)
|
||||
|
||||
FetchContent_Declare(zlib
|
||||
GIT_REPOSITORY https://github.com/zlib-ng/zlib-ng
|
||||
GIT_TAG 2.0.6
|
||||
USES_TERMINAL_DOWNLOAD TRUE)
|
||||
FetchContent_MakeAvailable(zlib)
|
||||
|
||||
# Fix Windows zlib dll names from "zlibd1.dll" to "zlib.dll":
|
||||
if(WIN32)
|
||||
set_target_properties(zlib PROPERTIES OUTPUT_NAME "zlib")
|
||||
set_target_properties(zlib PROPERTIES DEBUG_POSTFIX "")
|
||||
set_target_properties(zlib PROPERTIES SUFFIX ".dll")
|
||||
endif()
|
26
Src/external_dependencies/cpr/cpr-config.cmake
Normal file
26
Src/external_dependencies/cpr/cpr-config.cmake
Normal file
@ -0,0 +1,26 @@
|
||||
# - C++ Requests, Curl for People
|
||||
# This module is a libcurl wrapper written in modern C++.
|
||||
# It provides an easy, intuitive, and efficient interface to
|
||||
# a host of networking methods.
|
||||
#
|
||||
# Finding this module will define the following variables:
|
||||
# CPR_FOUND - True if the core library has been found
|
||||
# CPR_LIBRARIES - Path to the core library archive
|
||||
# CPR_INCLUDE_DIRS - Path to the include directories. Gives access
|
||||
# to cpr.h, which must be included in every
|
||||
# file that uses this interface
|
||||
|
||||
find_path(CPR_INCLUDE_DIR
|
||||
NAMES cpr.h)
|
||||
|
||||
find_library(CPR_LIBRARY
|
||||
NAMES cpr
|
||||
HINTS ${CPR_LIBRARY_ROOT})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(CPR REQUIRED_VARS CPR_LIBRARY CPR_INCLUDE_DIR)
|
||||
|
||||
if(CPR_FOUND)
|
||||
set(CPR_LIBRARIES ${CPR_LIBRARY})
|
||||
set(CPR_INCLUDE_DIRS ${CPR_INCLUDE_DIR})
|
||||
endif()
|
84
Src/external_dependencies/cpr/cpr/CMakeLists.txt
Normal file
84
Src/external_dependencies/cpr/cpr/CMakeLists.txt
Normal file
@ -0,0 +1,84 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
add_library(cpr
|
||||
accept_encoding.cpp
|
||||
async.cpp
|
||||
auth.cpp
|
||||
bearer.cpp
|
||||
cert_info.cpp
|
||||
cookies.cpp
|
||||
cprtypes.cpp
|
||||
curl_container.cpp
|
||||
curlholder.cpp
|
||||
error.cpp
|
||||
file.cpp
|
||||
multipart.cpp
|
||||
parameters.cpp
|
||||
payload.cpp
|
||||
proxies.cpp
|
||||
proxyauth.cpp
|
||||
session.cpp
|
||||
threadpool.cpp
|
||||
timeout.cpp
|
||||
unix_socket.cpp
|
||||
util.cpp
|
||||
response.cpp
|
||||
redirect.cpp
|
||||
interceptor.cpp
|
||||
ssl_ctx.cpp
|
||||
curlmultiholder.cpp
|
||||
multiperform.cpp)
|
||||
|
||||
add_library(cpr::cpr ALIAS cpr)
|
||||
|
||||
target_link_libraries(cpr PUBLIC CURL::libcurl) # todo should be private, but first dependencys in ssl_options need to be removed
|
||||
|
||||
# Fix missing OpenSSL includes for Windows since in 'ssl_ctx.cpp' we include OpenSSL directly
|
||||
if(SSL_BACKEND_USED STREQUAL "OpenSSL")
|
||||
target_link_libraries(cpr PRIVATE OpenSSL::SSL)
|
||||
target_include_directories(cpr PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
# Set version for shared libraries.
|
||||
set_target_properties(cpr
|
||||
PROPERTIES
|
||||
VERSION ${${PROJECT_NAME}_VERSION}
|
||||
SOVERSION ${${PROJECT_NAME}_VERSION_MAJOR})
|
||||
|
||||
# Import GNU common install directory variables
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(CPR_USE_SYSTEM_CURL)
|
||||
install(TARGETS cpr
|
||||
EXPORT cprTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
# Include CMake helpers for package config files
|
||||
# Follow this installation guideline: https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_BINARY_DIR}/cpr/cprConfigVersion.cmake"
|
||||
VERSION ${${PROJECT_NAME}_VERSION}
|
||||
COMPATIBILITY ExactVersion)
|
||||
|
||||
configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/cprConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/cpr/cprConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpr)
|
||||
|
||||
install(EXPORT cprTargets
|
||||
FILE cprTargets.cmake
|
||||
NAMESPACE cpr::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpr)
|
||||
|
||||
install(FILES ${PROJECT_BINARY_DIR}/cpr/cprConfig.cmake
|
||||
${PROJECT_BINARY_DIR}/cpr/cprConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/cpr)
|
||||
|
||||
else()
|
||||
install(TARGETS cpr
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
25
Src/external_dependencies/cpr/cpr/accept_encoding.cpp
Normal file
25
Src/external_dependencies/cpr/cpr/accept_encoding.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "cpr/accept_encoding.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <numeric>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
AcceptEncoding::AcceptEncoding(const std::initializer_list<AcceptEncodingMethods>& methods) {
|
||||
methods_.clear();
|
||||
std::transform(methods.begin(), methods.end(), std::back_inserter(methods_), [&](cpr::AcceptEncodingMethods method) { return cpr::AcceptEncodingMethodsStringMap.at(method); });
|
||||
}
|
||||
|
||||
AcceptEncoding::AcceptEncoding(const std::initializer_list<std::string>& string_methods) : methods_{string_methods} {}
|
||||
|
||||
bool AcceptEncoding::empty() const noexcept {
|
||||
return methods_.empty();
|
||||
}
|
||||
|
||||
const std::string AcceptEncoding::getString() const {
|
||||
std::string methodsString = std::accumulate(std::next(methods_.begin()), methods_.end(), methods_[0], [](std::string a, std::string b) { return std::move(a) + ", " + std::move(b); });
|
||||
return methodsString;
|
||||
}
|
||||
|
||||
} // namespace cpr
|
8
Src/external_dependencies/cpr/cpr/async.cpp
Normal file
8
Src/external_dependencies/cpr/cpr/async.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
#include "cpr/async.h"
|
||||
|
||||
namespace cpr {
|
||||
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-avoid-non-const-global-variables)
|
||||
CPR_SINGLETON_IMPL(GlobalThreadPool)
|
||||
|
||||
} // namespace cpr
|
16
Src/external_dependencies/cpr/cpr/auth.cpp
Normal file
16
Src/external_dependencies/cpr/cpr/auth.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "cpr/auth.h"
|
||||
#include "cpr/util.h"
|
||||
|
||||
namespace cpr {
|
||||
Authentication::~Authentication() noexcept {
|
||||
util::secureStringClear(auth_string_);
|
||||
}
|
||||
|
||||
const char* Authentication::GetAuthString() const noexcept {
|
||||
return auth_string_.c_str();
|
||||
}
|
||||
|
||||
AuthMode Authentication::GetAuthMode() const noexcept {
|
||||
return auth_mode_;
|
||||
}
|
||||
} // namespace cpr
|
16
Src/external_dependencies/cpr/cpr/bearer.cpp
Normal file
16
Src/external_dependencies/cpr/cpr/bearer.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include "cpr/bearer.h"
|
||||
#include "cpr/util.h"
|
||||
|
||||
namespace cpr {
|
||||
// Only supported with libcurl >= 7.61.0.
|
||||
// As an alternative use SetHeader and add the token manually.
|
||||
#if LIBCURL_VERSION_NUM >= 0x073D00
|
||||
Bearer::~Bearer() noexcept {
|
||||
util::secureStringClear(token_string_);
|
||||
}
|
||||
|
||||
const char* Bearer::GetToken() const noexcept {
|
||||
return token_string_.c_str();
|
||||
}
|
||||
#endif
|
||||
} // namespace cpr
|
43
Src/external_dependencies/cpr/cpr/cert_info.cpp
Normal file
43
Src/external_dependencies/cpr/cpr/cert_info.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
#include "cpr/cert_info.h"
|
||||
|
||||
namespace cpr {
|
||||
|
||||
std::string& CertInfo::operator[](const size_t& pos) {
|
||||
return cert_info_[pos];
|
||||
}
|
||||
|
||||
CertInfo::iterator CertInfo::begin() {
|
||||
return cert_info_.begin();
|
||||
}
|
||||
CertInfo::iterator CertInfo::end() {
|
||||
return cert_info_.end();
|
||||
}
|
||||
|
||||
CertInfo::const_iterator CertInfo::begin() const {
|
||||
return cert_info_.begin();
|
||||
}
|
||||
|
||||
CertInfo::const_iterator CertInfo::end() const {
|
||||
return cert_info_.end();
|
||||
}
|
||||
|
||||
CertInfo::const_iterator CertInfo::cbegin() const {
|
||||
return cert_info_.cbegin();
|
||||
}
|
||||
|
||||
CertInfo::const_iterator CertInfo::cend() const {
|
||||
return cert_info_.cend();
|
||||
}
|
||||
|
||||
void CertInfo::emplace_back(const std::string& str) {
|
||||
cert_info_.emplace_back(str);
|
||||
}
|
||||
|
||||
void CertInfo::push_back(const std::string& str) {
|
||||
cert_info_.push_back(str);
|
||||
}
|
||||
|
||||
void CertInfo::pop_back() {
|
||||
cert_info_.pop_back();
|
||||
}
|
||||
} // namespace cpr
|
106
Src/external_dependencies/cpr/cpr/cookies.cpp
Normal file
106
Src/external_dependencies/cpr/cpr/cookies.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
#include "cpr/cookies.h"
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
||||
namespace cpr {
|
||||
const std::string Cookie::GetDomain() const {
|
||||
return domain_;
|
||||
}
|
||||
|
||||
bool Cookie::IsIncludingSubdomains() const {
|
||||
return includeSubdomains_;
|
||||
}
|
||||
|
||||
const std::string Cookie::GetPath() const {
|
||||
return path_;
|
||||
}
|
||||
|
||||
bool Cookie::IsHttpsOnly() const {
|
||||
return httpsOnly_;
|
||||
}
|
||||
|
||||
const std::chrono::system_clock::time_point Cookie::GetExpires() const {
|
||||
return expires_;
|
||||
}
|
||||
|
||||
const std::string Cookie::GetExpiresString() const {
|
||||
std::stringstream ss;
|
||||
std::tm tm{};
|
||||
std::time_t tt = std::chrono::system_clock::to_time_t(expires_);
|
||||
#ifdef _WIN32
|
||||
gmtime_s(&tm, &tt);
|
||||
#else
|
||||
gmtime_r(&tt, &tm);
|
||||
#endif
|
||||
ss << std::put_time(&tm, "%a, %d %b %Y %H:%M:%S GMT");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
const std::string Cookie::GetName() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
const std::string Cookie::GetValue() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
const std::string Cookies::GetEncoded(const CurlHolder& holder) const {
|
||||
std::stringstream stream;
|
||||
for (const cpr::Cookie& item : cookies_) {
|
||||
// Depending on if encoding is set to "true", we will URL-encode cookies
|
||||
stream << (encode ? holder.urlEncode(item.GetName()) : item.GetName()) << "=";
|
||||
|
||||
// special case version 1 cookies, which can be distinguished by
|
||||
// beginning and trailing quotes
|
||||
if (!item.GetValue().empty() && item.GetValue().front() == '"' && item.GetValue().back() == '"') {
|
||||
stream << item.GetValue();
|
||||
} else {
|
||||
// Depending on if encoding is set to "true", we will URL-encode cookies
|
||||
stream << (encode ? holder.urlEncode(item.GetValue()) : item.GetValue());
|
||||
}
|
||||
stream << "; ";
|
||||
}
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
cpr::Cookie& Cookies::operator[](size_t pos) {
|
||||
return cookies_[pos];
|
||||
}
|
||||
|
||||
Cookies::iterator Cookies::begin() {
|
||||
return cookies_.begin();
|
||||
}
|
||||
|
||||
Cookies::iterator Cookies::end() {
|
||||
return cookies_.end();
|
||||
}
|
||||
|
||||
Cookies::const_iterator Cookies::begin() const {
|
||||
return cookies_.begin();
|
||||
}
|
||||
|
||||
Cookies::const_iterator Cookies::end() const {
|
||||
return cookies_.end();
|
||||
}
|
||||
|
||||
Cookies::const_iterator Cookies::cbegin() const {
|
||||
return cookies_.cbegin();
|
||||
}
|
||||
|
||||
Cookies::const_iterator Cookies::cend() const {
|
||||
return cookies_.cend();
|
||||
}
|
||||
|
||||
void Cookies::emplace_back(const Cookie& str) {
|
||||
cookies_.emplace_back(str);
|
||||
}
|
||||
|
||||
void Cookies::push_back(const Cookie& str) {
|
||||
cookies_.push_back(str);
|
||||
}
|
||||
|
||||
void Cookies::pop_back() {
|
||||
cookies_.pop_back();
|
||||
}
|
||||
|
||||
} // namespace cpr
|
10
Src/external_dependencies/cpr/cpr/cprtypes.cpp
Normal file
10
Src/external_dependencies/cpr/cpr/cprtypes.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "cpr/cprtypes.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
namespace cpr {
|
||||
bool CaseInsensitiveCompare::operator()(const std::string& a, const std::string& b) const noexcept {
|
||||
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), [](unsigned char ac, unsigned char bc) { return std::tolower(ac) < std::tolower(bc); });
|
||||
}
|
||||
} // namespace cpr
|
58
Src/external_dependencies/cpr/cpr/curl_container.cpp
Normal file
58
Src/external_dependencies/cpr/cpr/curl_container.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "cpr/curl_container.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
|
||||
namespace cpr {
|
||||
template <class T>
|
||||
CurlContainer<T>::CurlContainer(const std::initializer_list<T>& containerList) : containerList_(containerList) {}
|
||||
|
||||
template <class T>
|
||||
void CurlContainer<T>::Add(const std::initializer_list<T>& containerList) {
|
||||
std::transform(containerList.begin(), containerList.end(), std::back_inserter(containerList_), [](const T& elem) { return std::move(elem); });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void CurlContainer<T>::Add(const T& element) {
|
||||
containerList_.push_back(std::move(element));
|
||||
}
|
||||
|
||||
template <>
|
||||
const std::string CurlContainer<Parameter>::GetContent(const CurlHolder& holder) const {
|
||||
std::string content{};
|
||||
for (const Parameter& parameter : containerList_) {
|
||||
if (!content.empty()) {
|
||||
content += "&";
|
||||
}
|
||||
|
||||
std::string escapedKey = encode ? holder.urlEncode(parameter.key) : parameter.key;
|
||||
if (parameter.value.empty()) {
|
||||
content += escapedKey;
|
||||
} else {
|
||||
std::string escapedValue = encode ? holder.urlEncode(parameter.value) : parameter.value;
|
||||
content += escapedKey + "=";
|
||||
content += escapedValue;
|
||||
}
|
||||
};
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
template <>
|
||||
const std::string CurlContainer<Pair>::GetContent(const CurlHolder& holder) const {
|
||||
std::string content{};
|
||||
for (const cpr::Pair& element : containerList_) {
|
||||
if (!content.empty()) {
|
||||
content += "&";
|
||||
}
|
||||
std::string escaped = encode ? holder.urlEncode(element.value) : element.value;
|
||||
content += element.key + "=" + escaped;
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
template class CurlContainer<Pair>;
|
||||
template class CurlContainer<Parameter>;
|
||||
|
||||
} // namespace cpr
|
49
Src/external_dependencies/cpr/cpr/curlholder.cpp
Normal file
49
Src/external_dependencies/cpr/cpr/curlholder.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "cpr/curlholder.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace cpr {
|
||||
CurlHolder::CurlHolder() {
|
||||
/**
|
||||
* Allow multithreaded access to CPR by locking curl_easy_init().
|
||||
* curl_easy_init() is not thread safe.
|
||||
* References:
|
||||
* https://curl.haxx.se/libcurl/c/curl_easy_init.html
|
||||
* https://curl.haxx.se/libcurl/c/threadsafe.html
|
||||
**/
|
||||
curl_easy_init_mutex_().lock();
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-prefer-member-initializer) since we need it to happen inside the lock
|
||||
handle = curl_easy_init();
|
||||
curl_easy_init_mutex_().unlock();
|
||||
|
||||
assert(handle);
|
||||
} // namespace cpr
|
||||
|
||||
CurlHolder::~CurlHolder() {
|
||||
curl_slist_free_all(chunk);
|
||||
curl_slist_free_all(resolveCurlList);
|
||||
curl_formfree(formpost);
|
||||
curl_easy_cleanup(handle);
|
||||
}
|
||||
|
||||
std::string CurlHolder::urlEncode(const std::string& s) const {
|
||||
assert(handle);
|
||||
char* output = curl_easy_escape(handle, s.c_str(), static_cast<int>(s.length()));
|
||||
if (output) {
|
||||
std::string result = output;
|
||||
curl_free(output);
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string CurlHolder::urlDecode(const std::string& s) const {
|
||||
assert(handle);
|
||||
char* output = curl_easy_unescape(handle, s.c_str(), static_cast<int>(s.length()), nullptr);
|
||||
if (output) {
|
||||
std::string result = output;
|
||||
curl_free(output);
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
} // namespace cpr
|
15
Src/external_dependencies/cpr/cpr/curlmultiholder.cpp
Normal file
15
Src/external_dependencies/cpr/cpr/curlmultiholder.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include "cpr/curlmultiholder.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
CurlMultiHolder::CurlMultiHolder() : handle{curl_multi_init()} {
|
||||
assert(handle);
|
||||
}
|
||||
|
||||
CurlMultiHolder::~CurlMultiHolder() {
|
||||
curl_multi_cleanup(handle);
|
||||
}
|
||||
|
||||
} // namespace cpr
|
68
Src/external_dependencies/cpr/cpr/error.cpp
Normal file
68
Src/external_dependencies/cpr/cpr/error.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "cpr/error.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
namespace cpr {
|
||||
ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) {
|
||||
switch (curl_code) {
|
||||
case CURLE_OK:
|
||||
return ErrorCode::OK;
|
||||
case CURLE_UNSUPPORTED_PROTOCOL:
|
||||
return ErrorCode::UNSUPPORTED_PROTOCOL;
|
||||
case CURLE_URL_MALFORMAT:
|
||||
return ErrorCode::INVALID_URL_FORMAT;
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
return ErrorCode::PROXY_RESOLUTION_FAILURE;
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
return ErrorCode::HOST_RESOLUTION_FAILURE;
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
return ErrorCode::CONNECTION_FAILURE;
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
return ErrorCode::OPERATION_TIMEDOUT;
|
||||
case CURLE_SSL_CONNECT_ERROR:
|
||||
return ErrorCode::SSL_CONNECT_ERROR;
|
||||
#if LIBCURL_VERSION_NUM < 0x073e00
|
||||
case CURLE_PEER_FAILED_VERIFICATION:
|
||||
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
|
||||
#endif
|
||||
case CURLE_ABORTED_BY_CALLBACK:
|
||||
case CURLE_WRITE_ERROR:
|
||||
return ErrorCode::REQUEST_CANCELLED;
|
||||
case CURLE_GOT_NOTHING:
|
||||
return ErrorCode::EMPTY_RESPONSE;
|
||||
case CURLE_SSL_ENGINE_NOTFOUND:
|
||||
case CURLE_SSL_ENGINE_SETFAILED:
|
||||
return ErrorCode::GENERIC_SSL_ERROR;
|
||||
case CURLE_SEND_ERROR:
|
||||
return ErrorCode::NETWORK_SEND_FAILURE;
|
||||
case CURLE_RECV_ERROR:
|
||||
return ErrorCode::NETWORK_RECEIVE_ERROR;
|
||||
case CURLE_SSL_CERTPROBLEM:
|
||||
return ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR;
|
||||
case CURLE_SSL_CIPHER:
|
||||
return ErrorCode::GENERIC_SSL_ERROR;
|
||||
#if LIBCURL_VERSION_NUM >= 0x073e00
|
||||
case CURLE_PEER_FAILED_VERIFICATION:
|
||||
return ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR;
|
||||
#else
|
||||
case CURLE_SSL_CACERT:
|
||||
return ErrorCode::SSL_CACERT_ERROR;
|
||||
#endif
|
||||
case CURLE_USE_SSL_FAILED:
|
||||
case CURLE_SSL_ENGINE_INITFAILED:
|
||||
return ErrorCode::GENERIC_SSL_ERROR;
|
||||
case CURLE_SSL_CACERT_BADFILE:
|
||||
return ErrorCode::SSL_CACERT_ERROR;
|
||||
case CURLE_SSL_SHUTDOWN_FAILED:
|
||||
return ErrorCode::GENERIC_SSL_ERROR;
|
||||
case CURLE_SSL_CRL_BADFILE:
|
||||
case CURLE_SSL_ISSUER_ERROR:
|
||||
return ErrorCode::SSL_CACERT_ERROR;
|
||||
case CURLE_TOO_MANY_REDIRECTS:
|
||||
return ErrorCode::TOO_MANY_REDIRECTS;
|
||||
default:
|
||||
return ErrorCode::INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cpr
|
40
Src/external_dependencies/cpr/cpr/file.cpp
Normal file
40
Src/external_dependencies/cpr/cpr/file.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "cpr/file.h"
|
||||
|
||||
namespace cpr {
|
||||
|
||||
Files::iterator Files::begin() {
|
||||
return files.begin();
|
||||
}
|
||||
|
||||
Files::iterator Files::end() {
|
||||
return files.end();
|
||||
}
|
||||
|
||||
Files::const_iterator Files::begin() const {
|
||||
return files.begin();
|
||||
}
|
||||
|
||||
Files::const_iterator Files::end() const {
|
||||
return files.end();
|
||||
}
|
||||
|
||||
Files::const_iterator Files::cbegin() const {
|
||||
return files.cbegin();
|
||||
}
|
||||
|
||||
Files::const_iterator Files::cend() const {
|
||||
return files.cend();
|
||||
}
|
||||
|
||||
void Files::emplace_back(const File& file) {
|
||||
files.emplace_back(file);
|
||||
}
|
||||
|
||||
void Files::push_back(const File& file) {
|
||||
files.push_back(file);
|
||||
}
|
||||
|
||||
void Files::pop_back() {
|
||||
files.pop_back();
|
||||
}
|
||||
} // namespace cpr
|
46
Src/external_dependencies/cpr/cpr/interceptor.cpp
Normal file
46
Src/external_dependencies/cpr/cpr/interceptor.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "cpr/interceptor.h"
|
||||
|
||||
#include <exception>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
Response Interceptor::proceed(Session& session) {
|
||||
return session.proceed();
|
||||
}
|
||||
|
||||
Response Interceptor::proceed(Session& session, ProceedHttpMethod httpMethod) {
|
||||
switch (httpMethod) {
|
||||
case ProceedHttpMethod::DELETE_REQUEST:
|
||||
return session.Delete();
|
||||
case ProceedHttpMethod::GET_REQUEST:
|
||||
return session.Get();
|
||||
case ProceedHttpMethod::HEAD_REQUEST:
|
||||
return session.Head();
|
||||
case ProceedHttpMethod::OPTIONS_REQUEST:
|
||||
return session.Options();
|
||||
case ProceedHttpMethod::PATCH_REQUEST:
|
||||
return session.Patch();
|
||||
case ProceedHttpMethod::POST_REQUEST:
|
||||
return session.Post();
|
||||
case ProceedHttpMethod::PUT_REQUEST:
|
||||
return session.Put();
|
||||
default:
|
||||
throw std::invalid_argument{"Can't procceed the session with the provided http method!"};
|
||||
}
|
||||
}
|
||||
|
||||
Response Interceptor::proceed(Session& session, ProceedHttpMethod httpMethod, std::ofstream& file) {
|
||||
if (httpMethod == ProceedHttpMethod::DOWNLOAD_FILE_REQUEST) {
|
||||
return session.Download(file);
|
||||
}
|
||||
throw std::invalid_argument{"std::ofstream argument is only valid for ProceedHttpMethod::DOWNLOAD_FILE!"};
|
||||
}
|
||||
|
||||
Response Interceptor::proceed(Session& session, ProceedHttpMethod httpMethod, const WriteCallback& write) {
|
||||
if (httpMethod == ProceedHttpMethod::DOWNLOAD_CALLBACK_REQUEST) {
|
||||
return session.Download(write);
|
||||
}
|
||||
throw std::invalid_argument{"WriteCallback argument is only valid for ProceedHttpMethod::DOWNLOAD_CALLBACK!"};
|
||||
}
|
||||
|
||||
} // namespace cpr
|
5
Src/external_dependencies/cpr/cpr/multipart.cpp
Normal file
5
Src/external_dependencies/cpr/cpr/multipart.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "cpr/multipart.h"
|
||||
|
||||
namespace cpr {
|
||||
Multipart::Multipart(const std::initializer_list<Part>& p_parts) : parts{p_parts} {}
|
||||
} // namespace cpr
|
273
Src/external_dependencies/cpr/cpr/multiperform.cpp
Normal file
273
Src/external_dependencies/cpr/cpr/multiperform.cpp
Normal file
@ -0,0 +1,273 @@
|
||||
#include "cpr/multiperform.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
MultiPerform::MultiPerform() : multicurl_(new CurlMultiHolder()) {}
|
||||
|
||||
MultiPerform::~MultiPerform() {
|
||||
// Unock all sessions
|
||||
for (std::pair<std::shared_ptr<Session>, HttpMethod>& pair : sessions_) {
|
||||
pair.first->isUsedInMultiPerform = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::AddSession(std::shared_ptr<Session>& session, HttpMethod method) {
|
||||
// Check if this multiperform is download only
|
||||
if (((method != HttpMethod::DOWNLOAD_REQUEST && is_download_multi_perform) && method != HttpMethod::UNDEFINED) || (method == HttpMethod::DOWNLOAD_REQUEST && !is_download_multi_perform && !sessions_.empty())) {
|
||||
// Currently it is not possible to mix download and non-download methods, as download needs additional parameters
|
||||
throw std::invalid_argument("Failed to add session: Cannot mix download and non-download methods!");
|
||||
}
|
||||
|
||||
// Set download only if neccessary
|
||||
if (method == HttpMethod::DOWNLOAD_REQUEST) {
|
||||
is_download_multi_perform = true;
|
||||
}
|
||||
|
||||
// Add easy handle to multi handle
|
||||
CURLMcode error_code = curl_multi_add_handle(multicurl_->handle, session->curl_->handle);
|
||||
if (error_code) {
|
||||
std::cerr << "curl_multi_add_handle() failed, code " << static_cast<int>(error_code) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Lock session to the multihandle
|
||||
session->isUsedInMultiPerform = true;
|
||||
|
||||
// Add session to sessions_
|
||||
sessions_.emplace_back(session, method);
|
||||
}
|
||||
|
||||
void MultiPerform::RemoveSession(const std::shared_ptr<Session>& session) {
|
||||
// Remove easy handle from multihandle
|
||||
CURLMcode error_code = curl_multi_remove_handle(multicurl_->handle, session->curl_->handle);
|
||||
if (error_code) {
|
||||
std::cerr << "curl_multi_remove_handle() failed, code " << static_cast<int>(error_code) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Unock session
|
||||
session->isUsedInMultiPerform = false;
|
||||
|
||||
// Remove session from sessions_
|
||||
auto it = std::find_if(sessions_.begin(), sessions_.end(), [&session](const std::pair<std::shared_ptr<Session>, HttpMethod>& pair) { return session->curl_->handle == pair.first->curl_->handle; });
|
||||
if (it == sessions_.end()) {
|
||||
throw std::invalid_argument("Failed to find session!");
|
||||
}
|
||||
sessions_.erase(it);
|
||||
|
||||
// Reset download only if empty
|
||||
if (sessions_.empty()) {
|
||||
is_download_multi_perform = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::DoMultiPerform() {
|
||||
// Do multi perform until every handle has finished
|
||||
int still_running{0};
|
||||
do {
|
||||
CURLMcode error_code = curl_multi_perform(multicurl_->handle, &still_running);
|
||||
if (error_code) {
|
||||
std::cerr << "curl_multi_perform() failed, code " << static_cast<int>(error_code) << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
if (still_running) {
|
||||
const int timeout_ms{250};
|
||||
error_code = curl_multi_poll(multicurl_->handle, nullptr, 0, timeout_ms, nullptr);
|
||||
if (error_code) {
|
||||
std::cerr << "curl_multi_poll() failed, code " << static_cast<int>(error_code) << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (still_running);
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::ReadMultiInfo(std::function<Response(Session&, CURLcode)>&& complete_function) {
|
||||
// Get infos and create Response objects
|
||||
std::vector<Response> responses;
|
||||
struct CURLMsg* info{nullptr};
|
||||
do {
|
||||
int msgq = 0;
|
||||
|
||||
// Read info from multihandle
|
||||
info = curl_multi_info_read(multicurl_->handle, &msgq);
|
||||
|
||||
if (info) {
|
||||
// Find current session
|
||||
auto it = std::find_if(sessions_.begin(), sessions_.end(), [&info](const std::pair<std::shared_ptr<Session>, HttpMethod>& pair) { return pair.first->curl_->handle == info->easy_handle; });
|
||||
if (it == sessions_.end()) {
|
||||
std::cerr << "Failed to find current session!" << std::endl;
|
||||
break;
|
||||
}
|
||||
std::shared_ptr<Session> current_session = (*it).first;
|
||||
|
||||
// Add response object
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-pro-type-union-access)
|
||||
responses.push_back(complete_function(*current_session, info->data.result));
|
||||
}
|
||||
} while (info);
|
||||
|
||||
// Sort response objects to match order of added sessions
|
||||
std::vector<Response> sorted_responses;
|
||||
for (std::pair<std::shared_ptr<Session>, HttpMethod>& pair : sessions_) {
|
||||
Session& current_session = *(pair.first);
|
||||
auto it = std::find_if(responses.begin(), responses.end(), [¤t_session](const Response& response) { return current_session.curl_->handle == response.curl_->handle; });
|
||||
Response current_response = *it;
|
||||
// Erase response from original vector to increase future search speed
|
||||
responses.erase(it);
|
||||
sorted_responses.push_back(current_response);
|
||||
}
|
||||
|
||||
return sorted_responses;
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::MakeRequest() {
|
||||
DoMultiPerform();
|
||||
return ReadMultiInfo([](Session& session, CURLcode curl_error) -> Response { return session.Complete(curl_error); });
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::MakeDownloadRequest() {
|
||||
DoMultiPerform();
|
||||
return ReadMultiInfo([](Session& session, CURLcode curl_error) -> Response { return session.CompleteDownload(curl_error); });
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareSessions() {
|
||||
for (std::pair<std::shared_ptr<Session>, HttpMethod>& pair : sessions_) {
|
||||
switch (pair.second) {
|
||||
case HttpMethod::GET_REQUEST:
|
||||
pair.first->PrepareGet();
|
||||
break;
|
||||
case HttpMethod::POST_REQUEST:
|
||||
pair.first->PreparePost();
|
||||
break;
|
||||
case HttpMethod::PUT_REQUEST:
|
||||
pair.first->PreparePut();
|
||||
break;
|
||||
case HttpMethod::DELETE_REQUEST:
|
||||
pair.first->PrepareDelete();
|
||||
break;
|
||||
case HttpMethod::PATCH_REQUEST:
|
||||
pair.first->PreparePatch();
|
||||
break;
|
||||
case HttpMethod::HEAD_REQUEST:
|
||||
pair.first->PrepareHead();
|
||||
break;
|
||||
case HttpMethod::OPTIONS_REQUEST:
|
||||
pair.first->PrepareOptions();
|
||||
break;
|
||||
default:
|
||||
std::cerr << "PrepareSessions failed: Undefined HttpMethod or download without arguments!" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareDownloadSession(size_t sessions_index, const WriteCallback& write) {
|
||||
std::pair<std::shared_ptr<Session>, HttpMethod>& pair = sessions_[sessions_index];
|
||||
switch (pair.second) {
|
||||
case HttpMethod::DOWNLOAD_REQUEST:
|
||||
pair.first->PrepareDownload(write);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "PrepareSessions failed: Undefined HttpMethod or non download method with arguments!" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareDownloadSession(size_t sessions_index, std::ofstream& file) {
|
||||
std::pair<std::shared_ptr<Session>, HttpMethod>& pair = sessions_[sessions_index];
|
||||
switch (pair.second) {
|
||||
case HttpMethod::DOWNLOAD_REQUEST:
|
||||
pair.first->PrepareDownload(file);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "PrepareSessions failed: Undefined HttpMethod or non download method with arguments!" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::SetHttpMethod(HttpMethod method) {
|
||||
for (std::pair<std::shared_ptr<Session>, HttpMethod>& pair : sessions_) {
|
||||
pair.second = method;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareGet() {
|
||||
SetHttpMethod(HttpMethod::GET_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareDelete() {
|
||||
SetHttpMethod(HttpMethod::DELETE_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PreparePut() {
|
||||
SetHttpMethod(HttpMethod::PUT_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PreparePatch() {
|
||||
SetHttpMethod(HttpMethod::PATCH_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareHead() {
|
||||
SetHttpMethod(HttpMethod::HEAD_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PrepareOptions() {
|
||||
SetHttpMethod(HttpMethod::OPTIONS_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
void MultiPerform::PreparePost() {
|
||||
SetHttpMethod(HttpMethod::POST_REQUEST);
|
||||
PrepareSessions();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Get() {
|
||||
PrepareGet();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Delete() {
|
||||
PrepareDelete();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Put() {
|
||||
PreparePut();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Head() {
|
||||
PrepareHead();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Options() {
|
||||
PrepareOptions();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Patch() {
|
||||
PreparePatch();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Post() {
|
||||
PreparePost();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
std::vector<Response> MultiPerform::Perform() {
|
||||
PrepareSessions();
|
||||
return MakeRequest();
|
||||
}
|
||||
|
||||
} // namespace cpr
|
10
Src/external_dependencies/cpr/cpr/parameters.cpp
Normal file
10
Src/external_dependencies/cpr/cpr/parameters.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "cpr/parameters.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
|
||||
#include "cpr/util.h"
|
||||
|
||||
namespace cpr {
|
||||
Parameters::Parameters(const std::initializer_list<Parameter>& parameters) : CurlContainer<Parameter>(parameters) {}
|
||||
} // namespace cpr
|
10
Src/external_dependencies/cpr/cpr/payload.cpp
Normal file
10
Src/external_dependencies/cpr/cpr/payload.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include "cpr/payload.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <string>
|
||||
|
||||
#include "cpr/util.h"
|
||||
|
||||
namespace cpr {
|
||||
Payload::Payload(const std::initializer_list<Pair>& pairs) : CurlContainer<Pair>(pairs) {}
|
||||
} // namespace cpr
|
21
Src/external_dependencies/cpr/cpr/proxies.cpp
Normal file
21
Src/external_dependencies/cpr/cpr/proxies.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "cpr/proxies.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
Proxies::Proxies(const std::initializer_list<std::pair<const std::string, std::string>>& hosts) : hosts_{hosts} {}
|
||||
Proxies::Proxies(const std::map<std::string, std::string>& hosts) : hosts_{hosts} {}
|
||||
|
||||
bool Proxies::has(const std::string& protocol) const {
|
||||
return hosts_.count(protocol) > 0;
|
||||
}
|
||||
|
||||
const std::string& Proxies::operator[](const std::string& protocol) {
|
||||
return hosts_[protocol];
|
||||
}
|
||||
|
||||
} // namespace cpr
|
21
Src/external_dependencies/cpr/cpr/proxyauth.cpp
Normal file
21
Src/external_dependencies/cpr/cpr/proxyauth.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include "cpr/proxyauth.h"
|
||||
#include "cpr/util.h"
|
||||
|
||||
namespace cpr {
|
||||
EncodedAuthentication::~EncodedAuthentication() noexcept {
|
||||
util::secureStringClear(auth_string_);
|
||||
}
|
||||
|
||||
const char* EncodedAuthentication::GetAuthString() const noexcept {
|
||||
return auth_string_.c_str();
|
||||
}
|
||||
|
||||
bool ProxyAuthentication::has(const std::string& protocol) const {
|
||||
return proxyAuth_.count(protocol) > 0;
|
||||
}
|
||||
|
||||
const char* ProxyAuthentication::operator[](const std::string& protocol) {
|
||||
return proxyAuth_[protocol].GetAuthString();
|
||||
}
|
||||
|
||||
} // namespace cpr
|
40
Src/external_dependencies/cpr/cpr/redirect.cpp
Normal file
40
Src/external_dependencies/cpr/cpr/redirect.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "cpr/redirect.h"
|
||||
|
||||
namespace cpr {
|
||||
PostRedirectFlags operator|(PostRedirectFlags lhs, PostRedirectFlags rhs) {
|
||||
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
|
||||
}
|
||||
|
||||
PostRedirectFlags operator&(PostRedirectFlags lhs, PostRedirectFlags rhs) {
|
||||
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
|
||||
}
|
||||
|
||||
PostRedirectFlags operator^(PostRedirectFlags lhs, PostRedirectFlags rhs) {
|
||||
return static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) ^ static_cast<uint8_t>(rhs));
|
||||
}
|
||||
|
||||
PostRedirectFlags operator~(PostRedirectFlags flag) {
|
||||
return static_cast<PostRedirectFlags>(~static_cast<uint8_t>(flag));
|
||||
}
|
||||
|
||||
PostRedirectFlags& operator|=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
|
||||
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) | static_cast<uint8_t>(rhs));
|
||||
uint8_t tmp = static_cast<uint8_t>(lhs);
|
||||
lhs = static_cast<PostRedirectFlags>(tmp);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
PostRedirectFlags& operator&=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
|
||||
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) & static_cast<uint8_t>(rhs));
|
||||
return lhs;
|
||||
}
|
||||
|
||||
PostRedirectFlags& operator^=(PostRedirectFlags& lhs, PostRedirectFlags rhs) {
|
||||
lhs = static_cast<PostRedirectFlags>(static_cast<uint8_t>(lhs) ^ static_cast<uint8_t>(rhs));
|
||||
return lhs;
|
||||
}
|
||||
|
||||
bool any(PostRedirectFlags flag) {
|
||||
return flag != PostRedirectFlags::NONE;
|
||||
}
|
||||
} // namespace cpr
|
44
Src/external_dependencies/cpr/cpr/response.cpp
Normal file
44
Src/external_dependencies/cpr/cpr/response.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "cpr/response.h"
|
||||
|
||||
namespace cpr {
|
||||
|
||||
Response::Response(std::shared_ptr<CurlHolder> curl, std::string&& p_text, std::string&& p_header_string, Cookies&& p_cookies = Cookies{}, Error&& p_error = Error{}) : curl_(std::move(curl)), text(std::move(p_text)), cookies(std::move(p_cookies)), error(std::move(p_error)), raw_header(std::move(p_header_string)) {
|
||||
header = cpr::util::parseHeader(raw_header, &status_line, &reason);
|
||||
assert(curl_);
|
||||
assert(curl_->handle);
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_RESPONSE_CODE, &status_code);
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_TOTAL_TIME, &elapsed);
|
||||
char* url_string{nullptr};
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_EFFECTIVE_URL, &url_string);
|
||||
url = Url(url_string);
|
||||
#if LIBCURL_VERSION_NUM >= 0x073700
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_DOWNLOAD_T, &downloaded_bytes);
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_UPLOAD_T, &uploaded_bytes);
|
||||
#else
|
||||
double downloaded_bytes_double, uploaded_bytes_double;
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_DOWNLOAD, &downloaded_bytes_double);
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_UPLOAD, &uploaded_bytes_double);
|
||||
downloaded_bytes = downloaded_bytes_double;
|
||||
uploaded_bytes = uploaded_bytes_double;
|
||||
#endif
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_REDIRECT_COUNT, &redirect_count);
|
||||
}
|
||||
|
||||
std::vector<CertInfo> Response::GetCertInfos() {
|
||||
assert(curl_);
|
||||
assert(curl_->handle);
|
||||
curl_certinfo* ci{nullptr};
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_CERTINFO, &ci);
|
||||
|
||||
std::vector<CertInfo> cert_infos;
|
||||
for (int i = 0; i < ci->num_of_certs; i++) {
|
||||
CertInfo cert_info;
|
||||
// NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
for (curl_slist* slist = ci->certinfo[i]; slist; slist = slist->next) {
|
||||
cert_info.emplace_back(std::string{slist->data});
|
||||
}
|
||||
cert_infos.emplace_back(cert_info);
|
||||
}
|
||||
return cert_infos;
|
||||
}
|
||||
} // namespace cpr
|
964
Src/external_dependencies/cpr/cpr/session.cpp
Normal file
964
Src/external_dependencies/cpr/cpr/session.cpp
Normal file
@ -0,0 +1,964 @@
|
||||
#include "cpr/session.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "cpr/async.h"
|
||||
#include "cpr/cprtypes.h"
|
||||
#include "cpr/interceptor.h"
|
||||
#include "cpr/util.h"
|
||||
|
||||
#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
|
||||
#include "cpr/ssl_ctx.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace cpr {
|
||||
// Ignored here since libcurl reqires a long:
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
constexpr long ON = 1L;
|
||||
// Ignored here since libcurl reqires a long:
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
constexpr long OFF = 0L;
|
||||
|
||||
CURLcode Session::DoEasyPerform() {
|
||||
if (isUsedInMultiPerform) {
|
||||
std::cerr << "curl_easy_perform cannot be executed if the CURL handle is used in a MultiPerform." << std::endl;
|
||||
return CURLcode::CURLE_FAILED_INIT;
|
||||
}
|
||||
return curl_easy_perform(curl_->handle);
|
||||
}
|
||||
|
||||
void Session::SetHeaderInternal() {
|
||||
curl_slist* chunk = nullptr;
|
||||
for (const std::pair<const std::string, std::string>& item : header_) {
|
||||
std::string header_string = item.first;
|
||||
if (item.second.empty()) {
|
||||
header_string += ";";
|
||||
} else {
|
||||
header_string += ": " + item.second;
|
||||
}
|
||||
|
||||
curl_slist* temp = curl_slist_append(chunk, header_string.c_str());
|
||||
if (temp) {
|
||||
chunk = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the chunked transfer encoding in case it does not already exist:
|
||||
if (chunkedTransferEncoding_ && header_.find("Transfer-Encoding") == header_.end()) {
|
||||
curl_slist* temp = curl_slist_append(chunk, "Transfer-Encoding:chunked");
|
||||
if (temp) {
|
||||
chunk = temp;
|
||||
}
|
||||
}
|
||||
|
||||
// libcurl would prepare the header "Expect: 100-continue" by default when uploading files larger than 1 MB.
|
||||
// Here we would like to disable this feature:
|
||||
curl_slist* temp = curl_slist_append(chunk, "Expect:");
|
||||
if (temp) {
|
||||
chunk = temp;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPHEADER, chunk);
|
||||
|
||||
curl_slist_free_all(curl_->chunk);
|
||||
curl_->chunk = chunk;
|
||||
}
|
||||
|
||||
// Only supported with libcurl >= 7.61.0.
|
||||
// As an alternative use SetHeader and add the token manually.
|
||||
#if LIBCURL_VERSION_NUM >= 0x073D00
|
||||
void Session::SetBearer(const Bearer& token) {
|
||||
// Ignore here since this has been defined by libcurl.
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_XOAUTH2_BEARER, token.GetToken());
|
||||
}
|
||||
#endif
|
||||
|
||||
Session::Session() : curl_(new CurlHolder()) {
|
||||
// Set up some sensible defaults
|
||||
curl_version_info_data* version_info = curl_version_info(CURLVERSION_NOW);
|
||||
std::string version = "curl/" + std::string{version_info->version};
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_USERAGENT, version.c_str());
|
||||
SetRedirect(Redirect());
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_ERRORBUFFER, curl_->error.data());
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COOKIEFILE, "");
|
||||
#ifdef CPR_CURL_NOSIGNAL
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOSIGNAL, 1L);
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x071900
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
#endif
|
||||
}
|
||||
|
||||
Response Session::makeDownloadRequest() {
|
||||
if (!interceptors_.empty()) {
|
||||
std::shared_ptr<Interceptor> interceptor = interceptors_.front();
|
||||
interceptors_.pop();
|
||||
return interceptor->intercept(*this);
|
||||
}
|
||||
|
||||
CURLcode curl_error = DoEasyPerform();
|
||||
|
||||
return CompleteDownload(curl_error);
|
||||
}
|
||||
|
||||
void Session::prepareCommon() {
|
||||
assert(curl_->handle);
|
||||
|
||||
// Set Header:
|
||||
SetHeaderInternal();
|
||||
|
||||
const std::string parametersContent = parameters_.GetContent(*curl_);
|
||||
if (!parametersContent.empty()) {
|
||||
Url new_url{url_ + "?" + parametersContent};
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_URL, new_url.c_str());
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
|
||||
}
|
||||
|
||||
// Proxy:
|
||||
std::string protocol = url_.str().substr(0, url_.str().find(':'));
|
||||
if (proxies_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
|
||||
if (proxyAuth_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
|
||||
}
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_MAJOR >= 7
|
||||
#if LIBCURL_VERSION_MINOR >= 21
|
||||
if (acceptEncoding_.empty()) {
|
||||
/* enable all supported built-in compressions */
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_ACCEPT_ENCODING, "");
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_ACCEPT_ENCODING, acceptEncoding_.getString().c_str());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_MAJOR >= 7
|
||||
#if LIBCURL_VERSION_MINOR >= 71
|
||||
// Fix loading certs from Windows cert store when using OpenSSL:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
curl_->error[0] = '\0';
|
||||
|
||||
response_string_.clear();
|
||||
if (response_string_reserve_size_ > 0) {
|
||||
response_string_.reserve(response_string_reserve_size_);
|
||||
}
|
||||
header_string_.clear();
|
||||
if (!this->writecb_.callback) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &response_string_);
|
||||
}
|
||||
if (!this->headercb_.callback) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::writeFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &header_string_);
|
||||
}
|
||||
|
||||
// Enable so we are able to retrive certificate information:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CERTINFO, 1L);
|
||||
}
|
||||
|
||||
void Session::prepareCommonDownload() {
|
||||
assert(curl_->handle);
|
||||
|
||||
// Set Header:
|
||||
SetHeaderInternal();
|
||||
|
||||
const std::string parametersContent = parameters_.GetContent(*curl_);
|
||||
if (!parametersContent.empty()) {
|
||||
Url new_url{url_ + "?" + parametersContent};
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_URL, new_url.c_str());
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
|
||||
}
|
||||
|
||||
std::string protocol = url_.str().substr(0, url_.str().find(':'));
|
||||
if (proxies_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
|
||||
if (proxyAuth_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
|
||||
}
|
||||
}
|
||||
|
||||
curl_->error[0] = '\0';
|
||||
|
||||
header_string_.clear();
|
||||
if (headercb_.callback) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::headerUserFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &headercb_);
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::writeFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &header_string_);
|
||||
}
|
||||
}
|
||||
|
||||
Response Session::makeRequest() {
|
||||
if (!interceptors_.empty()) {
|
||||
// At least one interceptor exists -> Execute its intercept function
|
||||
std::shared_ptr<Interceptor> interceptor = interceptors_.front();
|
||||
interceptors_.pop();
|
||||
return interceptor->intercept(*this);
|
||||
}
|
||||
|
||||
CURLcode curl_error = DoEasyPerform();
|
||||
return Complete(curl_error);
|
||||
}
|
||||
|
||||
void Session::SetLimitRate(const LimitRate& limit_rate) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_MAX_RECV_SPEED_LARGE, limit_rate.downrate);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_MAX_SEND_SPEED_LARGE, limit_rate.uprate);
|
||||
}
|
||||
|
||||
void Session::SetReadCallback(const ReadCallback& read) {
|
||||
readcb_ = read;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_INFILESIZE_LARGE, read.size);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, read.size);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_READFUNCTION, cpr::util::readUserFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_READDATA, &readcb_);
|
||||
chunkedTransferEncoding_ = read.size == -1;
|
||||
}
|
||||
|
||||
void Session::SetHeaderCallback(const HeaderCallback& header) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, cpr::util::headerUserFunction);
|
||||
headercb_ = header;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, &headercb_);
|
||||
}
|
||||
|
||||
void Session::SetWriteCallback(const WriteCallback& write) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeUserFunction);
|
||||
writecb_ = write;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &writecb_);
|
||||
}
|
||||
|
||||
void Session::SetProgressCallback(const ProgressCallback& progress) {
|
||||
progresscb_ = progress;
|
||||
#if LIBCURL_VERSION_NUM < 0x072000
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROGRESSFUNCTION, cpr::util::progressUserFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROGRESSDATA, &progresscb_);
|
||||
#else
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_XFERINFOFUNCTION, cpr::util::progressUserFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_XFERINFODATA, &progresscb_);
|
||||
#endif
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOPROGRESS, 0L);
|
||||
}
|
||||
|
||||
void Session::SetDebugCallback(const DebugCallback& debug) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_DEBUGFUNCTION, cpr::util::debugUserFunction);
|
||||
debugcb_ = debug;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_DEBUGDATA, &debugcb_);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_VERBOSE, 1L);
|
||||
}
|
||||
|
||||
void Session::SetUrl(const Url& url) {
|
||||
url_ = url;
|
||||
}
|
||||
|
||||
void Session::SetResolve(const Resolve& resolve) {
|
||||
SetResolves({resolve});
|
||||
}
|
||||
|
||||
void Session::SetResolves(const std::vector<Resolve>& resolves) {
|
||||
curl_slist_free_all(curl_->resolveCurlList);
|
||||
curl_->resolveCurlList = nullptr;
|
||||
for (const Resolve& resolve : resolves) {
|
||||
for (const uint16_t port : resolve.ports) {
|
||||
curl_->resolveCurlList = curl_slist_append(curl_->resolveCurlList, (resolve.host + ":" + std::to_string(port) + ":" + resolve.addr).c_str());
|
||||
}
|
||||
}
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_RESOLVE, curl_->resolveCurlList);
|
||||
}
|
||||
|
||||
void Session::SetParameters(const Parameters& parameters) {
|
||||
parameters_ = parameters;
|
||||
}
|
||||
|
||||
void Session::SetParameters(Parameters&& parameters) {
|
||||
parameters_ = std::move(parameters);
|
||||
}
|
||||
|
||||
void Session::SetHeader(const Header& header) {
|
||||
header_ = header;
|
||||
}
|
||||
|
||||
void Session::UpdateHeader(const Header& header) {
|
||||
for (const std::pair<const std::string, std::string>& item : header) {
|
||||
header_[item.first] = item.second;
|
||||
}
|
||||
}
|
||||
|
||||
void Session::SetTimeout(const Timeout& timeout) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_TIMEOUT_MS, timeout.Milliseconds());
|
||||
}
|
||||
|
||||
void Session::SetConnectTimeout(const ConnectTimeout& timeout) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CONNECTTIMEOUT_MS, timeout.Milliseconds());
|
||||
}
|
||||
|
||||
void Session::SetAuth(const Authentication& auth) {
|
||||
// Ignore here since this has been defined by libcurl.
|
||||
switch (auth.GetAuthMode()) {
|
||||
case AuthMode::BASIC:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
|
||||
break;
|
||||
case AuthMode::DIGEST:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
|
||||
break;
|
||||
case AuthMode::NTLM:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_USERPWD, auth.GetAuthString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Session::SetUserAgent(const UserAgent& ua) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_USERAGENT, ua.c_str());
|
||||
}
|
||||
|
||||
void Session::SetPayload(const Payload& payload) {
|
||||
hasBodyOrPayload_ = true;
|
||||
const std::string content = payload.GetContent(*curl_);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(content.length()));
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
|
||||
}
|
||||
|
||||
void Session::SetPayload(Payload&& payload) {
|
||||
hasBodyOrPayload_ = true;
|
||||
const std::string content = payload.GetContent(*curl_);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(content.length()));
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str());
|
||||
}
|
||||
|
||||
void Session::SetProxies(const Proxies& proxies) {
|
||||
proxies_ = proxies;
|
||||
}
|
||||
|
||||
void Session::SetProxies(Proxies&& proxies) {
|
||||
proxies_ = std::move(proxies);
|
||||
}
|
||||
|
||||
void Session::SetProxyAuth(ProxyAuthentication&& proxy_auth) {
|
||||
proxyAuth_ = std::move(proxy_auth);
|
||||
}
|
||||
|
||||
void Session::SetProxyAuth(const ProxyAuthentication& proxy_auth) {
|
||||
proxyAuth_ = proxy_auth;
|
||||
}
|
||||
|
||||
void Session::SetMultipart(const Multipart& multipart) {
|
||||
curl_httppost* formpost = nullptr;
|
||||
curl_httppost* lastptr = nullptr;
|
||||
|
||||
for (const Part& part : multipart.parts) {
|
||||
std::vector<curl_forms> formdata;
|
||||
if (!part.content_type.empty()) {
|
||||
formdata.push_back({CURLFORM_CONTENTTYPE, part.content_type.c_str()});
|
||||
}
|
||||
if (part.is_file) {
|
||||
for (const File& file : part.files) {
|
||||
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
|
||||
formdata.push_back({CURLFORM_FILE, file.filepath.c_str()});
|
||||
if (file.hasOverridedFilename()) {
|
||||
formdata.push_back({CURLFORM_FILENAME, file.overrided_filename.c_str()});
|
||||
}
|
||||
formdata.push_back({CURLFORM_END, nullptr});
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
|
||||
formdata.clear();
|
||||
}
|
||||
} else if (part.is_buffer) {
|
||||
// Do not use formdata, to prevent having to use reinterpreter_cast:
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER, part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH, part.datalen, CURLFORM_END);
|
||||
} else {
|
||||
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
|
||||
formdata.push_back({CURLFORM_COPYCONTENTS, part.value.c_str()});
|
||||
formdata.push_back({CURLFORM_END, nullptr});
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
|
||||
}
|
||||
}
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, formpost);
|
||||
hasBodyOrPayload_ = true;
|
||||
|
||||
curl_formfree(curl_->formpost);
|
||||
curl_->formpost = formpost;
|
||||
}
|
||||
|
||||
void Session::SetMultipart(Multipart&& multipart) {
|
||||
curl_httppost* formpost = nullptr;
|
||||
curl_httppost* lastptr = nullptr;
|
||||
|
||||
for (const Part& part : multipart.parts) {
|
||||
std::vector<curl_forms> formdata;
|
||||
if (!part.content_type.empty()) {
|
||||
formdata.push_back({CURLFORM_CONTENTTYPE, part.content_type.c_str()});
|
||||
}
|
||||
if (part.is_file) {
|
||||
for (const File& file : part.files) {
|
||||
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
|
||||
formdata.push_back({CURLFORM_FILE, file.filepath.c_str()});
|
||||
if (file.hasOverridedFilename()) {
|
||||
formdata.push_back({CURLFORM_FILENAME, file.overrided_filename.c_str()});
|
||||
}
|
||||
formdata.push_back({CURLFORM_END, nullptr});
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
|
||||
formdata.clear();
|
||||
}
|
||||
} else if (part.is_buffer) {
|
||||
// Do not use formdata, to prevent having to use reinterpreter_cast:
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, part.name.c_str(), CURLFORM_BUFFER, part.value.c_str(), CURLFORM_BUFFERPTR, part.data, CURLFORM_BUFFERLENGTH, part.datalen, CURLFORM_END);
|
||||
} else {
|
||||
formdata.push_back({CURLFORM_COPYNAME, part.name.c_str()});
|
||||
formdata.push_back({CURLFORM_COPYCONTENTS, part.value.c_str()});
|
||||
formdata.push_back({CURLFORM_END, nullptr});
|
||||
curl_formadd(&formpost, &lastptr, CURLFORM_ARRAY, formdata.data(), CURLFORM_END);
|
||||
}
|
||||
}
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPPOST, formpost);
|
||||
hasBodyOrPayload_ = true;
|
||||
|
||||
curl_formfree(curl_->formpost);
|
||||
curl_->formpost = formpost;
|
||||
}
|
||||
|
||||
void Session::SetRedirect(const Redirect& redirect) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_FOLLOWLOCATION, redirect.follow ? 1L : 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_MAXREDIRS, redirect.maximum);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_UNRESTRICTED_AUTH, redirect.cont_send_cred ? 1L : 0L);
|
||||
|
||||
// NOLINTNEXTLINE (google-runtime-int)
|
||||
long mask = 0;
|
||||
if (any(redirect.post_flags & PostRedirectFlags::POST_301)) {
|
||||
mask |= CURL_REDIR_POST_301;
|
||||
}
|
||||
if (any(redirect.post_flags & PostRedirectFlags::POST_302)) {
|
||||
mask |= CURL_REDIR_POST_302;
|
||||
}
|
||||
if (any(redirect.post_flags & PostRedirectFlags::POST_303)) {
|
||||
mask |= CURL_REDIR_POST_303;
|
||||
}
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTREDIR, mask);
|
||||
}
|
||||
|
||||
void Session::SetCookies(const Cookies& cookies) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COOKIELIST, "ALL");
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COOKIE, cookies.GetEncoded(*curl_).c_str());
|
||||
}
|
||||
|
||||
void Session::SetBody(const Body& body) {
|
||||
hasBodyOrPayload_ = true;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body.str().length()));
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, body.c_str());
|
||||
}
|
||||
|
||||
void Session::SetBody(Body&& body) {
|
||||
hasBodyOrPayload_ = true;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast<curl_off_t>(body.str().length()));
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body.c_str());
|
||||
}
|
||||
|
||||
void Session::SetLowSpeed(const LowSpeed& low_speed) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_LOW_SPEED_LIMIT, low_speed.limit);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_LOW_SPEED_TIME, low_speed.time);
|
||||
}
|
||||
|
||||
void Session::SetVerifySsl(const VerifySsl& verify) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYPEER, verify ? ON : OFF);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYHOST, verify ? 2L : 0L);
|
||||
}
|
||||
|
||||
void Session::SetUnixSocket(const UnixSocket& unix_socket) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_UNIX_SOCKET_PATH, unix_socket.GetUnixSocketString());
|
||||
}
|
||||
|
||||
void Session::SetSslOptions(const SslOptions& options) {
|
||||
if (!options.cert_file.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLCERT, options.cert_file.c_str());
|
||||
if (!options.cert_type.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLCERTTYPE, options.cert_type.c_str());
|
||||
}
|
||||
}
|
||||
if (!options.key_file.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEY, options.key_file.c_str());
|
||||
if (!options.key_type.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEYTYPE, options.key_type.c_str());
|
||||
}
|
||||
if (!options.key_pass.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_KEYPASSWD, options.key_pass.c_str());
|
||||
}
|
||||
#if SUPPORT_CURLOPT_SSLKEY_BLOB
|
||||
} else if (!options.key_blob.empty()) {
|
||||
std::string key_blob(options.key_blob);
|
||||
curl_blob blob{};
|
||||
// NOLINTNEXTLINE (readability-container-data-pointer)
|
||||
blob.data = &key_blob[0];
|
||||
blob.len = key_blob.length();
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEY_BLOB, &blob);
|
||||
if (!options.key_type.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLKEYTYPE, options.key_type.c_str());
|
||||
}
|
||||
if (!options.key_pass.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_KEYPASSWD, options.key_pass.c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (!options.pinned_public_key.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PINNEDPUBLICKEY, options.pinned_public_key.c_str());
|
||||
}
|
||||
#if SUPPORT_ALPN
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_ENABLE_ALPN, options.enable_alpn ? ON : OFF);
|
||||
#endif
|
||||
#if SUPPORT_NPN
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_ENABLE_NPN, options.enable_npn ? ON : OFF);
|
||||
#endif
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYPEER, options.verify_peer ? ON : OFF);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYHOST, options.verify_host ? 2L : 0L);
|
||||
#if LIBCURL_VERSION_NUM >= 0x072900
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_VERIFYSTATUS, options.verify_status ? ON : OFF);
|
||||
#endif
|
||||
|
||||
int maxTlsVersion = options.ssl_version;
|
||||
#if SUPPORT_MAX_TLS_VERSION
|
||||
maxTlsVersion |= options.max_version;
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSLVERSION,
|
||||
// Ignore here since this has been defined by libcurl.
|
||||
maxTlsVersion);
|
||||
#if SUPPORT_SSL_NO_REVOKE
|
||||
if (options.ssl_no_revoke) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
|
||||
}
|
||||
#endif
|
||||
if (!options.ca_info.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CAINFO, options.ca_info.c_str());
|
||||
}
|
||||
if (!options.ca_path.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CAPATH, options.ca_path.c_str());
|
||||
}
|
||||
#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
|
||||
#ifdef OPENSSL_BACKEND_USED
|
||||
if (!options.ca_buffer.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CTX_FUNCTION, sslctx_function_load_ca_cert_from_buffer);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CTX_DATA, options.ca_buffer.c_str());
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (!options.crl_file.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CRLFILE, options.crl_file.c_str());
|
||||
}
|
||||
if (!options.ciphers.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_CIPHER_LIST, options.ciphers.c_str());
|
||||
}
|
||||
#if SUPPORT_TLSv13_CIPHERS
|
||||
if (!options.tls13_ciphers.empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_TLS13_CIPHERS, options.ciphers.c_str());
|
||||
}
|
||||
#endif
|
||||
#if SUPPORT_SESSIONID_CACHE
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_SSL_SESSIONID_CACHE, options.session_id_cache ? ON : OFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Session::SetVerbose(const Verbose& verbose) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_VERBOSE, verbose.verbose ? ON : OFF);
|
||||
}
|
||||
|
||||
void Session::SetInterface(const Interface& iface) {
|
||||
if (iface.str().empty()) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_INTERFACE, nullptr);
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_INTERFACE, iface.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Session::SetLocalPort(const LocalPort& local_port) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_LOCALPORT, local_port);
|
||||
}
|
||||
|
||||
void Session::SetLocalPortRange(const LocalPortRange& local_port_range) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_LOCALPORTRANGE, local_port_range);
|
||||
}
|
||||
|
||||
void Session::SetHttpVersion(const HttpVersion& version) {
|
||||
switch (version.code) {
|
||||
case HttpVersionCode::VERSION_NONE:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE);
|
||||
break;
|
||||
|
||||
case HttpVersionCode::VERSION_1_0:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
||||
break;
|
||||
|
||||
case HttpVersionCode::VERSION_1_1:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
break;
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x072100 // 7.33.0
|
||||
case HttpVersionCode::VERSION_2_0:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x072F00 // 7.47.0
|
||||
case HttpVersionCode::VERSION_2_0_TLS:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x073100 // 7.49.0
|
||||
case HttpVersionCode::VERSION_2_0_PRIOR_KNOWLEDGE:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x074200 // 7.66.0
|
||||
case HttpVersionCode::VERSION_3_0:
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_3);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: // Should not happen
|
||||
throw std::invalid_argument("Invalid/Unknown HTTP version type.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Session::SetRange(const Range& range) {
|
||||
std::string range_str = range.str();
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_RANGE, range_str.c_str());
|
||||
}
|
||||
|
||||
void Session::SetMultiRange(const MultiRange& multi_range) {
|
||||
std::string multi_range_str = multi_range.str();
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_RANGE, multi_range_str.c_str());
|
||||
}
|
||||
|
||||
void Session::SetReserveSize(const ReserveSize& reserve_size) {
|
||||
ResponseStringReserve(reserve_size.size);
|
||||
}
|
||||
|
||||
void Session::SetAcceptEncoding(const AcceptEncoding& accept_encoding) {
|
||||
acceptEncoding_ = accept_encoding;
|
||||
}
|
||||
|
||||
void Session::SetAcceptEncoding(AcceptEncoding&& accept_encoding) {
|
||||
acceptEncoding_ = std::move(accept_encoding);
|
||||
}
|
||||
|
||||
cpr_off_t Session::GetDownloadFileLength() {
|
||||
cpr_off_t downloadFileLenth = -1;
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_URL, url_.c_str());
|
||||
|
||||
std::string protocol = url_.str().substr(0, url_.str().find(':'));
|
||||
if (proxies_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXY, proxies_[protocol].c_str());
|
||||
if (proxyAuth_.has(protocol)) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_PROXYUSERPWD, proxyAuth_[protocol]);
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 1);
|
||||
if (DoEasyPerform() == CURLE_OK) {
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T, &downloadFileLenth);
|
||||
}
|
||||
return downloadFileLenth;
|
||||
}
|
||||
|
||||
void Session::ResponseStringReserve(size_t size) {
|
||||
response_string_reserve_size_ = size;
|
||||
}
|
||||
|
||||
Response Session::Delete() {
|
||||
PrepareDelete();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Download(const WriteCallback& write) {
|
||||
PrepareDownload(write);
|
||||
return makeDownloadRequest();
|
||||
}
|
||||
|
||||
Response Session::Download(std::ofstream& file) {
|
||||
PrepareDownload(file);
|
||||
return makeDownloadRequest();
|
||||
}
|
||||
|
||||
Response Session::Get() {
|
||||
PrepareGet();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Head() {
|
||||
PrepareHead();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Options() {
|
||||
PrepareOptions();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Patch() {
|
||||
PreparePatch();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Post() {
|
||||
PreparePost();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
Response Session::Put() {
|
||||
PreparePut();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
std::shared_ptr<Session> Session::GetSharedPtrFromThis() {
|
||||
try {
|
||||
return shared_from_this();
|
||||
} catch (std::bad_weak_ptr&) {
|
||||
throw std::runtime_error("Failed to get a shared pointer from this. The reason is probably that the session object is not managed by a shared pointer, which is required to use this functionality.");
|
||||
}
|
||||
}
|
||||
|
||||
AsyncResponse Session::GetAsync() {
|
||||
auto shared_this = shared_from_this();
|
||||
return async([shared_this]() { return shared_this->Get(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::DeleteAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Delete(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::DownloadAsync(const WriteCallback& write) {
|
||||
return async([shared_this = GetSharedPtrFromThis(), write]() { return shared_this->Download(write); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::DownloadAsync(std::ofstream& file) {
|
||||
return async([shared_this = GetSharedPtrFromThis(), &file]() { return shared_this->Download(file); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::HeadAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Head(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::OptionsAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Options(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::PatchAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Patch(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::PostAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Post(); });
|
||||
}
|
||||
|
||||
AsyncResponse Session::PutAsync() {
|
||||
return async([shared_this = GetSharedPtrFromThis()]() { return shared_this->Put(); });
|
||||
}
|
||||
|
||||
std::shared_ptr<CurlHolder> Session::GetCurlHolder() {
|
||||
return curl_;
|
||||
}
|
||||
|
||||
std::string Session::GetFullRequestUrl() {
|
||||
const std::string parametersContent = parameters_.GetContent(*curl_);
|
||||
return url_.str() + (parametersContent.empty() ? "" : "?") + parametersContent;
|
||||
}
|
||||
|
||||
void Session::PrepareDelete() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PrepareGet() {
|
||||
// In case there is a body or payload for this request, we create a custom GET-Request since a
|
||||
// GET-Request with body is based on the HTTP RFC **not** a leagal request.
|
||||
if (hasBodyOrPayload_) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1L);
|
||||
}
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PrepareHead() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PrepareOptions() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "OPTIONS");
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PreparePatch() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PreparePost() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
|
||||
// In case there is no body or payload set it to an empty post:
|
||||
if (hasBodyOrPayload_) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
|
||||
} else {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, readcb_.callback ? nullptr : "");
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
}
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PreparePut() {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
if (!hasBodyOrPayload_ && readcb_.callback) {
|
||||
/**
|
||||
* Yes, this one has to be CURLOPT_POSTFIELDS even if we are performing a PUT request.
|
||||
* In case we don't set this one, performing a POST-request with PUT won't work.
|
||||
* It in theory this only enforces the usage of the readcallback for POST requests, but works here as well.
|
||||
**/
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDS, nullptr);
|
||||
}
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_RANGE, nullptr);
|
||||
prepareCommon();
|
||||
}
|
||||
|
||||
void Session::PrepareDownload(std::ofstream& file) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEFUNCTION, cpr::util::writeFileFunction);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_WRITEDATA, &file);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
|
||||
|
||||
prepareCommonDownload();
|
||||
}
|
||||
|
||||
void Session::PrepareDownload(const WriteCallback& write) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HTTPGET, 1);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_CUSTOMREQUEST, nullptr);
|
||||
|
||||
SetWriteCallback(write);
|
||||
|
||||
prepareCommonDownload();
|
||||
}
|
||||
|
||||
Response Session::Complete(CURLcode curl_error) {
|
||||
curl_slist* raw_cookies{nullptr};
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
|
||||
Cookies cookies = util::parseCookies(raw_cookies);
|
||||
curl_slist_free_all(raw_cookies);
|
||||
|
||||
// Reset the has no body property:
|
||||
hasBodyOrPayload_ = false;
|
||||
|
||||
std::string errorMsg = curl_->error.data();
|
||||
return Response(curl_, std::move(response_string_), std::move(header_string_), std::move(cookies), Error(curl_error, std::move(errorMsg)));
|
||||
}
|
||||
|
||||
Response Session::CompleteDownload(CURLcode curl_error) {
|
||||
if (!headercb_.callback) {
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERFUNCTION, nullptr);
|
||||
curl_easy_setopt(curl_->handle, CURLOPT_HEADERDATA, 0);
|
||||
}
|
||||
|
||||
curl_slist* raw_cookies{nullptr};
|
||||
curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies);
|
||||
Cookies cookies = util::parseCookies(raw_cookies);
|
||||
curl_slist_free_all(raw_cookies);
|
||||
std::string errorMsg = curl_->error.data();
|
||||
|
||||
return Response(curl_, "", std::move(header_string_), std::move(cookies), Error(curl_error, std::move(errorMsg)));
|
||||
}
|
||||
|
||||
void Session::AddInterceptor(const std::shared_ptr<Interceptor>& pinterceptor) {
|
||||
interceptors_.push(pinterceptor);
|
||||
}
|
||||
|
||||
Response Session::proceed() {
|
||||
prepareCommon();
|
||||
return makeRequest();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
void Session::SetOption(const Resolve& resolve) { SetResolve(resolve); }
|
||||
void Session::SetOption(const std::vector<Resolve>& resolves) { SetResolves(resolves); }
|
||||
void Session::SetOption(const ReadCallback& read) { SetReadCallback(read); }
|
||||
void Session::SetOption(const HeaderCallback& header) { SetHeaderCallback(header); }
|
||||
void Session::SetOption(const WriteCallback& write) { SetWriteCallback(write); }
|
||||
void Session::SetOption(const ProgressCallback& progress) { SetProgressCallback(progress); }
|
||||
void Session::SetOption(const DebugCallback& debug) { SetDebugCallback(debug); }
|
||||
void Session::SetOption(const Url& url) { SetUrl(url); }
|
||||
void Session::SetOption(const Parameters& parameters) { SetParameters(parameters); }
|
||||
void Session::SetOption(Parameters&& parameters) { SetParameters(std::move(parameters)); }
|
||||
void Session::SetOption(const Header& header) { SetHeader(header); }
|
||||
void Session::SetOption(const Timeout& timeout) { SetTimeout(timeout); }
|
||||
void Session::SetOption(const ConnectTimeout& timeout) { SetConnectTimeout(timeout); }
|
||||
void Session::SetOption(const Authentication& auth) { SetAuth(auth); }
|
||||
void Session::SetOption(const LimitRate& limit_rate) { SetLimitRate(limit_rate); }
|
||||
// Only supported with libcurl >= 7.61.0.
|
||||
// As an alternative use SetHeader and add the token manually.
|
||||
#if LIBCURL_VERSION_NUM >= 0x073D00
|
||||
void Session::SetOption(const Bearer& auth) { SetBearer(auth); }
|
||||
#endif
|
||||
void Session::SetOption(const UserAgent& ua) { SetUserAgent(ua); }
|
||||
void Session::SetOption(const Payload& payload) { SetPayload(payload); }
|
||||
void Session::SetOption(Payload&& payload) { SetPayload(std::move(payload)); }
|
||||
void Session::SetOption(const Proxies& proxies) { SetProxies(proxies); }
|
||||
void Session::SetOption(Proxies&& proxies) { SetProxies(std::move(proxies)); }
|
||||
void Session::SetOption(ProxyAuthentication&& proxy_auth) { SetProxyAuth(std::move(proxy_auth)); }
|
||||
void Session::SetOption(const ProxyAuthentication& proxy_auth) { SetProxyAuth(proxy_auth); }
|
||||
void Session::SetOption(const Multipart& multipart) { SetMultipart(multipart); }
|
||||
void Session::SetOption(Multipart&& multipart) { SetMultipart(std::move(multipart)); }
|
||||
void Session::SetOption(const Redirect& redirect) { SetRedirect(redirect); }
|
||||
void Session::SetOption(const Cookies& cookies) { SetCookies(cookies); }
|
||||
void Session::SetOption(const Body& body) { SetBody(body); }
|
||||
void Session::SetOption(Body&& body) { SetBody(std::move(body)); }
|
||||
void Session::SetOption(const LowSpeed& low_speed) { SetLowSpeed(low_speed); }
|
||||
void Session::SetOption(const VerifySsl& verify) { SetVerifySsl(verify); }
|
||||
void Session::SetOption(const Verbose& verbose) { SetVerbose(verbose); }
|
||||
void Session::SetOption(const UnixSocket& unix_socket) { SetUnixSocket(unix_socket); }
|
||||
void Session::SetOption(const SslOptions& options) { SetSslOptions(options); }
|
||||
void Session::SetOption(const Interface& iface) { SetInterface(iface); }
|
||||
void Session::SetOption(const LocalPort& local_port) { SetLocalPort(local_port); }
|
||||
void Session::SetOption(const LocalPortRange& local_port_range) { SetLocalPortRange(local_port_range); }
|
||||
void Session::SetOption(const HttpVersion& version) { SetHttpVersion(version); }
|
||||
void Session::SetOption(const Range& range) { SetRange(range); }
|
||||
void Session::SetOption(const MultiRange& multi_range) { SetMultiRange(multi_range); }
|
||||
void Session::SetOption(const ReserveSize& reserve_size) { SetReserveSize(reserve_size.size); }
|
||||
void Session::SetOption(const AcceptEncoding& accept_encoding) { SetAcceptEncoding(accept_encoding); }
|
||||
void Session::SetOption(AcceptEncoding&& accept_encoding) { SetAcceptEncoding(accept_encoding); }
|
||||
// clang-format on
|
||||
} // namespace cpr
|
70
Src/external_dependencies/cpr/cpr/ssl_ctx.cpp
Normal file
70
Src/external_dependencies/cpr/cpr/ssl_ctx.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#include "cpr/ssl_ctx.h"
|
||||
|
||||
#if SUPPORT_CURLOPT_SSL_CTX_FUNCTION
|
||||
|
||||
#ifdef OPENSSL_BACKEND_USED
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
/**
|
||||
* The ssl_ctx parameter is actually a pointer to the SSL library's SSL_CTX for OpenSSL.
|
||||
* If an error is returned from the callback no attempt to establish a connection is made and
|
||||
* the perform operation will return the callback's error code.
|
||||
*
|
||||
* 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) {
|
||||
// Check arguments
|
||||
if (raw_cert_buf == nullptr || sslctx == nullptr) {
|
||||
printf("Invalid callback arguments\n");
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
// Setup pointer
|
||||
X509_STORE* store = nullptr;
|
||||
X509* cert = nullptr;
|
||||
BIO* bio = nullptr;
|
||||
char* cert_buf = static_cast<char*>(raw_cert_buf);
|
||||
|
||||
// Create a memory BIO using the data of cert_buf.
|
||||
// Note: It is assumed, that cert_buf is nul terminated and its length is determined by strlen.
|
||||
bio = BIO_new_mem_buf(cert_buf, -1);
|
||||
|
||||
// Load the PEM formatted certicifate into an X509 structure which OpenSSL can use.
|
||||
PEM_read_bio_X509(bio, &cert, nullptr, nullptr);
|
||||
if (cert == nullptr) {
|
||||
printf("PEM_read_bio_X509 failed\n");
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
// Get a pointer to the current certificate verification storage
|
||||
store = SSL_CTX_get_cert_store(static_cast<SSL_CTX*>(sslctx));
|
||||
|
||||
// Add the loaded certificate to the verification storage
|
||||
int status = X509_STORE_add_cert(store, cert);
|
||||
if (status == 0) {
|
||||
printf("Error adding certificate\n");
|
||||
return CURLE_ABORTED_BY_CALLBACK;
|
||||
}
|
||||
|
||||
// Decrement the reference count of the X509 structure cert and frees it up
|
||||
X509_free(cert);
|
||||
|
||||
// Free the entire bio chain
|
||||
BIO_free(bio);
|
||||
|
||||
// The CA certificate was loaded successfully into the verification storage
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
} // namespace cpr
|
||||
|
||||
#endif // OPENSSL_BACKEND_USED
|
||||
|
||||
#endif // SUPPORT_CURLOPT_SSL_CTX_FUNCTION
|
148
Src/external_dependencies/cpr/cpr/threadpool.cpp
Normal file
148
Src/external_dependencies/cpr/cpr/threadpool.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "cpr/threadpool.h"
|
||||
|
||||
namespace cpr {
|
||||
|
||||
ThreadPool::ThreadPool(size_t min_threads, size_t max_threads, std::chrono::milliseconds max_idle_ms) : min_thread_num(min_threads), max_thread_num(max_threads), max_idle_time(max_idle_ms), status(STOP), cur_thread_num(0), idle_thread_num(0) {}
|
||||
|
||||
ThreadPool::~ThreadPool() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
int ThreadPool::Start(size_t start_threads) {
|
||||
if (status != STOP) {
|
||||
return -1;
|
||||
}
|
||||
status = RUNNING;
|
||||
if (start_threads < min_thread_num) {
|
||||
start_threads = min_thread_num;
|
||||
}
|
||||
if (start_threads > max_thread_num) {
|
||||
start_threads = max_thread_num;
|
||||
}
|
||||
for (size_t i = 0; i < start_threads; ++i) {
|
||||
CreateThread();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThreadPool::Stop() {
|
||||
if (status == STOP) {
|
||||
return -1;
|
||||
}
|
||||
status = STOP;
|
||||
task_cond.notify_all();
|
||||
for (auto& i : threads) {
|
||||
if (i.thread->joinable()) {
|
||||
i.thread->join();
|
||||
}
|
||||
}
|
||||
threads.clear();
|
||||
cur_thread_num = 0;
|
||||
idle_thread_num = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThreadPool::Pause() {
|
||||
if (status == RUNNING) {
|
||||
status = PAUSE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThreadPool::Resume() {
|
||||
if (status == PAUSE) {
|
||||
status = RUNNING;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ThreadPool::Wait() {
|
||||
while (true) {
|
||||
if (status == STOP || (tasks.empty() && idle_thread_num == cur_thread_num)) {
|
||||
break;
|
||||
}
|
||||
std::this_thread::yield();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ThreadPool::CreateThread() {
|
||||
if (cur_thread_num >= max_thread_num) {
|
||||
return false;
|
||||
}
|
||||
std::thread* thread = new std::thread([this] {
|
||||
bool initialRun = true;
|
||||
while (status != STOP) {
|
||||
while (status == PAUSE) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
Task task;
|
||||
{
|
||||
std::unique_lock<std::mutex> locker(task_mutex);
|
||||
task_cond.wait_for(locker, std::chrono::milliseconds(max_idle_time), [this]() { return status == STOP || !tasks.empty(); });
|
||||
if (status == STOP) {
|
||||
return;
|
||||
}
|
||||
if (tasks.empty()) {
|
||||
if (cur_thread_num > min_thread_num) {
|
||||
DelThread(std::this_thread::get_id());
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!initialRun) {
|
||||
--idle_thread_num;
|
||||
}
|
||||
task = std::move(tasks.front());
|
||||
tasks.pop();
|
||||
}
|
||||
if (task) {
|
||||
task();
|
||||
++idle_thread_num;
|
||||
} else if (initialRun) {
|
||||
++idle_thread_num;
|
||||
initialRun = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
AddThread(thread);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ThreadPool::AddThread(std::thread* thread) {
|
||||
thread_mutex.lock();
|
||||
++cur_thread_num;
|
||||
ThreadData data;
|
||||
data.thread = std::shared_ptr<std::thread>(thread);
|
||||
data.id = thread->get_id();
|
||||
data.status = RUNNING;
|
||||
data.start_time = time(nullptr);
|
||||
data.stop_time = 0;
|
||||
threads.emplace_back(data);
|
||||
thread_mutex.unlock();
|
||||
}
|
||||
|
||||
void ThreadPool::DelThread(std::thread::id id) {
|
||||
time_t now = time(nullptr);
|
||||
thread_mutex.lock();
|
||||
--cur_thread_num;
|
||||
--idle_thread_num;
|
||||
auto iter = threads.begin();
|
||||
while (iter != threads.end()) {
|
||||
if (iter->status == STOP && now > iter->stop_time) {
|
||||
if (iter->thread->joinable()) {
|
||||
iter->thread->join();
|
||||
iter = threads.erase(iter);
|
||||
continue;
|
||||
}
|
||||
} else if (iter->id == id) {
|
||||
iter->status = STOP;
|
||||
iter->stop_time = time(nullptr);
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
thread_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace cpr
|
31
Src/external_dependencies/cpr/cpr/timeout.cpp
Normal file
31
Src/external_dependencies/cpr/cpr/timeout.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "cpr/timeout.h"
|
||||
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace cpr {
|
||||
|
||||
// No way around since curl uses a long here.
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
long Timeout::Milliseconds() const {
|
||||
static_assert(std::is_same<std::chrono::milliseconds, decltype(ms)>::value, "Following casting expects milliseconds.");
|
||||
|
||||
// No way around since curl uses a long here.
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
if (ms.count() > static_cast<std::chrono::milliseconds::rep>(std::numeric_limits<long>::max())) {
|
||||
throw std::overflow_error("cpr::Timeout: timeout value overflow: " + std::to_string(ms.count()) + " ms.");
|
||||
}
|
||||
// No way around since curl uses a long here.
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
if (ms.count() < static_cast<std::chrono::milliseconds::rep>(std::numeric_limits<long>::min())) {
|
||||
throw std::underflow_error("cpr::Timeout: timeout value underflow: " + std::to_string(ms.count()) + " ms.");
|
||||
}
|
||||
|
||||
// No way around since curl uses a long here.
|
||||
// NOLINTNEXTLINE(google-runtime-int)
|
||||
return static_cast<long>(ms.count());
|
||||
}
|
||||
|
||||
} // namespace cpr
|
8
Src/external_dependencies/cpr/cpr/unix_socket.cpp
Normal file
8
Src/external_dependencies/cpr/cpr/unix_socket.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#include "cpr/unix_socket.h"
|
||||
|
||||
namespace cpr {
|
||||
const char* UnixSocket::GetUnixSocketString() const noexcept {
|
||||
return unix_socket_.data();
|
||||
}
|
||||
} // namespace cpr
|
236
Src/external_dependencies/cpr/cpr/util.cpp
Normal file
236
Src/external_dependencies/cpr/cpr/util.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
#include "cpr/util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if defined(_Win32)
|
||||
#include <Windows.h>
|
||||
#else
|
||||
// https://en.cppreference.com/w/c/string/byte/memset
|
||||
// NOLINTNEXTLINE(bugprone-reserved-identifier, cert-dcl37-c, cert-dcl51-cpp, cppcoreguidelines-macro-usage)
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#include <cstring>
|
||||
#endif
|
||||
|
||||
namespace cpr::util {
|
||||
|
||||
enum class CurlHTTPCookieField : size_t {
|
||||
Domain = 0,
|
||||
IncludeSubdomains,
|
||||
Path,
|
||||
HttpsOnly,
|
||||
Expires,
|
||||
Name,
|
||||
Value,
|
||||
};
|
||||
|
||||
Cookies parseCookies(curl_slist* raw_cookies) {
|
||||
const int CURL_HTTP_COOKIE_SIZE = static_cast<int>(CurlHTTPCookieField::Value) + 1;
|
||||
Cookies cookies;
|
||||
for (curl_slist* nc = raw_cookies; nc; nc = nc->next) {
|
||||
std::vector<std::string> tokens = cpr::util::split(nc->data, '\t');
|
||||
while (tokens.size() < CURL_HTTP_COOKIE_SIZE) {
|
||||
tokens.emplace_back("");
|
||||
}
|
||||
std::time_t expires = static_cast<time_t>(std::stoul(tokens.at(static_cast<size_t>(CurlHTTPCookieField::Expires))));
|
||||
cookies.emplace_back(Cookie{
|
||||
tokens.at(static_cast<size_t>(CurlHTTPCookieField::Name)),
|
||||
tokens.at(static_cast<size_t>(CurlHTTPCookieField::Value)),
|
||||
tokens.at(static_cast<size_t>(CurlHTTPCookieField::Domain)),
|
||||
isTrue(tokens.at(static_cast<size_t>(CurlHTTPCookieField::IncludeSubdomains))),
|
||||
tokens.at(static_cast<size_t>(CurlHTTPCookieField::Path)),
|
||||
isTrue(tokens.at(static_cast<size_t>(CurlHTTPCookieField::HttpsOnly))),
|
||||
std::chrono::system_clock::from_time_t(expires),
|
||||
});
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
|
||||
Header parseHeader(const std::string& headers, std::string* status_line, std::string* reason) {
|
||||
Header header;
|
||||
std::vector<std::string> lines;
|
||||
std::istringstream stream(headers);
|
||||
{
|
||||
std::string line;
|
||||
while (std::getline(stream, line, '\n')) {
|
||||
lines.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::string& line : lines) {
|
||||
if (line.substr(0, 5) == "HTTP/") {
|
||||
// set the status_line if it was given
|
||||
if ((status_line != nullptr) || (reason != nullptr)) {
|
||||
line.resize(std::min<size_t>(line.size(), line.find_last_not_of("\t\n\r ") + 1));
|
||||
if (status_line != nullptr) {
|
||||
*status_line = line;
|
||||
}
|
||||
|
||||
// set the reason if it was given
|
||||
if (reason != nullptr) {
|
||||
size_t pos1 = line.find_first_of("\t ");
|
||||
size_t pos2 = std::string::npos;
|
||||
if (pos1 != std::string::npos) {
|
||||
pos2 = line.find_first_of("\t ", pos1 + 1);
|
||||
}
|
||||
if (pos2 != std::string::npos) {
|
||||
line.erase(0, pos2 + 1);
|
||||
*reason = line;
|
||||
}
|
||||
}
|
||||
}
|
||||
header.clear();
|
||||
}
|
||||
|
||||
if (line.length() > 0) {
|
||||
size_t found = line.find(':');
|
||||
if (found != std::string::npos) {
|
||||
std::string value = line.substr(found + 1);
|
||||
value.erase(0, value.find_first_not_of("\t "));
|
||||
value.resize(std::min<size_t>(value.size(), value.find_last_not_of("\t\n\r ") + 1));
|
||||
header[line.substr(0, found)] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
std::vector<std::string> split(const std::string& to_split, char delimiter) {
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
std::stringstream stream(to_split);
|
||||
std::string item;
|
||||
while (std::getline(stream, item, delimiter)) {
|
||||
tokens.push_back(item);
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
size_t readUserFunction(char* ptr, size_t size, size_t nitems, const ReadCallback* read) {
|
||||
size *= nitems;
|
||||
return (*read)(ptr, size) ? size : CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCallback* header) {
|
||||
size *= nmemb;
|
||||
return (*header)({ptr, size}) ? size : 0;
|
||||
}
|
||||
|
||||
size_t writeFunction(char* ptr, size_t size, size_t nmemb, std::string* data) {
|
||||
size *= nmemb;
|
||||
data->append(ptr, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t writeFileFunction(char* ptr, size_t size, size_t nmemb, std::ofstream* file) {
|
||||
size *= nmemb;
|
||||
file->write(ptr, static_cast<std::streamsize>(size));
|
||||
return size;
|
||||
}
|
||||
|
||||
size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallback* write) {
|
||||
size *= nmemb;
|
||||
return (*write)({ptr, size}) ? size : 0;
|
||||
}
|
||||
|
||||
#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
|
||||
return (*progress)(dltotal, dlnow, ultotal, ulnow) ? 0 : 1;
|
||||
} // namespace cpr::util
|
||||
|
||||
int debugUserFunction(CURL* /*handle*/, curl_infotype type, char* data, size_t size, const DebugCallback* debug) {
|
||||
(*debug)(static_cast<DebugCallback::InfoType>(type), std::string(data, size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary CurlHolder object and uses it to escape the given string.
|
||||
* If you plan to use this methode on a regular basis think about creating a CurlHolder
|
||||
* object and calling urlEncode(std::string) on it.
|
||||
*
|
||||
* Example:
|
||||
* CurlHolder holder;
|
||||
* std::string input = "Hello World!";
|
||||
* std::string result = holder.urlEncode(input);
|
||||
**/
|
||||
std::string urlEncode(const std::string& s) {
|
||||
CurlHolder holder; // Create a temporary new holder for URL encoding
|
||||
return holder.urlEncode(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a temporary CurlHolder object and uses it to unescape the given string.
|
||||
* If you plan to use this methode on a regular basis think about creating a CurlHolder
|
||||
* object and calling urlDecode(std::string) on it.
|
||||
*
|
||||
* Example:
|
||||
* CurlHolder holder;
|
||||
* std::string input = "Hello%20World%21";
|
||||
* std::string result = holder.urlDecode(input);
|
||||
**/
|
||||
std::string urlDecode(const std::string& s) {
|
||||
CurlHolder holder; // Create a temporary new holder for URL decoding
|
||||
return holder.urlDecode(s);
|
||||
}
|
||||
|
||||
#if defined(__STDC_LIB_EXT1__)
|
||||
void secureStringClear(std::string& s) {
|
||||
if (s.empty()) {
|
||||
return;
|
||||
}
|
||||
memset_s(&s.front(), s.length(), 0, s.length());
|
||||
s.clear();
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
void secureStringClear(std::string& s) {
|
||||
if (s.empty()) {
|
||||
return;
|
||||
}
|
||||
SecureZeroMemory(&s.front(), s.length());
|
||||
s.clear();
|
||||
}
|
||||
#else
|
||||
#if defined(__clang__)
|
||||
#pragma clang optimize off // clang
|
||||
#elif defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#pragma GCC push_options // g++
|
||||
#pragma GCC optimize("O0") // g++
|
||||
#endif
|
||||
void secureStringClear(std::string& s) {
|
||||
if (s.empty()) {
|
||||
return;
|
||||
}
|
||||
// NOLINTNEXTLINE (readability-container-data-pointer)
|
||||
char* ptr = &(s[0]);
|
||||
memset(ptr, '\0', s.length());
|
||||
s.clear();
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang optimize on // clang
|
||||
#elif defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#pragma GCC pop_options // g++
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bool isTrue(const std::string& s) {
|
||||
std::string temp_string{s};
|
||||
std::transform(temp_string.begin(), temp_string.end(), temp_string.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||
return temp_string == "true";
|
||||
}
|
||||
|
||||
} // namespace cpr::util
|
67
Src/external_dependencies/cpr/include/CMakeLists.txt
Normal file
67
Src/external_dependencies/cpr/include/CMakeLists.txt
Normal file
@ -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})
|
36
Src/external_dependencies/cpr/include/cpr/accept_encoding.h
Normal file
36
Src/external_dependencies/cpr/include/cpr/accept_encoding.h
Normal file
@ -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
|
321
Src/external_dependencies/cpr/include/cpr/api.h
Normal file
321
Src/external_dependencies/cpr/include/cpr/api.h
Normal file
@ -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
|
49
Src/external_dependencies/cpr/include/cpr/async.h
Normal file
49
Src/external_dependencies/cpr/include/cpr/async.h
Normal file
@ -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
|
33
Src/external_dependencies/cpr/include/cpr/auth.h
Normal file
33
Src/external_dependencies/cpr/include/cpr/auth.h
Normal file
@ -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
|
36
Src/external_dependencies/cpr/include/cpr/bearer.h
Normal file
36
Src/external_dependencies/cpr/include/cpr/bearer.h
Normal file
@ -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
|
54
Src/external_dependencies/cpr/include/cpr/body.h
Normal file
54
Src/external_dependencies/cpr/include/cpr/body.h
Normal file
@ -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
|
35
Src/external_dependencies/cpr/include/cpr/buffer.h
Normal file
35
Src/external_dependencies/cpr/include/cpr/buffer.h
Normal file
@ -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
|
89
Src/external_dependencies/cpr/include/cpr/callback.h
Normal file
89
Src/external_dependencies/cpr/include/cpr/callback.h
Normal file
@ -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
|
35
Src/external_dependencies/cpr/include/cpr/cert_info.h
Normal file
35
Src/external_dependencies/cpr/include/cpr/cert_info.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/connect_timeout.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/connect_timeout.h
Normal file
@ -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
|
92
Src/external_dependencies/cpr/include/cpr/cookies.h
Normal file
92
Src/external_dependencies/cpr/include/cpr/cookies.h
Normal file
@ -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
|
46
Src/external_dependencies/cpr/include/cpr/cpr.h
Normal file
46
Src/external_dependencies/cpr/include/cpr/cpr.h
Normal file
@ -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
|
137
Src/external_dependencies/cpr/include/cpr/cprtypes.h
Normal file
137
Src/external_dependencies/cpr/include/cpr/cprtypes.h
Normal file
@ -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
|
53
Src/external_dependencies/cpr/include/cpr/curl_container.h
Normal file
53
Src/external_dependencies/cpr/include/cpr/curl_container.h
Normal file
@ -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 //
|
54
Src/external_dependencies/cpr/include/cpr/curlholder.h
Normal file
54
Src/external_dependencies/cpr/include/cpr/curlholder.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/curlmultiholder.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/curlmultiholder.h
Normal file
@ -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
|
53
Src/external_dependencies/cpr/include/cpr/error.h
Normal file
53
Src/external_dependencies/cpr/include/cpr/error.h
Normal file
@ -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
|
55
Src/external_dependencies/cpr/include/cpr/file.h
Normal file
55
Src/external_dependencies/cpr/include/cpr/file.h
Normal file
@ -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
|
19
Src/external_dependencies/cpr/include/cpr/filesystem.h
Normal file
19
Src/external_dependencies/cpr/include/cpr/filesystem.h
Normal file
@ -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
|
67
Src/external_dependencies/cpr/include/cpr/http_version.h
Normal file
67
Src/external_dependencies/cpr/include/cpr/http_version.h
Normal file
@ -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
|
36
Src/external_dependencies/cpr/include/cpr/interceptor.h
Normal file
36
Src/external_dependencies/cpr/include/cpr/interceptor.h
Normal file
@ -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
|
34
Src/external_dependencies/cpr/include/cpr/interface.h
Normal file
34
Src/external_dependencies/cpr/include/cpr/interface.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/limit_rate.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/limit_rate.h
Normal file
@ -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
|
23
Src/external_dependencies/cpr/include/cpr/local_port.h
Normal file
23
Src/external_dependencies/cpr/include/cpr/local_port.h
Normal file
@ -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
|
23
Src/external_dependencies/cpr/include/cpr/local_port_range.h
Normal file
23
Src/external_dependencies/cpr/include/cpr/local_port_range.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/low_speed.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/low_speed.h
Normal file
@ -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
|
45
Src/external_dependencies/cpr/include/cpr/multipart.h
Normal file
45
Src/external_dependencies/cpr/include/cpr/multipart.h
Normal file
@ -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
|
119
Src/external_dependencies/cpr/include/cpr/multiperform.h
Normal file
119
Src/external_dependencies/cpr/include/cpr/multiperform.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/parameters.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/parameters.h
Normal file
@ -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
|
23
Src/external_dependencies/cpr/include/cpr/payload.h
Normal file
23
Src/external_dependencies/cpr/include/cpr/payload.h
Normal file
@ -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
|
23
Src/external_dependencies/cpr/include/cpr/proxies.h
Normal file
23
Src/external_dependencies/cpr/include/cpr/proxies.h
Normal file
@ -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
|
44
Src/external_dependencies/cpr/include/cpr/proxyauth.h
Normal file
44
Src/external_dependencies/cpr/include/cpr/proxyauth.h
Normal file
@ -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
|
44
Src/external_dependencies/cpr/include/cpr/range.h
Normal file
44
Src/external_dependencies/cpr/include/cpr/range.h
Normal file
@ -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
|
84
Src/external_dependencies/cpr/include/cpr/redirect.h
Normal file
84
Src/external_dependencies/cpr/include/cpr/redirect.h
Normal file
@ -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
|
17
Src/external_dependencies/cpr/include/cpr/reserve_size.h
Normal file
17
Src/external_dependencies/cpr/include/cpr/reserve_size.h
Normal file
@ -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
|
23
Src/external_dependencies/cpr/include/cpr/resolve.h
Normal file
23
Src/external_dependencies/cpr/include/cpr/resolve.h
Normal file
@ -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
|
58
Src/external_dependencies/cpr/include/cpr/response.h
Normal file
58
Src/external_dependencies/cpr/include/cpr/response.h
Normal file
@ -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
|
297
Src/external_dependencies/cpr/include/cpr/session.h
Normal file
297
Src/external_dependencies/cpr/include/cpr/session.h
Normal file
@ -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
|
47
Src/external_dependencies/cpr/include/cpr/singleton.h
Normal file
47
Src/external_dependencies/cpr/include/cpr/singleton.h
Normal file
@ -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
|
26
Src/external_dependencies/cpr/include/cpr/ssl_ctx.h
Normal file
26
Src/external_dependencies/cpr/include/cpr/ssl_ctx.h
Normal file
@ -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
|
622
Src/external_dependencies/cpr/include/cpr/ssl_options.h
Normal file
622
Src/external_dependencies/cpr/include/cpr/ssl_options.h
Normal file
@ -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
|
100
Src/external_dependencies/cpr/include/cpr/status_codes.h
Normal file
100
Src/external_dependencies/cpr/include/cpr/status_codes.h
Normal file
@ -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
|
122
Src/external_dependencies/cpr/include/cpr/threadpool.h
Normal file
122
Src/external_dependencies/cpr/include/cpr/threadpool.h
Normal file
@ -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
|
27
Src/external_dependencies/cpr/include/cpr/timeout.h
Normal file
27
Src/external_dependencies/cpr/include/cpr/timeout.h
Normal file
@ -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
|
21
Src/external_dependencies/cpr/include/cpr/unix_socket.h
Normal file
21
Src/external_dependencies/cpr/include/cpr/unix_socket.h
Normal file
@ -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
|
33
Src/external_dependencies/cpr/include/cpr/user_agent.h
Normal file
33
Src/external_dependencies/cpr/include/cpr/user_agent.h
Normal file
@ -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
|
45
Src/external_dependencies/cpr/include/cpr/util.h
Normal file
45
Src/external_dependencies/cpr/include/cpr/util.h
Normal file
@ -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
|
18
Src/external_dependencies/cpr/include/cpr/verbose.h
Normal file
18
Src/external_dependencies/cpr/include/cpr/verbose.h
Normal file
@ -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_ */
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
|
||||
ToolsVersion="15.0">
|
||||
<PropertyGroup>
|
||||
<LibraryType Condition="'$(Configuration)'=='Debug'">mdd</LibraryType>
|
||||
<LibraryType Condition="'$(Configuration)'=='Release'">md</LibraryType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<CprLibs Include="$(MSBuildThisFileDirectory)\$(Platform)\$(Configuration)\lib\*.lib" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CprDlls Include="$(MSBuildThisFileDirectory)\$(Platform)\$(Configuration)\bin\*.dll" />
|
||||
<None Include="@(CprDlls)">
|
||||
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<CprLibraries>@(CprLibs)</CprLibraries>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)\$(Platform)\$(Configuration)\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>$(CprLibraries);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Target Name="PlatformCheck" BeforeTargets="InjectReference" Condition="(('$(Platform)' != 'x86') AND ('$(Platform)' != 'x64')) AND ('$(Platform)' != 'Win32'))">
|
||||
<Error Text="$(MSBuildThisFileName) does not work correctly on this platform: '$(Platform)'. You need to specify platform x86, x64, or Win32." />
|
||||
</Target>
|
||||
</Project>
|
19
Src/external_dependencies/cpr/nuget/libcpr.nuspec
Normal file
19
Src/external_dependencies/cpr/nuget/libcpr.nuspec
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>libcpr</id>
|
||||
<version>$VERSION$</version>
|
||||
<title>C++ Requests: Curl for People</title>
|
||||
<authors>Simon Berger</authors>
|
||||
<owners>Fabian Sauter, Kilian Traub, many other libcpr contributors</owners>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<icon>resources/cpr.png</icon>
|
||||
<readme>README.md</readme>
|
||||
<projectUrl>https://github.com/libcpr</projectUrl>
|
||||
<description>C++ Requests: Curl for People, a spiritual port of Python Requests.</description>
|
||||
<tags>Native, native</tags>
|
||||
<language>english</language>
|
||||
<repository type="git" url="https://github.com/libcpr/cpr" branch="master" commit="$COMMIT_HASH$" />
|
||||
</metadata>
|
||||
</package>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user