Fossil

Check-in [4d8a71be]
Login

Check-in [4d8a71be]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ssl-read-loops2
Files: files | file ages | folders
SHA3-256: 4d8a71be8cbd37a5dd50e3aae4487cd4265e4e387b4c77511de30c4338d43e15
User & Date: florian 2022-01-28 05:51:00
Context
2022-01-28
06:37
Minor code style fixes. ... (check-in: d4ef6153 user: florian tags: ssl-read-loops2)
05:51
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. ... (check-in: 4d8a71be user: florian tags: ssl-read-loops2)
2022-01-27
20:08
Remove the prototype for pikchr() from config.h, since pikchr.c gets a valid header file on all platforms. ... (check-in: fd9b8fd8 user: danield tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cgi.c.

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
** further input or if an I/O error occurs.
*/
size_t cgi_fread(void *ptr, size_t nmemb){
  if( !g.httpUseSSL ){
    return fread(ptr, 1, nmemb, g.httpIn);
  }
#ifdef FOSSIL_ENABLE_SSL
  return ssl_read_server(g.httpSSLConn, ptr, nmemb);
#else
  fossil_fatal("SSL not available");
#endif
}

/* Works like feof():
**







|







370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
** further input or if an I/O error occurs.
*/
size_t cgi_fread(void *ptr, size_t nmemb){
  if( !g.httpUseSSL ){
    return fread(ptr, 1, nmemb, g.httpIn);
  }
#ifdef FOSSIL_ENABLE_SSL
  return ssl_read_server(g.httpSSLConn, ptr, nmemb, 0);
#else
  fossil_fatal("SSL not available");
#endif
}

/* Works like feof():
**

Changes to src/http_ssl.c.

809
810
811
812
813
814
815



816
817
818
819
820
821
822
823
824
825
826
827
828

829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  return BIO_eof(pServer->bio);
}

/*
** Read cleartext bytes that have been received from the client and
** decrypted by the SSL server codec.



*/
size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf){
  int n;
  size_t rc = 0;
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  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;
    }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
  }
  return rc;
}

/*
** Read a single line of text from the client.
*/







>
>
>

|











>

<
<
<
<
<
<
<







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833







834
835
836
837
838
839
840
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  return BIO_eof(pServer->bio);
}

/*
** Read cleartext bytes that have been received from the client and
** decrypted by the SSL server codec.
** If the expected payload size unknown, i.e. if the HTTP Content-Length: header
** field has not been parsed, the noLoop argument should be 1, or SSL_read() may
** block and wait for more data than is eventually going to arrive (on Windows).
*/
size_t ssl_read_server(void *pServerArg, char *zBuf, size_t nBuf, int noLoop){
  int n;
  size_t rc = 0;
  SslServerConn *pServer = (SslServerConn*)pServerArg;
  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;
    }else if(n>0){
      rc += n;
      if( noLoop ) break;
    }







  }
  return rc;
}

/*
** Read a single line of text from the client.
*/

Changes to src/winhttp.c.

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#ifdef FOSSIL_ENABLE_SSL
    sslConn = ssl_new_server(p->s);
#endif
  }
  while( amt<szHdr ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt);
#endif
    }else{
      got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got==0 ){
      wanted = 0;







|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#ifdef FOSSIL_ENABLE_SSL
    sslConn = ssl_new_server(p->s);
#endif
  }
  while( amt<szHdr ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, &zBuf[amt], szHdr-1-amt, 1);
#endif
    }else{
      got = recv(p->s, &zBuf[amt], szHdr-1-amt, 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got==0 ){
      wanted = 0;
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  if( amt>=szHdr ) goto end_request;
  out = fossil_fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zBuf, 1, amt, out);
  while( wanted>0 ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, zBuf, sizeof(zBuf));
#endif
    }else{
      got = recv(p->s, zBuf, sizeof(zBuf), 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got>0 ){
      fwrite(zBuf, 1, got, out);







|







392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  if( amt>=szHdr ) goto end_request;
  out = fossil_fopen(zRequestFName, "wb");
  if( out==0 ) goto end_request;
  fwrite(zBuf, 1, amt, out);
  while( wanted>0 ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, zBuf, min(wanted,sizeof(zBuf)), 0);
#endif
    }else{
      got = recv(p->s, zBuf, sizeof(zBuf), 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got>0 ){
      fwrite(zBuf, 1, got, out);