From 970b52897c8f7b358a14940b3c33de3267c7b7fa Mon Sep 17 00:00:00 2001 From: yhirose Date: Sat, 16 Nov 2024 02:09:52 -0500 Subject: [PATCH] Fix #1980 Fix #1980 --- .github/workflows/test.yaml | 42 ++++++++++++++++++++++++++++--------- httplib.h | 24 ++++++++++++++++++--- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index cf2104f..3d84808 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -11,7 +11,7 @@ jobs: - name: install libraries run: sudo apt-get update && sudo apt-get install -y libbrotli-dev libcurl4-openssl-dev - name: build and run tests - run: cd test && make -j4 + run: cd test && make - name: run fuzz test target run: cd test && make fuzz_test @@ -21,23 +21,45 @@ jobs: - name: checkout uses: actions/checkout@v4 - name: build and run tests - run: | - cd test && make -j2 + run: cd test && make + - name: run fuzz test target + run: cd test && make fuzz_test windows: runs-on: windows-latest steps: - - name: prepare git for checkout on windows + - name: Prepare Git for Checkout on Windows run: | git config --global core.autocrlf false git config --global core.eol lf - - name: checkout + - name: Checkout uses: actions/checkout@v4 - - name: setup msbuild on windows + - name: Export GitHub Actions cache environment variables + uses: actions/github-script@v7 + with: + script: | + core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); + core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); + - name: Setup msbuild on windows uses: microsoft/setup-msbuild@v2 - - name: make-windows + - name: Install libraries run: | - cd test - msbuild.exe test.sln /verbosity:minimal /t:Build "/p:Configuration=Release;Platform=x64" - x64\Release\test.exe + vcpkg install gtest curl zlib brotli + choco install openssl + - name: Configure CMake with SSL + run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON + - name: Build with with SSL + run: cmake --build build --config Release + - name: Run tests with SSL + run: ctest --output-on-failure --test-dir build -C Release + + - name: Configure CMake without SSL + run: cmake -B build-no-ssl -S . -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DHTTPLIB_TEST=ON -DHTTPLIB_REQUIRE_OPENSSL=ON -DHTTPLIB_REQUIRE_ZLIB=ON -DHTTPLIB_REQUIRE_BROTLI=ON + - name: Build without SSL + run: cmake --build build-no-ssl --config Release + - name: Run tests without SSL + run: ctest --output-on-failure --test-dir build-no-ssl -C Release + env: + VCPKG_ROOT: "C:/vcpkg" + VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" diff --git a/httplib.h b/httplib.h index e50ad45..f3835ee 100644 --- a/httplib.h +++ b/httplib.h @@ -1582,6 +1582,9 @@ private: bool send_(Request &req, Response &res, Error &error); Result send_(Request &&req); +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + bool is_ssl_peer_could_be_closed(SSL *ssl) const; +#endif socket_t create_client_socket(Error &error) const; bool read_response_line(Stream &strm, const Request &req, Response &res) const; @@ -7415,6 +7418,14 @@ inline bool ClientImpl::send(Request &req, Response &res, Error &error) { return ret; } +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT +inline bool ClientImpl::is_ssl_peer_could_be_closed(SSL *ssl) const { + char buf[1]; + return !SSL_peek(ssl, buf, 1) && + SSL_get_error(ssl, 0) == SSL_ERROR_ZERO_RETURN; +} +#endif + inline bool ClientImpl::send_(Request &req, Response &res, Error &error) { { std::lock_guard guard(socket_mutex_); @@ -7426,6 +7437,15 @@ inline bool ClientImpl::send_(Request &req, Response &res, Error &error) { auto is_alive = false; if (socket_.is_open()) { is_alive = detail::is_socket_alive(socket_.sock); + +#ifdef CPPHTTPLIB_OPENSSL_SUPPORT + if (is_alive && is_ssl()) { + if (is_ssl_peer_could_be_closed(socket_.ssl)) { + is_alive = false; + } + } +#endif + if (!is_alive) { // Attempt to avoid sigpipe by shutting down nongracefully if it seems // like the other side has already closed the connection Also, there @@ -7922,9 +7942,7 @@ inline bool ClientImpl::process_request(Stream &strm, Request &req, if (is_ssl()) { auto is_proxy_enabled = !proxy_host_.empty() && proxy_port_ != -1; if (!is_proxy_enabled) { - char buf[1]; - if (SSL_peek(socket_.ssl, buf, 1) == 0 && - SSL_get_error(socket_.ssl, 0) == SSL_ERROR_ZERO_RETURN) { + if (is_ssl_peer_could_be_closed(socket_.ssl)) { error = Error::SSLPeerCouldBeClosed_; return false; }