Fossil

Changes On Branch ssl-read-loops
Login

Changes On Branch ssl-read-loops

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

Changes In Branch ssl-read-loops Excluding Merge-Ins

This is equivalent to a diff from 7f5877e8 to 95256636

2022-01-26
13:10
Updates to the change log. ... (check-in: 076e7863 user: drh tags: trunk)
07:41
Alternative to [b890451cfb], [b70557f690] and [acffc8f785] to fix the SSL_read() loops on Windows. Pending tests on non-Windows platforms. ... (Closed-Leaf check-in: 95256636 user: florian tags: ssl-read-loops)
2022-01-25
19:36
Corrected parsing of /json-mode POST data in TLS mode. Extended /json/wiki/preview to support a mimetype option. ... (check-in: 7f5877e8 user: stephan tags: trunk)
18:14
ssl_read_server() now returns 0 on read error and lets the higher-level code deal with the short read. This might resolve the issue under discussion in forum post 2f818850abb72719. ... (check-in: acffc8f7 user: stephan tags: trunk)

Changes to src/blob.c.

981
982
983
984
985
986
987




988
989
990
991
992
993
994




995
996
997
998
999
1000
1001
int blob_read_from_cgi(Blob *pBlob, int nToRead){
  size_t n;
  blob_zero(pBlob);
  if( nToRead<0 ){
    char zBuf[10000];
    while( !cgi_feof() ){
      n = cgi_fread(zBuf, sizeof(zBuf));




      if( n>0 ){
        blob_append(pBlob, zBuf, n);
      }
    }
  }else{
    blob_resize(pBlob, nToRead);
    n = cgi_fread(blob_buffer(pBlob), nToRead);




    blob_resize(pBlob, n);
  }
  return blob_size(pBlob);
}

/*
** Initialize a blob to be the content of a file.  If the filename







>
>
>
>







>
>
>
>







981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
int blob_read_from_cgi(Blob *pBlob, int nToRead){
  size_t n;
  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);
}

/*
** Initialize a blob to be the content of a file.  If the filename

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
841
842
843
844







845
846
847
848
849
850
851
  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.
** 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;
  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 ){
      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;
      /* SSL_read() returns at most 16 KB of data, so retry in this case. */
      if( n!=16384 ) break;
    }







  }
  return rc;
}

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

Changes to src/winhttp.c.

362
363
364
365
366
367
368

369
370
371
372
373
374
375
    sslConn = ssl_new_server(p->s);
#endif
  }
  while( amt<szHdr ){
    if( sslConn ){
#ifdef FOSSIL_ENABLE_SSL
      got = ssl_read_server(sslConn, &zBuf[amt], szHdr-amt);

#endif
    }else{
      got = recv(p->s, &zBuf[amt], szHdr-amt, 0);
      if( got==SOCKET_ERROR ) goto end_request;
    }
    if( got==0 ){
      wanted = 0;







>







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

400
401
402
403
404
405
406
  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);







>







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  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));
      if( got<0 ) goto end_request;
#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);