Fossil SCM

Another attempt to fix the SSL_read() loops on Windows. Not necessarily more elegant, but at least working around a well-defined problem, making the code easier to maintain.

florian 2022-01-28 05:51 trunk
Commit 4d8a71be8cbd37a5dd50e3aae4487cd4265e4e387b4c77511de30c4338d43e15
3 files changed +1 -1 +6 -9 +2 -2
+1 -1
--- src/cgi.c
+++ src/cgi.c
@@ -372,11 +372,11 @@
372372
size_t cgi_fread(void *ptr, size_t nmemb){
373373
if( !g.httpUseSSL ){
374374
return fread(ptr, 1, nmemb, g.httpIn);
375375
}
376376
#ifdef FOSSIL_ENABLE_SSL
377
- return ssl_read_server(g.httpSSLConn, ptr, nmemb);
377
+ return ssl_read_server(g.httpSSLConn, ptr, nmemb, 0);
378378
#else
379379
fossil_fatal("SSL not available");
380380
#endif
381381
}
382382
383383
--- src/cgi.c
+++ src/cgi.c
@@ -372,11 +372,11 @@
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
383
--- src/cgi.c
+++ src/cgi.c
@@ -372,11 +372,11 @@
372 size_t cgi_fread(void *ptr, size_t nmemb){
373 if( !g.httpUseSSL ){
374 return fread(ptr, 1, nmemb, g.httpIn);
375 }
376 #ifdef FOSSIL_ENABLE_SSL
377 return ssl_read_server(g.httpSSLConn, ptr, nmemb, 0);
378 #else
379 fossil_fatal("SSL not available");
380 #endif
381 }
382
383
+6 -9
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,12 +811,15 @@
811811
}
812812
813813
/*
814814
** Read cleartext bytes that have been received from the client and
815815
** decrypted by the SSL server codec.
816
+** If the expected payload size unknown, i.e. if the HTTP Content-Length: header
817
+** field has not been parsed, the noLoop argument should be 1, or SSL_read() may
818
+** block and wait for more data than is eventually going to arrive (on Windows).
816819
*/
817
-size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
820
+size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int noLoop){
818821
int n;
819822
size_t rc = 0;
820823
SslServerConn *pServer = (SslServerConn*)pServerArg;
821824
if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822825
else if( BIO_eof(pServer->bio) ) return 0;
@@ -824,18 +827,12 @@
824827
n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825828
if( n<=0 ){
826829
break;
827830
}else if(n>0){
828831
rc += n;
829
- }
830
-#ifdef _WIN32
831
- /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832
- ** not require reading in a loop, returning all data in a single
833
- ** call. If we read in a loop on Windows, SSL reads fail. Details:
834
- ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835
- break;
836
-#endif
832
+ if( noLoop ) break;
833
+ }
837834
}
838835
return rc;
839836
}
840837
841838
/*
842839
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,12 +811,15 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
 
 
 
816 */
817 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
818 int n;
819 size_t rc = 0;
820 SslServerConn *pServer = (SslServerConn*)pServerArg;
821 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
822 else if( BIO_eof(pServer->bio) ) return 0;
@@ -824,18 +827,12 @@
824 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
825 if( n<=0 ){
826 break;
827 }else if(n>0){
828 rc += n;
829 }
830 #ifdef _WIN32
831 /* Windows (XP and 10 tested with openssl 1.1.1m and 3.0.1) does
832 ** not require reading in a loop, returning all data in a single
833 ** call. If we read in a loop on Windows, SSL reads fail. Details:
834 ** https://fossil-scm.org/forum/forumpost/2f818850abb72719 */
835 break;
836 #endif
837 }
838 return rc;
839 }
840
841 /*
842
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -811,12 +811,15 @@
811 }
812
813 /*
814 ** Read cleartext bytes that have been received from the client and
815 ** decrypted by the SSL server codec.
816 ** If the expected payload size unknown, i.e. if the HTTP Content-Length: header
817 ** field has not been parsed, the noLoop argument should be 1, or SSL_read() may
818 ** block and wait for more data than is eventually going to arrive (on Windows).
819 */
820 size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int noLoop){
821 int n;
822 size_t rc = 0;
823 SslServerConn *pServer = (SslServerConn*)pServerArg;
824 if( nBuf>0x7fffffff ){ fossil_fatal("SSL read too big"); }
825 else if( BIO_eof(pServer->bio) ) return 0;
@@ -824,18 +827,12 @@
827 n = SSL_read(pServer->ssl, zBuf + rc, (int)(nBuf - rc));
828 if( n<=0 ){
829 break;
830 }else if(n>0){
831 rc += n;
832 if( noLoop ) break;
833 }
 
 
 
 
 
 
834 }
835 return rc;
836 }
837
838 /*
839
+2 -2
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363363
#endif
364364
}
365365
while( amt<szHdr ){
366366
if( sslConn ){
367367
#ifdef FOSSIL_ENABLE_SSL
368
- got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt);
368
+ got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 1);
369369
#endif
370370
}else{
371371
got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372372
if( got==SOCKET_ERROR ) goto end_request;
373373
}
@@ -394,11 +394,11 @@
394394
if( out==0 ) goto end_request;
395395
fwrite(zBuf, 1, amt, out);
396396
while( wanted>0 ){
397397
if( sslConn ){
398398
#ifdef FOSSIL_ENABLE_SSL
399
- got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
399
+ got = ssl_read_server(sslConn, zBuf, min(wanted,sizeof(zBuf)), 0);
400400
#endif
401401
}else{
402402
got = recv(p->s, zBuf, sizeof(zBuf), 0);
403403
if( got==SOCKET_ERROR ) goto end_request;
404404
}
405405
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405
--- src/winhttp.c
+++ src/winhttp.c
@@ -363,11 +363,11 @@
363 #endif
364 }
365 while( amt<szHdr ){
366 if( sslConn ){
367 #ifdef FOSSIL_ENABLE_SSL
368 got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 1);
369 #endif
370 }else{
371 got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
372 if( got==SOCKET_ERROR ) goto end_request;
373 }
@@ -394,11 +394,11 @@
394 if( out==0 ) goto end_request;
395 fwrite(zBuf, 1, amt, out);
396 while( wanted>0 ){
397 if( sslConn ){
398 #ifdef FOSSIL_ENABLE_SSL
399 got = ssl_read_server(sslConn, zBuf, min(wanted,sizeof(zBuf)), 0);
400 #endif
401 }else{
402 got = recv(p->s, zBuf, sizeof(zBuf), 0);
403 if( got==SOCKET_ERROR ) goto end_request;
404 }
405

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button