Преглед изворни кода

Enhance early response handling for large requests with long URIs on Windows

yhirose пре 2 недеља
родитељ
комит
278e4ca56a
1 измењених фајлова са 11 додато и 2 уклоњено
  1. 11 2
      httplib.h

+ 11 - 2
httplib.h

@@ -11025,15 +11025,24 @@ inline bool ClientImpl::write_request(Stream &strm, Request &req,
   // request bodies to avoid interfering with normal small requests and
   // request bodies to avoid interfering with normal small requests and
   // reduce side-effects. Poll briefly (up to 50ms) for an early response.
   // reduce side-effects. Poll briefly (up to 50ms) for an early response.
 #if defined(_WIN32)
 #if defined(_WIN32)
-  if (req.body.size() > (1u << 20)) { // > 1MB
+  if (req.body.size() > (1u << 20) &&
+      req.path.size() >
+          CPPHTTPLIB_REQUEST_URI_MAX_LENGTH) { // > 1MB && long URI
     auto start = std::chrono::high_resolution_clock::now();
     auto start = std::chrono::high_resolution_clock::now();
     const auto max_wait_ms = 50;
     const auto max_wait_ms = 50;
     for (;;) {
     for (;;) {
-      if (strm.is_readable()) { return false; }
       auto sock = strm.socket();
       auto sock = strm.socket();
+      // Prefer socket-level readiness to avoid SSL_pending() false-positives
+      // from SSL internals. If the underlying socket is readable, assume an
+      // early response may be present.
       if (sock != INVALID_SOCKET && detail::select_read(sock, 0, 0) > 0) {
       if (sock != INVALID_SOCKET && detail::select_read(sock, 0, 0) > 0) {
         return false;
         return false;
       }
       }
+      // Fallback to stream-level check for non-socket streams or when the
+      // socket isn't reporting readable. Avoid using `is_readable()` for
+      // SSL, since `SSL_pending()` may report buffered records that do not
+      // indicate a complete application-level response yet.
+      if (!is_ssl() && strm.is_readable()) { return false; }
       auto now = std::chrono::high_resolution_clock::now();
       auto now = std::chrono::high_resolution_clock::now();
       auto elapsed =
       auto elapsed =
           std::chrono::duration_cast<std::chrono::milliseconds>(now - start)
           std::chrono::duration_cast<std::chrono::milliseconds>(now - start)