diff --git a/.clang-tidy b/.clang-tidy index 7d9297732..e950962a5 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -34,7 +34,9 @@ Checks: '*, -modernize-return-braced-init-list, -cppcoreguidelines-avoid-magic-numbers, -readability-magic-numbers, --cppcoreguidelines-avoid-do-while +-cppcoreguidelines-avoid-do-while, +-cppcoreguidelines-rvalue-reference-param-not-moved, +-misc-header-include-cycle ' WarningsAsErrors: '*' HeaderFilterRegex: 'src/*.hpp' diff --git a/.github/workflows/build-deb.yml b/.github/workflows/build-deb.yml index 0f909a3d0..ccd2049a5 100644 --- a/.github/workflows/build-deb.yml +++ b/.github/workflows/build-deb.yml @@ -1,9 +1,12 @@ name: Build Debian Package on: push: - tags: - - 1.** - pull_request: + tags: [ '[0-9]+.[0-9]+.[0-9]+' ] + workflow_dispatch: + inputs: + version: + description: 'The optional semantic version number. If not supplied the branch/tag will be used.' + type: string jobs: package-ubuntu-latest-amd64: @@ -21,12 +24,26 @@ jobs: - name: "Install cpr dependencies" run: sudo apt install -y libssl-dev libcurl4-openssl-dev - name: "Install building tools" - run: sudo apt install cmake debmake devscripts debhelper - + run: sudo apt install -y cmake debmake devscripts debhelper + # Set version number + - name: Set version based on input + if: ${{ inputs.version }} + run: echo "RELEASE_VERSION=${{ inputs.version }}" >> "$GITHUB_ENV" + - name: Set version based on ref + if: ${{ !inputs.version }} + run: | + mkdir -p cpr/build + pushd cpr/build + cmake .. -DCPR_BUILD_VERSION_OUTPUT_ONLY=ON + echo "RELEASE_VERSION=$(cat version.txt)" >> $GITHUB_ENV + popd + rm -rf cpr/build + - name: Print Version + run: echo "deb version will be '${{ env.RELEASE_VERSION }}'" # Build package of runtime library - name: "Package build of runtime library" env: - VERSION: ${{ github.ref_name }} + VERSION: ${{ env.RELEASE_VERSION }} run: bash cpr/package-build/build-package.sh cpr - name: "Upload deb-packages" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e71330897..c9bc8f7bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,18 @@ name: CI on: [push, workflow_dispatch, pull_request] # Trigger for every push as well as for every pull request. Yes, this will run stuff twice in case we create a PR from inside this repo. I'm open for better solutions, where I do not have to specify each brach individually for the 'push' trigger. +env: + # Enable verbose output. + # Repeat up to 5 times to deal with flaky tests. + CTEST_OPTIONS: "-V --repeat until-pass:5" + # The OpenSSL path for CI runs. Found via 'brew info openssl'. + MACOS_OPENSSL_ROOT_DIR: "/opt/homebrew/Cellar/openssl@3/3.3.0" + jobs: ubuntu-clang-openssl: strategy: matrix: - container: ["ubuntu:18.04", "ubuntu:20.04", "ubuntu:22.04", "ubuntu:23.04"] + container: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:23.04", "ubuntu:24.04"] systemCurl: [ON, OFF] buildType: [Debug, Release] runs-on: ubuntu-latest @@ -18,7 +25,7 @@ jobs: env: DEBIAN_FRONTEND: noninteractive - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v1.13 + uses: jwlawson/actions-setup-cmake@v1.14 with: cmake-version: '3.22.x' - name: Checkout @@ -37,12 +44,12 @@ jobs: cxx: clang++ build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} ubuntu-gcc-openssl: strategy: matrix: - container: ["ubuntu:18.04", "ubuntu:20.04", "ubuntu:22.04", "ubuntu:23.04"] + container: ["ubuntu:20.04", "ubuntu:22.04", "ubuntu:23.04", "ubuntu:24.04"] systemCurl: [ON, OFF] buildType: [Debug, Release] runs-on: ubuntu-latest @@ -55,7 +62,7 @@ jobs: env: DEBIAN_FRONTEND: noninteractive - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v1.13 + uses: jwlawson/actions-setup-cmake@v1.14 with: cmake-version: '3.22.x' - name: Checkout @@ -74,7 +81,7 @@ jobs: cxx: g++ build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} ubuntu-gcc-mbedtls: runs-on: ubuntu-latest @@ -86,7 +93,7 @@ jobs: env: DEBIAN_FRONTEND: noninteractive - name: Setup cmake - uses: jwlawson/actions-setup-cmake@v1.13 + uses: jwlawson/actions-setup-cmake@v1.14 with: cmake-version: '3.22.x' - name: Checkout @@ -104,7 +111,7 @@ jobs: cxx: g++ build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} fedora-clang-openssl: strategy: @@ -133,7 +140,7 @@ jobs: cxx: clang++ build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} fedora-gcc-openssl: strategy: @@ -164,7 +171,7 @@ jobs: cxx: g++ build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} fedora-gcc-ssl-sanitizer: strategy: @@ -191,7 +198,7 @@ jobs: cxx: g++ build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} windows-msvc-ssl: strategy: @@ -212,7 +219,7 @@ jobs: source-dir: ${{ github.workspace }} build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} windows-msvc-openssl: runs-on: windows-latest @@ -233,28 +240,25 @@ jobs: source-dir: ${{ github.workspace }} build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} macos-clang-openssl: runs-on: macos-latest steps: - name: Install OpenSSL - run: | - brew install openssl - echo 'export PATH="/usr/local/opt/openssl@3/bin:$PATH"' >> /Users/runner/.bash_profile - source ~/.bash_profile - export LDFLAGS="-L/usr/local/opt/openssl@3/lib" - export CPPFLAGS="-I/usr/local/opt/openssl@3/include" - export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig" + run: brew install openssl - name: Checkout - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v3 - name: "Build & Test" env: CPR_BUILD_TESTS: ON CPR_BUILD_TESTS_SSL: ON CPR_FORCE_OPENSSL_BACKEND: ON - OPENSSL_ROOT_DIR: "/usr/local/opt/openssl@3" - OPENSSL_LIBRARIES: "/usr/local/opt/openssl@3/lib" + OPENSSL_ROOT_DIR: "${{ env.MACOS_OPENSSL_ROOT_DIR }}" + OPENSSL_LIBRARIES: "${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib" + LDFLAGS: "-L${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib" + CPPFLAGS: "-I${{ env.MACOS_OPENSSL_ROOT_DIR }}/include" + PKG_CONFIG_PATH: "${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib/pkgconfig" uses: ashutoshvarma/action-cmake-build@master with: build-dir: ${{ github.workspace }}/build @@ -263,7 +267,7 @@ jobs: cxx: clang++ build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} macos-clang-ssl: strategy: @@ -285,7 +289,7 @@ jobs: cxx: clang++ build-type: ${{ matrix.buildType }} run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} macos-clang-darwinssl: runs-on: macos-latest @@ -305,7 +309,7 @@ jobs: cxx: clang++ build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} macos-clang-openssl-boost: runs-on: macos-latest @@ -313,23 +317,20 @@ jobs: - name: Install Boost run: brew install boost - name: Install OpenSSL - run: | - brew install openssl - echo 'export PATH="/usr/local/opt/openssl@3/bin:$PATH"' >> /Users/runner/.bash_profile - source ~/.bash_profile + run: brew install openssl - name: Checkout - uses: actions/checkout@v3.1.0 + uses: actions/checkout@v3 - name: "Build & Test" env: CPR_BUILD_TESTS: ON - CPR_BUILD_TESTS_SSL: OFF - CPR_USE_BOOST_FILESYSTEM: ON + CPR_BUILD_TESTS_SSL: ON CPR_FORCE_OPENSSL_BACKEND: ON - OPENSSL_ROOT_DIR: "/usr/local/opt/openssl@3" - OPENSSL_LIBRARIES: "/usr/local/opt/openssl@3/lib" - LDFLAGS: "-L/usr/local/opt/openssl@3/lib" - CPPFLAGS: "-I/usr/local/opt/openssl@3/include" - PKG_CONFIG_PATH: "/usr/local/opt/openssl@3/lib/pkgconfig" + CPR_USE_BOOST_FILESYSTEM: ON + OPENSSL_ROOT_DIR: "${{ env.MACOS_OPENSSL_ROOT_DIR }}" + OPENSSL_LIBRARIES: "${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib" + LDFLAGS: "-L${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib" + CPPFLAGS: "-I${{ env.MACOS_OPENSSL_ROOT_DIR }}/include" + PKG_CONFIG_PATH: "${{ env.MACOS_OPENSSL_ROOT_DIR }}/lib/pkgconfig" uses: ashutoshvarma/action-cmake-build@master with: build-dir: ${{ github.workspace }}/build @@ -338,4 +339,4 @@ jobs: cxx: clang++ build-type: Release run-test: true - ctest-options: -V + ctest-options: ${{ env.CTEST_OPTIONS }} diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index ec39e6bf4..7c80d5e34 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -9,11 +9,9 @@ jobs: steps: - name: Update package list run: sudo dnf update -y - - name: Install dependencies - run: sudo dnf install -y openssl-devel cmake git gcc clang ninja-build - - name: Install clang-tidy + - name: Install clang-format run: sudo dnf install -y clang-tools-extra - name: Checkout uses: actions/checkout@v3 - name: Check format - uses: RafikFarhad/clang-format-github-action@v2.1.0 \ No newline at end of file + run: bash scripts/check_clang_format.sh diff --git a/.gitignore b/.gitignore index 9ca21347c..6d731f780 100644 --- a/.gitignore +++ b/.gitignore @@ -46,8 +46,10 @@ _site/ .ycm_extra_conf.py* # VSCode -.vscode/ +.vscode/* +!.vscode/tasks.json .vs/ +!.vs/tasks.json # clangd .cache/ diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..cf1091bf2 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,62 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "🗑️ Delete build dir", + "type": "shell", + "command": "${workspaceFolder}/scripts/delete_build_dir.sh", + "problemMatcher": [], + "group": { + "kind": "build" + }, + "presentation": { + "clear": true + }, + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "📝 Run clang-format", + "type": "shell", + "command": "${workspaceFolder}/scripts/run_clang_format.sh", + "args": [ + "cpr", + "include", + "test" + ], + "problemMatcher": [], + "group": { + "kind": "build" + }, + "presentation": { + "clear": true + }, + "options": { + "cwd": "${workspaceFolder}" + } + }, + { + "label": "📑 Check clang-format", + "type": "shell", + "command": "${workspaceFolder}/scripts/check_clang_format.sh", + "args": [ + "cpr", + "include", + "test" + ], + "problemMatcher": [], + "group": { + "kind": "build" + }, + "presentation": { + "clear": true + }, + "options": { + "cwd": "${workspaceFolder}" + } + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 80386795f..1bc0967b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.15) -project(cpr VERSION 1.9.7 LANGUAGES CXX) +project(cpr VERSION 1.9.8 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") @@ -47,6 +47,7 @@ cpr_option(CPR_ENABLE_CPPCHECK "Set to ON to enable Cppcheck static analysis. Re 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_BUILD_VERSION_OUTPUT_ONLY "Set to ON to only export the version into 'build/version.txt' and exit" OFF) cpr_option(CPR_DEBUG_SANITIZER_FLAG_THREAD "Enables the ThreadSanitizer for debug builds." OFF) cpr_option(CPR_DEBUG_SANITIZER_FLAG_ADDR "Enables the AddressSanitizer for debug builds." OFF) cpr_option(CPR_DEBUG_SANITIZER_FLAG_LEAK "Enables the LeakSanitizer for debug builds." OFF) @@ -54,6 +55,13 @@ cpr_option(CPR_DEBUG_SANITIZER_FLAG_UB "Enables the UndefinedBehaviorSanitizer f cpr_option(CPR_DEBUG_SANITIZER_FLAG_ALL "Enables all sanitizers for debug builds except the ThreadSanitizer since it is incompatible with the other sanitizers." OFF) message(STATUS "=======================================================") +# Save the project version as txt file for deb and NuGet builds +if(CPR_BUILD_VERSION_OUTPUT_ONLY) + message(STATUS "Printing version and exiting...") + file(WRITE "${CMAKE_BINARY_DIR}/version.txt" "${PROJECT_VERSION}") + return() +endif() + include(GNUInstallDirs) include(FetchContent) include(cmake/code_coverage.cmake) @@ -149,6 +157,7 @@ if(CPR_FORCE_USE_SYSTEM_CURL) 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.") @@ -169,6 +178,11 @@ if(CPR_FORCE_USE_SYSTEM_CURL) message(FATAL_ERROR "Curl not found on this system. To use the build in version set CPR_FORCE_USE_SYSTEM_CURL to OFF.") endif() endif() + + # Check for the minimum supported curl version + if(NOT (CURL_VERSION_STRING VERSION_GREATER_EQUAL "7.64.0")) + message(FATAL_ERROR "Your system curl version (${CURL_VERSION_STRING}) is too old! curl >= 7.64.0 is required. Update your curl version, or use the build in curl version e.g. via `cmake .. -DCPR_USE_SYSTEM_CURL=OFF` during CMake configure.") + endif() else() message(STATUS "Configuring build in curl...") @@ -232,14 +246,23 @@ else() 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-8_4_0/curl-8.4.0.tar.xz - URL_HASH SHA256=16c62a9c4af0f703d28bda6d7bbf37ba47055ad3414d70dec63e2e6336f2a82d # the file hash for curl-8.4.0.tar.xz + URL https://github.com/curl/curl/releases/download/curl-8_10_1/curl-8.10.1.tar.xz + URL_HASH SHA256=73a4b0e99596a09fa5924a4fb7e4b995a85fda0d18a2c02ab9cf134bebce04ee # the file hash for curl-8.10.1.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) endif() +# Depending on which version of libcurl we are using the CMake target is called differently +if(TARGET libcurl) + # Old curl CMake target name + set(CURL_LIB libcurl) +else() + # New curl CMake target name + set(CURL_LIB CURL::libcurl) +endif() + # GTest configuration if(CPR_BUILD_TESTS) if(CPR_USE_SYSTEM_GTEST) diff --git a/README.md b/README.md index 9db57c9ac..face1b4f7 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ The only explicit requirements are: * a `C++11` compatible compiler such as Clang or GCC. The minimum required version of GCC is unknown, so if anyone has trouble building this library with a specific version of GCC, do let me know * If you would like to perform https requests `OpenSSL` and its development libraries are required. +* If you do not use the build in version of [curl](https://github.com/curl/curl) but instead use your systems version, make sure you use a version `>= 7.64.0`. Lower versions are not supported. This means you need Debian `>= 10` or Ubuntu `>= 20.04 LTS`. ## Building cpr - Using vcpkg diff --git a/cpr/CMakeLists.txt b/cpr/CMakeLists.txt index 8f68498c0..2a21b46c7 100644 --- a/cpr/CMakeLists.txt +++ b/cpr/CMakeLists.txt @@ -12,8 +12,6 @@ add_library(cpr curlholder.cpp error.cpp multipart.cpp - parameters.cpp - payload.cpp proxies.cpp proxyauth.cpp session.cpp @@ -28,7 +26,7 @@ add_library(cpr add_library(cpr::cpr ALIAS cpr) -target_link_libraries(cpr PUBLIC CURL::libcurl) # todo should be private, but first dependencies in ssl_options need to be removed +target_link_libraries(cpr PUBLIC ${CURL_LIB}) # todo should be private, but first dependencies 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") diff --git a/cpr/accept_encoding.cpp b/cpr/accept_encoding.cpp index f6449d5ff..234b3548b 100644 --- a/cpr/accept_encoding.cpp +++ b/cpr/accept_encoding.cpp @@ -1,8 +1,11 @@ #include "cpr/accept_encoding.h" #include +#include #include #include +#include +#include namespace cpr { diff --git a/cpr/bearer.cpp b/cpr/bearer.cpp index 02bd728bc..041b6c187 100644 --- a/cpr/bearer.cpp +++ b/cpr/bearer.cpp @@ -1,5 +1,6 @@ #include "cpr/bearer.h" #include "cpr/util.h" +#include namespace cpr { // Only supported with libcurl >= 7.61.0. diff --git a/cpr/cert_info.cpp b/cpr/cert_info.cpp index a77a02771..410648c04 100644 --- a/cpr/cert_info.cpp +++ b/cpr/cert_info.cpp @@ -1,4 +1,6 @@ #include "cpr/cert_info.h" +#include +#include namespace cpr { diff --git a/cpr/cookies.cpp b/cpr/cookies.cpp index 41e12469a..c71b0e28f 100644 --- a/cpr/cookies.cpp +++ b/cpr/cookies.cpp @@ -1,6 +1,10 @@ #include "cpr/cookies.h" +#include "cpr/curlholder.h" +#include #include #include +#include +#include namespace cpr { const std::string Cookie::GetDomain() const { diff --git a/cpr/cprtypes.cpp b/cpr/cprtypes.cpp index 7927b03bd..43df13491 100644 --- a/cpr/cprtypes.cpp +++ b/cpr/cprtypes.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace cpr { bool CaseInsensitiveCompare::operator()(const std::string& a, const std::string& b) const noexcept { diff --git a/cpr/curl_container.cpp b/cpr/curl_container.cpp index c90b777a3..911afc5cf 100644 --- a/cpr/curl_container.cpp +++ b/cpr/curl_container.cpp @@ -1,6 +1,9 @@ #include "cpr/curl_container.h" +#include "cpr/curlholder.h" #include +#include #include +#include namespace cpr { diff --git a/cpr/curlholder.cpp b/cpr/curlholder.cpp index 0dcd6d763..cee8897c0 100644 --- a/cpr/curlholder.cpp +++ b/cpr/curlholder.cpp @@ -1,5 +1,8 @@ #include "cpr/curlholder.h" #include +#include +#include +#include namespace cpr { CurlHolder::CurlHolder() { diff --git a/cpr/error.cpp b/cpr/error.cpp index f085051fb..ad728bb9d 100644 --- a/cpr/error.cpp +++ b/cpr/error.cpp @@ -1,6 +1,8 @@ #include "cpr/error.h" +#include #include +#include namespace cpr { ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) { @@ -65,4 +67,4 @@ ErrorCode Error::getErrorCodeForCurlError(std::int32_t curl_code) { } } -} // namespace cpr +} // namespace cpr \ No newline at end of file diff --git a/cpr/interceptor.cpp b/cpr/interceptor.cpp index c23c4b743..8a8d91222 100644 --- a/cpr/interceptor.cpp +++ b/cpr/interceptor.cpp @@ -1,6 +1,10 @@ #include "cpr/interceptor.h" +#include "cpr/callback.h" +#include "cpr/response.h" +#include "cpr/session.h" + +#include -#include namespace cpr { diff --git a/cpr/multipart.cpp b/cpr/multipart.cpp index d82d9a41e..f5cb32832 100644 --- a/cpr/multipart.cpp +++ b/cpr/multipart.cpp @@ -1,4 +1,5 @@ #include "cpr/multipart.h" +#include namespace cpr { Multipart::Multipart(const std::initializer_list& p_parts) : parts{p_parts} {} diff --git a/cpr/parameters.cpp b/cpr/parameters.cpp deleted file mode 100644 index ed62d2bae..000000000 --- a/cpr/parameters.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "cpr/parameters.h" - -namespace cpr { -} // namespace cpr diff --git a/cpr/payload.cpp b/cpr/payload.cpp deleted file mode 100644 index c3265c1ac..000000000 --- a/cpr/payload.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include "cpr/payload.h" - -namespace cpr { -} // namespace cpr diff --git a/cpr/redirect.cpp b/cpr/redirect.cpp index f95dc7567..3be96960b 100644 --- a/cpr/redirect.cpp +++ b/cpr/redirect.cpp @@ -1,4 +1,5 @@ #include "cpr/redirect.h" +#include namespace cpr { PostRedirectFlags operator|(PostRedirectFlags lhs, PostRedirectFlags rhs) { diff --git a/cpr/response.cpp b/cpr/response.cpp index c9c73a24d..70b831f35 100644 --- a/cpr/response.cpp +++ b/cpr/response.cpp @@ -1,4 +1,19 @@ #include "cpr/response.h" +#include +#include +#include +#include +#include + +#include "cpr/cert_info.h" +#include "cpr/cookies.h" +#include "cpr/cprtypes.h" +#include "cpr/curlholder.h" +#include "cpr/error.h" +#include "cpr/util.h" + +#include +#include namespace cpr { @@ -11,7 +26,7 @@ Response::Response(std::shared_ptr curl, std::string&& p_text, std:: char* url_string{nullptr}; curl_easy_getinfo(curl_->handle, CURLINFO_EFFECTIVE_URL, &url_string); url = Url(url_string); -#if LIBCURL_VERSION_NUM >= 0x073700 // 7.55.0 +#if LIBCURL_VERSION_NUM >= 0x073700 // 7.55.0 curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_DOWNLOAD_T, &downloaded_bytes); curl_easy_getinfo(curl_->handle, CURLINFO_SIZE_UPLOAD_T, &uploaded_bytes); #else diff --git a/cpr/session.cpp b/cpr/session.cpp index dace5334a..c693c0216 100644 --- a/cpr/session.cpp +++ b/cpr/session.cpp @@ -1,19 +1,47 @@ #include "cpr/session.h" -#include +#include +#include #include #include #include -#include +#include #include #include +#include #include +#include +#include #include "cpr/async.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/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/payload.h" +#include "cpr/range.h" +#include "cpr/redirect.h" +#include "cpr/reserve_size.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/util.h" +#include "cpr/verbose.h" #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION #include "cpr/ssl_ctx.h" @@ -137,9 +165,10 @@ Response Session::makeDownloadRequest() { curl_easy_getinfo(curl_->handle, CURLINFO_COOKIELIST, &raw_cookies); Cookies cookies = util::parseCookies(raw_cookies); curl_slist_free_all(raw_cookies); + std::string errorMsg = curl_->error.data(); - return Response(curl_, "", std::move(header_string), std::move(cookies), Error(curl_error, std::move(errorMsg))); + return Response(curl_, "", std::move(header_string_), std::move(cookies), Error(curl_error, std::move(errorMsg))); } void Session::prepareCommon() { @@ -326,14 +355,14 @@ void Session::SetUserAgent(const UserAgent& ua) { 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(content.length())); + curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(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(content.length())); + curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(content.length())); curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, content.c_str()); } @@ -425,13 +454,13 @@ void Session::SetCookies(const Cookies& cookies) { void Session::SetBody(const Body& body) { hasBodyOrPayload_ = true; - curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(body.str().length())); + curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(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(body.str().length())); + curl_easy_setopt(curl_->handle, CURLOPT_POSTFIELDSIZE_LARGE, static_cast(body.str().length())); curl_easy_setopt(curl_->handle, CURLOPT_COPYPOSTFIELDS, body.c_str()); } diff --git a/cpr/ssl_ctx.cpp b/cpr/ssl_ctx.cpp index a8d14eb84..75d4402db 100644 --- a/cpr/ssl_ctx.cpp +++ b/cpr/ssl_ctx.cpp @@ -1,13 +1,28 @@ - #include "cpr/ssl_ctx.h" +#include "cpr/ssl_options.h" +#include +#include #if SUPPORT_CURLOPT_SSL_CTX_FUNCTION #ifdef OPENSSL_BACKEND_USED -#include -#include +#include +#include #include +#include +#include + +// openssl/types.h was added in later version of openssl and is therefore not always available. +// This is for example the case on Ubuntu 20.04. +// We try to include it if available to satisfy clang-tidy. +// Ref: https://github.com/openssl/openssl/commit/50cd4768c6b89c757645f28519236bb989216f8d +// cppcheck-suppress preprocessorErrorDirective +#if __has_include() +#include +#else +#include +#endif namespace cpr { diff --git a/cpr/threadpool.cpp b/cpr/threadpool.cpp index 8ab1ee820..bd03d2ab7 100644 --- a/cpr/threadpool.cpp +++ b/cpr/threadpool.cpp @@ -1,4 +1,10 @@ #include "cpr/threadpool.h" +#include +#include +#include +#include +#include +#include namespace cpr { diff --git a/cpr/timeout.cpp b/cpr/timeout.cpp index 5bcd73b2f..7074db9b0 100644 --- a/cpr/timeout.cpp +++ b/cpr/timeout.cpp @@ -1,5 +1,6 @@ #include "cpr/timeout.h" +#include #include #include #include diff --git a/cpr/util.cpp b/cpr/util.cpp index 5b9b75709..4aa5deb09 100644 --- a/cpr/util.cpp +++ b/cpr/util.cpp @@ -1,17 +1,23 @@ #include "cpr/util.h" +#include "cpr/callback.h" +#include "cpr/cookies.h" +#include "cpr/cprtypes.h" +#include "cpr/curlholder.h" #include #include #include #include #include +#include #include -#include #include #include #include #include +#include + #if defined(_Win32) #include #else @@ -34,7 +40,7 @@ namespace cpr { namespace util { -enum class CurlHTTPCookieField : size_t { +enum class CurlHTTPCookieField : uint8_t { Domain = 0, IncludeSubdomains, Path, @@ -102,7 +108,7 @@ Header parseHeader(const std::string& headers, std::string* status_line, std::st header.clear(); } - if (line.length() > 0) { + if (!line.empty()) { const size_t found = line.find(':'); if (found != std::string::npos) { std::string value = line.substr(found + 1); @@ -155,11 +161,7 @@ size_t writeUserFunction(char* ptr, size_t size, size_t nmemb, const WriteCallba 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 +int progressUserFunction(const ProgressCallback* progress, cpr_pf_arg_t dltotal, cpr_pf_arg_t dlnow, cpr_pf_arg_t ultotal, cpr_pf_arg_t ulnow) { return (*progress)(dltotal, dlnow, ultotal, ulnow) ? 0 : 1; } diff --git a/include/cpr/api.h b/include/cpr/api.h index 9090a56da..2ef16d1e8 100644 --- a/include/cpr/api.h +++ b/include/cpr/api.h @@ -63,16 +63,14 @@ Response Get(Ts&&... ts) { // Get async methods template AsyncResponse GetAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Get(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Get(std::move(ts_inner)...); }, std::move(ts)...); } // Get callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto GetCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Get(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -86,16 +84,14 @@ Response Post(Ts&&... ts) { // Post async methods template AsyncResponse PostAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Post(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Post(std::move(ts_inner)...); }, std::move(ts)...); } // Post callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto PostCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Post(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -109,16 +105,14 @@ Response Put(Ts&&... ts) { // Put async methods template AsyncResponse PutAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Put(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Put(std::move(ts_inner)...); }, std::move(ts)...); } // Put callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto PutCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Put(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -132,16 +126,14 @@ Response Head(Ts&&... ts) { // Head async methods template AsyncResponse HeadAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Head(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Head(std::move(ts_inner)...); }, std::move(ts)...); } // Head callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto HeadCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Head(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -155,16 +147,14 @@ Response Delete(Ts&&... ts) { // Delete async methods template AsyncResponse DeleteAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Delete(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Delete(std::move(ts_inner)...); }, std::move(ts)...); } // Delete callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto DeleteCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Delete(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -178,16 +168,14 @@ Response Options(Ts&&... ts) { // Options async methods template AsyncResponse OptionsAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Options(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Options(std::move(ts_inner)...); }, std::move(ts)...); } // Options callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto OptionsCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Options(std::move(ts_inner)...)); }, std::move(then), std::move(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 @@ -201,16 +189,14 @@ Response Patch(Ts&&... ts) { // Patch async methods template AsyncResponse PatchAsync(Ts... ts) { - return cpr::async( - [](Ts... ts_inner) { return Patch(std::move(ts_inner)...); }, std::move(ts)...); + return cpr::async([](Ts... ts_inner) { return Patch(std::move(ts_inner)...); }, std::move(ts)...); } // Patch callback methods template // NOLINTNEXTLINE(fuchsia-trailing-return) auto PatchCallback(Then then, Ts... ts) -> std::future { - return cpr::async( - [](Then then_inner, Ts... ts_inner) { return then_inner(Patch(std::move(ts_inner)...)); }, std::move(then), std::move(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 diff --git a/include/cpr/body.h b/include/cpr/body.h index 04dc1c9de..6526972ea 100644 --- a/include/cpr/body.h +++ b/include/cpr/body.h @@ -2,10 +2,10 @@ #define CPR_BODY_H #include +#include #include #include #include -#include #include "cpr/buffer.h" #include "cpr/cprtypes.h" diff --git a/include/cpr/callback.h b/include/cpr/callback.h index e54c4fb1e..1442e491e 100644 --- a/include/cpr/callback.h +++ b/include/cpr/callback.h @@ -3,6 +3,7 @@ #include "cprtypes.h" +#include #include #include @@ -18,7 +19,7 @@ class ReadCallback { return callback(buffer, buffer_size, userdata); } - intptr_t userdata; + intptr_t userdata{}; cpr_off_t size{}; std::function callback; }; @@ -32,7 +33,7 @@ class HeaderCallback { return callback(std::move(header), userdata); } - intptr_t userdata; + intptr_t userdata{}; std::function callback; }; @@ -45,7 +46,7 @@ class WriteCallback { return callback(std::move(data), userdata); } - intptr_t userdata; + intptr_t userdata{}; std::function callback; }; @@ -53,13 +54,13 @@ class ProgressCallback { public: ProgressCallback() = default; // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) - ProgressCallback(std::function 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 { + ProgressCallback(std::function p_callback, intptr_t p_userdata = 0) : userdata(p_userdata), callback(std::move(p_callback)) {} + bool operator()(cpr_pf_arg_t downloadTotal, cpr_pf_arg_t downloadNow, cpr_pf_arg_t uploadTotal, cpr_pf_arg_t uploadNow) const { return callback(downloadTotal, downloadNow, uploadTotal, uploadNow, userdata); } - intptr_t userdata; - std::function callback; + intptr_t userdata{}; + std::function callback; }; class DebugCallback { @@ -80,7 +81,7 @@ class DebugCallback { callback(type, std::move(data), userdata); } - intptr_t userdata; + intptr_t userdata{}; std::function callback; }; diff --git a/include/cpr/cprtypes.h b/include/cpr/cprtypes.h index bbd2385d5..76c582063 100644 --- a/include/cpr/cprtypes.h +++ b/include/cpr/cprtypes.h @@ -4,10 +4,11 @@ #include #include #include -#include #include #include +#include + namespace cpr { /** @@ -15,6 +16,15 @@ namespace cpr { **/ using cpr_off_t = curl_off_t; +/** + * The argument type for progress functions, dependent on libcurl version + **/ +#if LIBCURL_VERSION_NUM < 0x072000 +using cpr_pf_arg_t = double; +#else +using cpr_pf_arg_t = cpr_off_t; +#endif + template class StringHolder { public: diff --git a/include/cpr/error.h b/include/cpr/error.h index bb59a4cc0..8b6c8fb7b 100644 --- a/include/cpr/error.h +++ b/include/cpr/error.h @@ -33,8 +33,8 @@ enum class ErrorCode { class Error { public: - ErrorCode code = ErrorCode::OK; - std::string message{}; + ErrorCode code{ErrorCode::OK}; + std::string message; Error() = default; diff --git a/include/cpr/redirect.h b/include/cpr/redirect.h index f57687cb9..d4c8e576b 100644 --- a/include/cpr/redirect.h +++ b/include/cpr/redirect.h @@ -72,12 +72,12 @@ class Redirect { 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){} + 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){} + 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 diff --git a/include/cpr/response.h b/include/cpr/response.h index 14c34a534..cf62c30e1 100644 --- a/include/cpr/response.h +++ b/include/cpr/response.h @@ -2,18 +2,14 @@ #define CPR_RESPONSE_H #include -#include #include #include -#include #include #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 { diff --git a/include/cpr/singleton.h b/include/cpr/singleton.h index e2ea13bb2..5a53ce511 100644 --- a/include/cpr/singleton.h +++ b/include/cpr/singleton.h @@ -4,43 +4,44 @@ #include #ifndef CPR_DISABLE_COPY -#define CPR_DISABLE_COPY(Class) \ +#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; + 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(); \ +#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(); \ + 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 diff --git a/include/cpr/util.h b/include/cpr/util.h index f35ad473d..55a9ad626 100644 --- a/include/cpr/util.h +++ b/include/cpr/util.h @@ -20,11 +20,7 @@ size_t headerUserFunction(char* ptr, size_t size, size_t nmemb, const HeaderCall 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 progressUserFunction(const ProgressCallback* progress, cpr_pf_arg_t dltotal, cpr_pf_arg_t dlnow, cpr_pf_arg_t ultotal, cpr_pf_arg_t ulnow); int debugUserFunction(CURL* handle, curl_infotype type, char* data, size_t size, const DebugCallback* debug); std::vector split(const std::string& to_split, char delimiter); std::string urlEncode(const std::string& s); diff --git a/nuget/libcpr.nuspec b/nuget/libcpr.nuspec index e47a8c08e..1169ebf4e 100644 --- a/nuget/libcpr.nuspec +++ b/nuget/libcpr.nuspec @@ -13,7 +13,7 @@ https://github.com/libcpr C++ Requests: Curl for People, a spiritual port of Python Requests. Native, native - english - + english + \ No newline at end of file diff --git a/scripts/check_clang_format.sh b/scripts/check_clang_format.sh new file mode 100755 index 000000000..488c45e79 --- /dev/null +++ b/scripts/check_clang_format.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Based on: https://gist.github.com/leilee/1d0915a583f8f29414cc21cd86e7151b +# Checks if all files are formatted based on the clang-format formatting rules. +# Execute as follows: +# ./scripts/check_clang_format.sh tests src + +printf "📑 Checking if your code fulfills all clang-format rules...\n" + +RET_CODE=0 + +function format() { + for f in $(find $@ -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cpp'); do + clang-format -i --dry-run --Werror --style=file ${f}; + ret=$? + if [ $ret -ne 0 ]; then + RET_CODE=$ret + fi + done + + echo "~~~ $@ directory checked ~~~"; +} + +# Check all of the arguments first to make sure they're all directories +for dir in "$@"; do + if [ ! -d "${dir}" ]; then + echo "${dir} is not a directory"; + else + format ${dir}; + fi +done + +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' + +if [ $RET_CODE -eq 0 ]; then + printf "✅ ${GREEN}Everything up to standard :party: ${NC}\n" +else + printf "❌ ${RED}Not up to formatting standard :sad_face: ${NC}\n" + echo "Try running run_clang_format.sh to format all files." +fi + +exit $RET_CODE \ No newline at end of file diff --git a/scripts/delete_build_dir.sh b/scripts/delete_build_dir.sh new file mode 100755 index 000000000..52d021568 --- /dev/null +++ b/scripts/delete_build_dir.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +printf "🗑️ Clearing your build directory...\n" +rm -rf build/* + +GREEN='\033[0;32m' +NC='\033[0m' + +printf "✅ ${GREEN}Done. Build directory deleted.${NC}\n" \ No newline at end of file diff --git a/scripts/run_clang_format.sh b/scripts/run_clang_format.sh new file mode 100755 index 000000000..edf116599 --- /dev/null +++ b/scripts/run_clang_format.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Based on: https://gist.github.com/leilee/1d0915a583f8f29414cc21cd86e7151b +# Run from the project root directory as follows: +# ./scripts/run_clang_format.sh tests src + +printf "📝 Running clang-format...\n" + +function format() { + for f in $(find $@ -name '*.h' -or -name '*.hpp' -or -name '*.c' -or -name '*.cpp'); do + echo "format ${f}"; + clang-format -i --style=file ${f}; + done + + echo "~~~ $@ directory formatted ~~~"; +} + +# Check all of the arguments first to make sure they're all directories +for dir in "$@"; do + if [ ! -d "${dir}" ]; then + echo "${dir} is not a directory"; + else + format ${dir}; + fi +done + +GREEN='\033[0;32m' +NC='\033[0m' + +printf "✅ ${GREEN}Done. All files were formatted (if required).${NC}\n" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8d640bec1..d9ddd8e50 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,7 +26,7 @@ macro(add_cpr_test _TEST_NAME) test_server GTest::GTest cpr::cpr - CURL::libcurl) + ${CURL_LIB}) add_test(NAME cpr_${_TEST_NAME}_tests COMMAND ${_TEST_NAME}_tests) # Group under the "tests" project folder in IDEs such as Visual Studio. set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") diff --git a/test/abstractServer.cpp b/test/abstractServer.cpp index bb8eaeb05..e32394b5a 100644 --- a/test/abstractServer.cpp +++ b/test/abstractServer.cpp @@ -132,11 +132,11 @@ bool AbstractServer::IsConnectionActive(mg_mgr* mgr, mg_connection* conn) { return false; } -uint16_t AbstractServer::GetRemotePort(const mg_connection* conn) { +uint16_t AbstractServer::GetRemotePort(const mg_connection* conn) { return (conn->rem.port >> 8) | (conn->rem.port << 8); } -uint16_t AbstractServer::GetLocalPort(const mg_connection* conn) { +uint16_t AbstractServer::GetLocalPort(const mg_connection* conn) { return (conn->loc.port >> 8) | (conn->loc.port << 8); } diff --git a/test/async_tests.cpp b/test/async_tests.cpp index 5935982e3..e0004e34c 100644 --- a/test/async_tests.cpp +++ b/test/async_tests.cpp @@ -3,8 +3,9 @@ #include #include -#include "cpr/cpr.h" +#include "cpr/api.h" +#include "cpr/response.h" #include "httpServer.hpp" using namespace cpr; @@ -15,7 +16,7 @@ bool write_data(std::string /*data*/, intptr_t /*userdata*/) { return true; } -TEST(UrlEncodedPostTests, AsyncGetTest) { +TEST(AsyncTests, AsyncGetTest) { Url url{server->GetBaseUrl() + "/hello.html"}; cpr::AsyncResponse future = cpr::GetAsync(url); std::string expected_text{"Hello world!"}; @@ -26,7 +27,7 @@ TEST(UrlEncodedPostTests, AsyncGetTest) { EXPECT_EQ(200, response.status_code); } -TEST(UrlEncodedPostTests, AsyncGetMultipleTest) { +TEST(AsyncTests, AsyncGetMultipleTest) { Url url{server->GetBaseUrl() + "/hello.html"}; std::vector responses; for (size_t i = 0; i < 10; ++i) { @@ -42,7 +43,7 @@ TEST(UrlEncodedPostTests, AsyncGetMultipleTest) { } } -TEST(UrlEncodedPostTests, AsyncGetMultipleReflectTest) { +TEST(AsyncTests, AsyncGetMultipleReflectTest) { Url url{server->GetBaseUrl() + "/hello.html"}; std::vector responses; for (size_t i = 0; i < 100; ++i) { @@ -62,7 +63,7 @@ TEST(UrlEncodedPostTests, AsyncGetMultipleReflectTest) { } } -TEST(UrlEncodedPostTests, AsyncDownloadTest) { +TEST(AsyncTests, AsyncDownloadTest) { cpr::Url url{server->GetBaseUrl() + "/download_gzip.html"}; cpr::AsyncResponse future = cpr::DownloadAsync("/tmp/aync_download", url, cpr::Header{{"Accept-Encoding", "gzip"}}, cpr::WriteCallback{write_data, 0}); cpr::Response response = future.get(); diff --git a/test/callback_tests.cpp b/test/callback_tests.cpp index 9a0ceaea8..813e4e767 100644 --- a/test/callback_tests.cpp +++ b/test/callback_tests.cpp @@ -896,7 +896,7 @@ TEST(CallbackDataTests, CallbackWriteFunctionTextTest) { TEST(CallbackDataTests, CallbackProgressFunctionCancelTest) { Url url{server->GetBaseUrl() + "/url_post.html"}; - Response response = Post(url, ProgressCallback{[](size_t /*downloadTotal*/, size_t /*downloadNow*/, size_t /*uploadTotal*/, size_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { return false; }}); + Response response = Post(url, ProgressCallback{[](cpr_pf_arg_t /*downloadTotal*/, cpr_pf_arg_t /*downloadNow*/, cpr_pf_arg_t /*uploadTotal*/, cpr_pf_arg_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { return false; }}); EXPECT_EQ(response.error.code, ErrorCode::REQUEST_CANCELLED); } @@ -905,7 +905,7 @@ TEST(CallbackDataTests, CallbackProgressFunctionTotalTest) { Body body{"x=5"}; size_t response_upload = 0; size_t response_download = 0; - Response response = Post(url, body, ProgressCallback{[&](size_t downloadTotal, size_t /*downloadNow*/, size_t uploadTotal, size_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { + Response response = Post(url, body, ProgressCallback{[&](cpr_pf_arg_t downloadTotal, cpr_pf_arg_t /*downloadNow*/, cpr_pf_arg_t uploadTotal, cpr_pf_arg_t /*uploadNow*/, intptr_t /*userdata*/) -> bool { response_upload = uploadTotal; response_download = downloadTotal; return true; diff --git a/test/get_tests.cpp b/test/get_tests.cpp index 142cd433e..ad081d59f 100644 --- a/test/get_tests.cpp +++ b/test/get_tests.cpp @@ -13,6 +13,13 @@ using namespace cpr; static HttpServer* server = new HttpServer(); +TEST(BasicTests, XXXTest) { + Url url{"https://getsolara.dev/api/endpoint.json"}; + Response response = cpr::Get(url); + EXPECT_EQ(200, response.status_code); + EXPECT_EQ(ErrorCode::OK, response.error.code); +} + TEST(BasicTests, HelloWorldTest) { Url url{server->GetBaseUrl() + "/hello.html"}; Response response = cpr::Get(url);