Index: src/blob.c ================================================================== --- src/blob.c +++ src/blob.c @@ -983,17 +983,25 @@ blob_zero(pBlob); if( nToRead<0 ){ char zBuf[10000]; while( !cgi_feof() ){ n = cgi_fread(zBuf, sizeof(zBuf)); + if( n==(size_t)-1 ){ + blob_zero(pBlob); + return -1; + } if( n>0 ){ blob_append(pBlob, zBuf, n); } } }else{ blob_resize(pBlob, nToRead); n = cgi_fread(blob_buffer(pBlob), nToRead); + if( n==(size_t)-1 ){ + blob_zero(pBlob); + return -1; + } blob_resize(pBlob, n); } return blob_size(pBlob); } Index: src/http_ssl.c ================================================================== --- src/http_ssl.c +++ src/http_ssl.c @@ -811,10 +811,11 @@ } /* ** Read cleartext bytes that have been received from the client and ** decrypted by the SSL server codec. +** Return (size_t)-1 on error. */ size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){ int n; size_t rc = 0; SslServerConn *pServer = (SslServerConn*)pServerArg; @@ -821,21 +822,28 @@ if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); } else if( BIO_eof(pServer->bio) ) return 0; while( nBuf!=rc ){ n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc)); if( n<=0 ){ - break; + int error = SSL_get_error(pServer->ssl,n); + switch( error ){ + case SSL_ERROR_NONE: + case SSL_ERROR_ZERO_RETURN: + /* Not all errors relevant with SSL_MODE_AUTO_RETRY. */ + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_CONNECT: + case SSL_ERROR_WANT_ACCEPT: + return rc; + default: + return (size_t)-1; + } }else if(n>0){ rc += n; - } -#ifdef _WIN32 - /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does - ** not require reading in a loop, returning all data in a single - ** call. If we read in a loop on Windows, SSL reads fail. Details: - ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */ - break; -#endif + /* SSL_read() returns at most 16 KB of data, so retry in this case. */ + if( n!=16384 ) break; + } } return rc; } /* Index: src/winhttp.c ================================================================== --- src/winhttp.c +++ src/winhttp.c @@ -364,10 +364,11 @@ } while( amts, &zBuf[amt], szHdr-amt, 0); if( got==SOCKET_ERROR ) goto end_request; } @@ -395,10 +396,11 @@ fwrite(zBuf, 1, amt, out); while( wanted>0 ){ if( sslConn ){ #ifdef FOSSIL_ENABLE_SSL got = ssl_read_server(sslConn, zBuf, sizeof(zBuf)); + if( got<0 ) goto end_request; #endif }else{ got = recv(p->s, zBuf, sizeof(zBuf), 0); if( got==SOCKET_ERROR ) goto end_request; }