Browse Source

Fix #1980

Fix #1980
yhirose 1 year ago
parent
commit
970b52897c
2 changed files with 53 additions and 13 deletions
  1. 32 10
      .github/workflows/test.yaml
  2. 21 3
      httplib.h

+ 32 - 10
.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"

+ 21 - 3
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<std::mutex> 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;
       }