Ver Fonte

Fix 'no TLS' problem with RequestWithoutContentLengthOrTransferEncoding

yhirose há 1 mês atrás
pai
commit
02e4c53685
2 ficheiros alterados com 21 adições e 13 exclusões
  1. 18 13
      httplib.h
  2. 3 0
      justfile

+ 18 - 13
httplib.h

@@ -9869,20 +9869,25 @@ inline bool Server::read_content_core(
         payload_max_length_ < (std::numeric_limits<size_t>::max)()) {
       socket_t s = strm.socket();
       if (s != INVALID_SOCKET) {
-        // Peek to check if there is any pending data
-        char peekbuf[1];
-        ssize_t n = ::recv(s, peekbuf, 1, MSG_PEEK);
-        if (n > 0) {
-          // There is data, so read it with payload limit enforcement
-          auto result = detail::read_content_without_length(
-              strm, payload_max_length_, out);
-          if (result == detail::ReadContentResult::PayloadTooLarge) {
-            res.status = StatusCode::PayloadTooLarge_413;
-            return false;
-          } else if (result != detail::ReadContentResult::Success) {
-            return false;
+        // Use a non-blocking check to see if there is any pending data.
+        // A blocking recv(MSG_PEEK) would deadlock when the client is
+        // waiting for the response (e.g. POST with Connection: close and
+        // no body).
+        if (detail::select_read(s, 0, 0) > 0) {
+          char peekbuf[1];
+          ssize_t n = ::recv(s, peekbuf, 1, MSG_PEEK);
+          if (n > 0) {
+            // There is data, so read it with payload limit enforcement
+            auto result = detail::read_content_without_length(
+                strm, payload_max_length_, out);
+            if (result == detail::ReadContentResult::PayloadTooLarge) {
+              res.status = StatusCode::PayloadTooLarge_413;
+              return false;
+            } else if (result != detail::ReadContentResult::Success) {
+              return false;
+            }
+            return true;
           }
-          return true;
         }
       }
     }

+ 3 - 0
justfile

@@ -13,6 +13,9 @@ mbedtls:
     @(cd test && make test_mbedtls && LSAN_OPTIONS=suppressions=lsan_suppressions.txt ./test_mbedtls)
     @(cd test && make proxy_mbedtls)
 
+no_tls:
+    @(cd test && make test_no_tls && ./test_no_tls)
+
 fuzz:
     @(cd test && make fuzz_test)